typedoc
Version:
Create api documentation for TypeScript projects.
659 lines (658 loc) • 38.2 kB
JavaScript
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
import ts from "typescript";
import { Comment, DocumentReflection, ProjectReflection, ReflectionKind, } from "../models/index.js";
import { Context } from "./context.js";
import { AbstractComponent } from "../utils/component.js";
import { Option, MinimalSourceFile, readFile, unique, getDocumentEntryPoints, } from "../utils/index.js";
import { convertType } from "./types.js";
import { ConverterEvents } from "./converter-events.js";
import { convertSymbol } from "./symbols.js";
import { createMinimatch, matchesAny, nicePath } from "../utils/paths.js";
import { hasAllFlags, hasAnyFlag } from "../utils/enum.js";
import { parseCommentString } from "./comments/parser.js";
import { lexCommentString } from "./comments/rawLexer.js";
import { resolvePartLinks, resolveLinks, } from "./comments/linkResolver.js";
import { meaningToString, } from "./comments/declarationReference.js";
import { basename, dirname, resolve } from "path";
import { GroupPlugin } from "./plugins/GroupPlugin.js";
import { CategoryPlugin } from "./plugins/CategoryPlugin.js";
import { CommentPlugin } from "./plugins/CommentPlugin.js";
import { ImplementsPlugin } from "./plugins/ImplementsPlugin.js";
import { InheritDocPlugin } from "./plugins/InheritDocPlugin.js";
import { LinkResolverPlugin } from "./plugins/LinkResolverPlugin.js";
import { PackagePlugin } from "./plugins/PackagePlugin.js";
import { SourcePlugin } from "./plugins/SourcePlugin.js";
import { TypePlugin } from "./plugins/TypePlugin.js";
import { IncludePlugin } from "./plugins/IncludePlugin.js";
import { MergeModuleWithPlugin } from "./plugins/MergeModuleWithPlugin.js";
/**
* Compiles source files using TypeScript and converts compiler symbols to reflections.
*
* @group Common
* @summary Responsible for converting TypeScript symbols into {@link Reflection}s and {@link Type}s.
*/
let Converter = (() => {
let _classSuper = AbstractComponent;
let _externalPattern_decorators;
let _externalPattern_initializers = [];
let _externalPattern_extraInitializers = [];
let _excludeExternals_decorators;
let _excludeExternals_initializers = [];
let _excludeExternals_extraInitializers = [];
let _excludeNotDocumented_decorators;
let _excludeNotDocumented_initializers = [];
let _excludeNotDocumented_extraInitializers = [];
let _excludePrivate_decorators;
let _excludePrivate_initializers = [];
let _excludePrivate_extraInitializers = [];
let _excludeProtected_decorators;
let _excludeProtected_initializers = [];
let _excludeProtected_extraInitializers = [];
let _excludeReferences_decorators;
let _excludeReferences_initializers = [];
let _excludeReferences_extraInitializers = [];
let _commentStyle_decorators;
let _commentStyle_initializers = [];
let _commentStyle_extraInitializers = [];
let _validation_decorators;
let _validation_initializers = [];
let _validation_extraInitializers = [];
let _externalSymbolLinkMappings_decorators;
let _externalSymbolLinkMappings_initializers = [];
let _externalSymbolLinkMappings_extraInitializers = [];
let _preserveLinkText_decorators;
let _preserveLinkText_initializers = [];
let _preserveLinkText_extraInitializers = [];
let _maxTypeConversionDepth_decorators;
let _maxTypeConversionDepth_initializers = [];
let _maxTypeConversionDepth_extraInitializers = [];
return class Converter extends _classSuper {
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
_externalPattern_decorators = [Option("externalPattern")];
_excludeExternals_decorators = [Option("excludeExternals")];
_excludeNotDocumented_decorators = [Option("excludeNotDocumented")];
_excludePrivate_decorators = [Option("excludePrivate")];
_excludeProtected_decorators = [Option("excludeProtected")];
_excludeReferences_decorators = [Option("excludeReferences")];
_commentStyle_decorators = [Option("commentStyle")];
_validation_decorators = [Option("validation")];
_externalSymbolLinkMappings_decorators = [Option("externalSymbolLinkMappings")];
_preserveLinkText_decorators = [Option("preserveLinkText")];
_maxTypeConversionDepth_decorators = [Option("maxTypeConversionDepth")];
__esDecorate(this, null, _externalPattern_decorators, { kind: "accessor", name: "externalPattern", static: false, private: false, access: { has: obj => "externalPattern" in obj, get: obj => obj.externalPattern, set: (obj, value) => { obj.externalPattern = value; } }, metadata: _metadata }, _externalPattern_initializers, _externalPattern_extraInitializers);
__esDecorate(this, null, _excludeExternals_decorators, { kind: "accessor", name: "excludeExternals", static: false, private: false, access: { has: obj => "excludeExternals" in obj, get: obj => obj.excludeExternals, set: (obj, value) => { obj.excludeExternals = value; } }, metadata: _metadata }, _excludeExternals_initializers, _excludeExternals_extraInitializers);
__esDecorate(this, null, _excludeNotDocumented_decorators, { kind: "accessor", name: "excludeNotDocumented", static: false, private: false, access: { has: obj => "excludeNotDocumented" in obj, get: obj => obj.excludeNotDocumented, set: (obj, value) => { obj.excludeNotDocumented = value; } }, metadata: _metadata }, _excludeNotDocumented_initializers, _excludeNotDocumented_extraInitializers);
__esDecorate(this, null, _excludePrivate_decorators, { kind: "accessor", name: "excludePrivate", static: false, private: false, access: { has: obj => "excludePrivate" in obj, get: obj => obj.excludePrivate, set: (obj, value) => { obj.excludePrivate = value; } }, metadata: _metadata }, _excludePrivate_initializers, _excludePrivate_extraInitializers);
__esDecorate(this, null, _excludeProtected_decorators, { kind: "accessor", name: "excludeProtected", static: false, private: false, access: { has: obj => "excludeProtected" in obj, get: obj => obj.excludeProtected, set: (obj, value) => { obj.excludeProtected = value; } }, metadata: _metadata }, _excludeProtected_initializers, _excludeProtected_extraInitializers);
__esDecorate(this, null, _excludeReferences_decorators, { kind: "accessor", name: "excludeReferences", static: false, private: false, access: { has: obj => "excludeReferences" in obj, get: obj => obj.excludeReferences, set: (obj, value) => { obj.excludeReferences = value; } }, metadata: _metadata }, _excludeReferences_initializers, _excludeReferences_extraInitializers);
__esDecorate(this, null, _commentStyle_decorators, { kind: "accessor", name: "commentStyle", static: false, private: false, access: { has: obj => "commentStyle" in obj, get: obj => obj.commentStyle, set: (obj, value) => { obj.commentStyle = value; } }, metadata: _metadata }, _commentStyle_initializers, _commentStyle_extraInitializers);
__esDecorate(this, null, _validation_decorators, { kind: "accessor", name: "validation", static: false, private: false, access: { has: obj => "validation" in obj, get: obj => obj.validation, set: (obj, value) => { obj.validation = value; } }, metadata: _metadata }, _validation_initializers, _validation_extraInitializers);
__esDecorate(this, null, _externalSymbolLinkMappings_decorators, { kind: "accessor", name: "externalSymbolLinkMappings", static: false, private: false, access: { has: obj => "externalSymbolLinkMappings" in obj, get: obj => obj.externalSymbolLinkMappings, set: (obj, value) => { obj.externalSymbolLinkMappings = value; } }, metadata: _metadata }, _externalSymbolLinkMappings_initializers, _externalSymbolLinkMappings_extraInitializers);
__esDecorate(this, null, _preserveLinkText_decorators, { kind: "accessor", name: "preserveLinkText", static: false, private: false, access: { has: obj => "preserveLinkText" in obj, get: obj => obj.preserveLinkText, set: (obj, value) => { obj.preserveLinkText = value; } }, metadata: _metadata }, _preserveLinkText_initializers, _preserveLinkText_extraInitializers);
__esDecorate(this, null, _maxTypeConversionDepth_decorators, { kind: "accessor", name: "maxTypeConversionDepth", static: false, private: false, access: { has: obj => "maxTypeConversionDepth" in obj, get: obj => obj.maxTypeConversionDepth, set: (obj, value) => { obj.maxTypeConversionDepth = value; } }, metadata: _metadata }, _maxTypeConversionDepth_initializers, _maxTypeConversionDepth_extraInitializers);
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
}
#externalPattern_accessor_storage = __runInitializers(this, _externalPattern_initializers, void 0);
/** @internal */
get externalPattern() { return this.#externalPattern_accessor_storage; }
set externalPattern(value) { this.#externalPattern_accessor_storage = value; }
externalPatternCache = __runInitializers(this, _externalPattern_extraInitializers);
excludeCache;
#excludeExternals_accessor_storage = __runInitializers(this, _excludeExternals_initializers, void 0);
/** @internal */
get excludeExternals() { return this.#excludeExternals_accessor_storage; }
set excludeExternals(value) { this.#excludeExternals_accessor_storage = value; }
#excludeNotDocumented_accessor_storage = (__runInitializers(this, _excludeExternals_extraInitializers), __runInitializers(this, _excludeNotDocumented_initializers, void 0));
/** @internal */
get excludeNotDocumented() { return this.#excludeNotDocumented_accessor_storage; }
set excludeNotDocumented(value) { this.#excludeNotDocumented_accessor_storage = value; }
#excludePrivate_accessor_storage = (__runInitializers(this, _excludeNotDocumented_extraInitializers), __runInitializers(this, _excludePrivate_initializers, void 0));
/** @internal */
get excludePrivate() { return this.#excludePrivate_accessor_storage; }
set excludePrivate(value) { this.#excludePrivate_accessor_storage = value; }
#excludeProtected_accessor_storage = (__runInitializers(this, _excludePrivate_extraInitializers), __runInitializers(this, _excludeProtected_initializers, void 0));
/** @internal */
get excludeProtected() { return this.#excludeProtected_accessor_storage; }
set excludeProtected(value) { this.#excludeProtected_accessor_storage = value; }
#excludeReferences_accessor_storage = (__runInitializers(this, _excludeProtected_extraInitializers), __runInitializers(this, _excludeReferences_initializers, void 0));
/** @internal */
get excludeReferences() { return this.#excludeReferences_accessor_storage; }
set excludeReferences(value) { this.#excludeReferences_accessor_storage = value; }
#commentStyle_accessor_storage = (__runInitializers(this, _excludeReferences_extraInitializers), __runInitializers(this, _commentStyle_initializers, void 0));
/** @internal */
get commentStyle() { return this.#commentStyle_accessor_storage; }
set commentStyle(value) { this.#commentStyle_accessor_storage = value; }
#validation_accessor_storage = (__runInitializers(this, _commentStyle_extraInitializers), __runInitializers(this, _validation_initializers, void 0));
/** @internal */
get validation() { return this.#validation_accessor_storage; }
set validation(value) { this.#validation_accessor_storage = value; }
#externalSymbolLinkMappings_accessor_storage = (__runInitializers(this, _validation_extraInitializers), __runInitializers(this, _externalSymbolLinkMappings_initializers, void 0));
/** @internal */
get externalSymbolLinkMappings() { return this.#externalSymbolLinkMappings_accessor_storage; }
set externalSymbolLinkMappings(value) { this.#externalSymbolLinkMappings_accessor_storage = value; }
#preserveLinkText_accessor_storage = (__runInitializers(this, _externalSymbolLinkMappings_extraInitializers), __runInitializers(this, _preserveLinkText_initializers, void 0));
/** @internal */
get preserveLinkText() { return this.#preserveLinkText_accessor_storage; }
set preserveLinkText(value) { this.#preserveLinkText_accessor_storage = value; }
#maxTypeConversionDepth_accessor_storage = (__runInitializers(this, _preserveLinkText_extraInitializers), __runInitializers(this, _maxTypeConversionDepth_initializers, void 0));
/** @internal */
get maxTypeConversionDepth() { return this.#maxTypeConversionDepth_accessor_storage; }
set maxTypeConversionDepth(value) { this.#maxTypeConversionDepth_accessor_storage = value; }
_config = __runInitializers(this, _maxTypeConversionDepth_extraInitializers);
_externalSymbolResolvers = [];
get config() {
return this._config || this._buildCommentParserConfig();
}
/**
* General events
*/
/**
* Triggered when the converter begins converting a project.
* The listener will be given a {@link Context} object.
* @event
*/
static EVENT_BEGIN = ConverterEvents.BEGIN;
/**
* Triggered when the converter has finished converting a project.
* The listener will be given a {@link Context} object.
* @event
*/
static EVENT_END = ConverterEvents.END;
/**
* Factory events
*/
/**
* Triggered when the converter has created a project reflection.
* The listener will be given {@link Context} and a {@link Models.ProjectReflection}.
* @event
*/
static EVENT_CREATE_PROJECT = ConverterEvents.CREATE_PROJECT;
/**
* Triggered when the converter has created a declaration reflection.
* The listener will be given {@link Context} and a {@link Models.DeclarationReflection}.
* @event
*/
static EVENT_CREATE_DECLARATION = ConverterEvents.CREATE_DECLARATION;
/**
* Triggered when the converter has created a document reflection.
* The listener will be given `undefined` (for consistency with the
* other create events) and a {@link Models.DocumentReflection}.
* @event
*/
static EVENT_CREATE_DOCUMENT = ConverterEvents.CREATE_DOCUMENT;
/**
* Triggered when the converter has created a signature reflection.
* The listener will be given {@link Context}, {@link Models.SignatureReflection} | {@link Models.ProjectReflection} the declaration,
* `ts.SignatureDeclaration | ts.IndexSignatureDeclaration | ts.JSDocSignature | undefined`,
* and `ts.Signature | undefined`. The signature will be undefined if the created signature is an index signature.
* @event
*/
static EVENT_CREATE_SIGNATURE = ConverterEvents.CREATE_SIGNATURE;
/**
* Triggered when the converter has created a parameter reflection.
* The listener will be given {@link Context}, {@link Models.ParameterReflection} and a `ts.Node?`
* @event
*/
static EVENT_CREATE_PARAMETER = ConverterEvents.CREATE_PARAMETER;
/**
* Triggered when the converter has created a type parameter reflection.
* The listener will be given {@link Context} and a {@link Models.TypeParameterReflection}
* @event
*/
static EVENT_CREATE_TYPE_PARAMETER = ConverterEvents.CREATE_TYPE_PARAMETER;
/**
* Resolve events
*/
/**
* Triggered when the converter begins resolving a project.
* The listener will be given {@link Context}.
* @event
*/
static EVENT_RESOLVE_BEGIN = ConverterEvents.RESOLVE_BEGIN;
/**
* Triggered when the converter resolves a reflection.
* The listener will be given {@link Context} and a {@link Reflection}.
* @event
*/
static EVENT_RESOLVE = ConverterEvents.RESOLVE;
/**
* Triggered when the converter has finished resolving a project.
* The listener will be given {@link Context}.
* @event
*/
static EVENT_RESOLVE_END = ConverterEvents.RESOLVE_END;
/** @internal @hidden */
includePlugin;
constructor(owner) {
super(owner);
const userConfiguredSymbolResolver = (ref, refl, _part, symbolId) => {
if (symbolId) {
return userConfiguredSymbolResolver(symbolId.toDeclarationReference(), refl, undefined, undefined);
}
// Require global links, matching local ones will likely hide mistakes where the
// user meant to link to a local type.
if (ref.resolutionStart !== "global" || !ref.symbolReference) {
return;
}
const modLinks = this.externalSymbolLinkMappings[ref.moduleSource ?? "global"];
if (typeof modLinks !== "object") {
return;
}
let name = "";
if (ref.symbolReference.path) {
name += ref.symbolReference.path.map((p) => p.path).join(".");
}
if (ref.symbolReference.meaning) {
name += meaningToString(ref.symbolReference.meaning);
}
if (typeof modLinks[name] === "string") {
return modLinks[name];
}
if (typeof modLinks["*"] === "string") {
return modLinks["*"];
}
};
this.addUnknownSymbolResolver(userConfiguredSymbolResolver);
new CategoryPlugin(this);
new CommentPlugin(this);
new GroupPlugin(this);
new ImplementsPlugin(this);
new InheritDocPlugin(this);
new LinkResolverPlugin(this);
new PackagePlugin(this);
new SourcePlugin(this);
new TypePlugin(this);
this.includePlugin = new IncludePlugin(this);
new MergeModuleWithPlugin(this);
}
/**
* Compile the given source files and create a project reflection for them.
*/
convert(entryPoints) {
const programs = unique(entryPoints.map((e) => e.program));
this.externalPatternCache = void 0;
const project = new ProjectReflection(this.application.options.getValue("name"), this.application.files);
const context = new Context(this, programs, project);
this.trigger(Converter.EVENT_BEGIN, context);
this.addProjectDocuments(project);
this.compile(entryPoints, context);
this.resolve(context);
this.trigger(Converter.EVENT_END, context);
this._config = undefined;
return project;
}
/** @internal */
addProjectDocuments(project) {
const projectDocuments = getDocumentEntryPoints(this.application.logger, this.application.options);
for (const { displayName, path } of projectDocuments) {
let file;
try {
file = new MinimalSourceFile(readFile(path), path);
}
catch (error) {
this.application.logger.error(this.application.logger.i18n.failed_to_read_0_when_processing_project_document(path));
continue;
}
this.addDocument(project, file, displayName);
}
}
/** @internal */
convertSymbol(context, symbol, exportSymbol) {
convertSymbol(context, symbol, exportSymbol);
}
/**
* Convert the given TypeScript type into its TypeDoc type reflection.
*
* @param context The context object describing the current state the converter is in.
* @returns The TypeDoc type reflection representing the given node and type.
* @internal
*/
convertType(context, node) {
return convertType(context, node);
}
/**
* Parse the given file into a comment. Intended to be used with markdown files.
*/
parseRawComment(file, files) {
return parseCommentString(lexCommentString(file.text), this.config, file, this.application.logger, files);
}
/**
* Adds a new resolver that the theme can use to try to figure out how to link to a symbol declared
* by a third-party library which is not included in the documentation.
*
* The resolver function will be passed a declaration reference which it can attempt to resolve. If
* resolution fails, the function should return undefined.
*
* Note: This will be used for both references to types declared in node_modules (in which case the
* reference passed will have the `moduleSource` set and the `symbolReference` will navigate via `.`)
* and user defined \{\@link\} tags which cannot be resolved. If the link being resolved is inferred
* from a type, then no `part` will be passed to the resolver function.
*/
addUnknownSymbolResolver(resolver) {
this._externalSymbolResolvers.push(resolver);
}
/** @internal */
resolveExternalLink(ref, refl, part, symbolId) {
for (const resolver of this._externalSymbolResolvers) {
const resolved = resolver(ref, refl, part, symbolId);
if (resolved)
return resolved;
}
}
resolveLinks(comment, owner) {
if (comment instanceof Comment) {
resolveLinks(comment, owner, (ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id), { preserveLinkText: this.preserveLinkText });
}
else {
return resolvePartLinks(owner, comment, (ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id), { preserveLinkText: this.preserveLinkText });
}
}
/**
* Compile the files within the given context and convert the compiler symbols to reflections.
*
* @param context The context object describing the current state the converter is in.
* @returns An array containing all errors generated by the TypeScript compiler.
*/
compile(entryPoints, context) {
const entries = entryPoints.map((e) => {
return {
entryPoint: e,
context: undefined,
};
});
let createModuleReflections = entries.length > 1;
if (!createModuleReflections) {
const opts = this.application.options;
createModuleReflections = opts.isSet("alwaysCreateEntryPointModule")
? opts.getValue("alwaysCreateEntryPointModule")
: !!context.scope.documents;
}
if (createModuleReflections) {
this.trigger(ConverterEvents.CREATE_PROJECT, context, context.project);
}
entries.forEach((e) => {
context.setActiveProgram(e.entryPoint.program);
e.context = this.convertExports(context, e.entryPoint, createModuleReflections);
});
for (const { entryPoint, context } of entries) {
// active program is already set on context
// if we don't have a context, then this entry point is being ignored
if (context) {
this.convertReExports(context, entryPoint.sourceFile);
}
}
context.setActiveProgram(undefined);
}
convertExports(context, entryPoint, createModuleReflections) {
const node = entryPoint.sourceFile;
const entryName = entryPoint.displayName;
const symbol = getSymbolForModuleLike(context, node);
let moduleContext;
if (createModuleReflections === false) {
// Special case for when we're giving a single entry point, we don't need to
// create modules for each entry. Register the project as this module.
context.project.registerReflection(context.project, symbol, entryPoint.sourceFile.fileName);
context.project.comment = symbol
? context.getComment(symbol, context.project.kind)
: context.getFileComment(node);
this.processDocumentTags(context.project, context.project);
this.trigger(ConverterEvents.CREATE_PROJECT, context, context.project);
moduleContext = context;
}
else {
const reflection = context.createDeclarationReflection(ReflectionKind.Module, symbol, void 0, entryName);
if (!reflection.comment && !symbol) {
reflection.comment = context.getFileComment(node);
}
context.finalizeDeclarationReflection(reflection);
moduleContext = context.withScope(reflection);
}
const allExports = getExports(context, node, symbol);
for (const exp of allExports.filter((exp) => isDirectExport(context.resolveAliasedSymbol(exp), node))) {
this.convertSymbol(moduleContext, exp);
}
return moduleContext;
}
convertReExports(moduleContext, node) {
for (const exp of getExports(moduleContext, node, moduleContext.project.getSymbolFromReflection(moduleContext.scope)).filter((exp) => !isDirectExport(moduleContext.resolveAliasedSymbol(exp), node))) {
this.convertSymbol(moduleContext, exp);
}
}
/**
* Resolve the project within the given context.
*
* @param context The context object describing the current state the converter is in.
* @returns The final project reflection.
*/
resolve(context) {
this.trigger(Converter.EVENT_RESOLVE_BEGIN, context);
const project = context.project;
for (const id in project.reflections) {
this.trigger(Converter.EVENT_RESOLVE, context, project.reflections[id]);
}
this.trigger(Converter.EVENT_RESOLVE_END, context);
}
/**
* Used to determine if we should immediately bail when creating a reflection.
* Note: This should not be used for excludeNotDocumented because we don't have enough
* information at this point since comment discovery hasn't happened.
* @internal
*/
shouldIgnore(symbol) {
if (this.isExcluded(symbol)) {
return true;
}
return this.excludeExternals && this.isExternal(symbol);
}
isExcluded(symbol) {
this.excludeCache ??= createMinimatch(this.application.options.getValue("exclude"));
const cache = this.excludeCache;
return (symbol.getDeclarations() ?? []).some((node) => matchesAny(cache, node.getSourceFile().fileName));
}
/** @internal */
isExternal(symbol) {
this.externalPatternCache ??= createMinimatch(this.externalPattern);
const cache = this.externalPatternCache;
return (symbol.getDeclarations() ?? []).some((node) => matchesAny(cache, node.getSourceFile().fileName));
}
processDocumentTags(reflection, parent) {
let relativeTo = reflection.comment?.sourcePath;
if (relativeTo) {
relativeTo = dirname(relativeTo);
const tags = reflection.comment?.getTags("@document") || [];
reflection.comment?.removeTags("@document");
for (const tag of tags) {
const path = Comment.combineDisplayParts(tag.content);
let file;
try {
const resolved = resolve(relativeTo, path);
file = new MinimalSourceFile(readFile(resolved), resolved);
}
catch {
this.application.logger.warn(this.application.logger.i18n.failed_to_read_0_when_processing_document_tag_in_1(nicePath(path), nicePath(reflection.comment.sourcePath)));
continue;
}
this.addDocument(parent, file, basename(file.fileName).replace(/\.[^.]+$/, ""));
}
}
}
addDocument(parent, file, displayName) {
const { content, frontmatter } = this.parseRawComment(file, parent.project.files);
const children = frontmatter["children"];
delete frontmatter["children"];
const docRefl = new DocumentReflection(displayName, parent, content, frontmatter);
parent.addChild(docRefl);
parent.project.registerReflection(docRefl, undefined, file.fileName);
this.trigger(ConverterEvents.CREATE_DOCUMENT, undefined, docRefl);
const childrenToAdd = [];
if (children && typeof children === "object") {
if (Array.isArray(children)) {
for (const child of children) {
if (typeof child === "string") {
childrenToAdd.push([
basename(child).replace(/\.[^.]+$/, ""),
child,
]);
}
else {
this.application.logger.error(this.application.i18n.frontmatter_children_0_should_be_an_array_of_strings_or_object_with_string_values(nicePath(file.fileName)));
return;
}
}
}
else {
for (const [name, path] of Object.entries(children)) {
if (typeof path === "string") {
childrenToAdd.push([name, path]);
}
else {
this.application.logger.error(this.application.i18n.frontmatter_children_0_should_be_an_array_of_strings_or_object_with_string_values(nicePath(file.fileName)));
return;
}
}
}
}
for (const [displayName, path] of childrenToAdd) {
const absPath = resolve(dirname(file.fileName), path);
let childFile;
try {
childFile = new MinimalSourceFile(readFile(absPath), absPath);
}
catch (error) {
this.application.logger.error(this.application.logger.i18n.failed_to_read_0_when_processing_document_child_in_1(path, nicePath(file.fileName)));
continue;
}
this.addDocument(docRefl, childFile, displayName);
}
}
_buildCommentParserConfig() {
this._config = {
blockTags: new Set(this.application.options.getValue("blockTags")),
inlineTags: new Set(this.application.options.getValue("inlineTags")),
modifierTags: new Set(this.application.options.getValue("modifierTags")),
jsDocCompatibility: this.application.options.getValue("jsDocCompatibility"),
suppressCommentWarningsInDeclarationFiles: this.application.options.getValue("suppressCommentWarningsInDeclarationFiles"),
useTsLinkResolution: this.application.options.getValue("useTsLinkResolution"),
commentStyle: this.application.options.getValue("commentStyle"),
};
// Can't be included in options because the TSDoc parser blows up if we do.
// TypeDoc supports it as one, so it should always be included here.
this._config.blockTags.add("@inheritDoc");
return this._config;
}
};
})();
export { Converter };
function getSymbolForModuleLike(context, node) {
const symbol = context.checker.getSymbolAtLocation(node) ?? node.symbol;
if (symbol) {
return symbol;
}
// This is a global file, get all symbols declared in this file...
// this isn't the best solution, it would be nice to have all globals given to a special
// "globals" file, but this is uncommon enough that I'm skipping it for now.
const sourceFile = node.getSourceFile();
const globalSymbols = context.checker
.getSymbolsInScope(node, ts.SymbolFlags.ModuleMember)
.filter((s) => s.getDeclarations()?.some((d) => d.getSourceFile() === sourceFile));
// Detect declaration files with declare module "foo" as their only export
// and lift that up one level as the source file symbol
if (globalSymbols.length === 1 &&
globalSymbols[0]
.getDeclarations()
?.every((declaration) => ts.isModuleDeclaration(declaration) &&
ts.isStringLiteral(declaration.name))) {
return globalSymbols[0];
}
}
function getExports(context, node, symbol) {
let result;
// The generated docs aren't great, but you really ought not be using
// this in the first place... so it's better than nothing.
const exportEq = symbol?.exports?.get("export=");
if (exportEq) {
// JS users might also have exported types here.
// We need to filter for types because otherwise static methods can show up as both
// members of the export= class and as functions if a class is directly exported.
result = [exportEq].concat(context.checker
.getExportsOfModule(symbol)
.filter((s) => !hasAnyFlag(s.flags, ts.SymbolFlags.Prototype | ts.SymbolFlags.Value)));
}
else if (symbol) {
result = context.checker
.getExportsOfModule(symbol)
.filter((s) => !hasAllFlags(s.flags, ts.SymbolFlags.Prototype));
if (result.length === 0) {
const globalDecl = node.statements.find((s) => ts.isModuleDeclaration(s) &&
s.flags & ts.NodeFlags.GlobalAugmentation);
if (globalDecl) {
const globalSymbol = context.getSymbolAtLocation(globalDecl);
if (globalSymbol) {
result = context.checker
.getExportsOfModule(globalSymbol)
.filter((exp) => exp.declarations?.some((d) => d.getSourceFile() === node))
.map((s) => context.checker.getMergedSymbol(s));
}
}
}
}
else {
// Global file with no inferred top level symbol, get all symbols declared in this file.
const sourceFile = node.getSourceFile();
result = context.checker
.getSymbolsInScope(node, ts.SymbolFlags.ModuleMember)
.filter((s) => s
.getDeclarations()
?.some((d) => d.getSourceFile() === sourceFile));
}
// Put symbols named "default" last, #1795
result.sort((a, b) => {
if (a.name === "default") {
return 1;
}
else if (b.name === "default") {
return -1;
}
return 0;
});
return result;
}
function isDirectExport(symbol, file) {
return (symbol
.getDeclarations()
?.every((decl) => decl.getSourceFile() === file) ?? false);
}