mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 19:13:31 +01:00
feat: docs for mixin methods, examples (#9960)
This commit is contained in:
@@ -3,7 +3,18 @@
|
|||||||
|
|
||||||
import { existsSync } from 'node:fs';
|
import { existsSync } from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
|
import type {
|
||||||
|
IApiMethodOptions,
|
||||||
|
ApiItemContainerMixin,
|
||||||
|
IApiParameterOptions,
|
||||||
|
IExcerptTokenRange,
|
||||||
|
IExcerptTokenRangeWithTypeParameters,
|
||||||
|
IExcerptToken,
|
||||||
|
IApiTypeParameterOptions,
|
||||||
|
IApiPropertyOptions,
|
||||||
|
} from '@discordjs/api-extractor-model';
|
||||||
import {
|
import {
|
||||||
|
ApiItemKind,
|
||||||
ApiModel,
|
ApiModel,
|
||||||
ApiClass,
|
ApiClass,
|
||||||
ApiPackage,
|
ApiPackage,
|
||||||
@@ -13,16 +24,11 @@ import {
|
|||||||
ApiNamespace,
|
ApiNamespace,
|
||||||
ApiInterface,
|
ApiInterface,
|
||||||
ApiPropertySignature,
|
ApiPropertySignature,
|
||||||
type ApiItemContainerMixin,
|
|
||||||
ReleaseTag,
|
ReleaseTag,
|
||||||
ApiProperty,
|
ApiProperty,
|
||||||
ApiMethodSignature,
|
ApiMethodSignature,
|
||||||
type IApiParameterOptions,
|
|
||||||
ApiEnum,
|
ApiEnum,
|
||||||
ApiEnumMember,
|
ApiEnumMember,
|
||||||
type IExcerptTokenRange,
|
|
||||||
type IExcerptTokenRangeWithTypeParameters,
|
|
||||||
type IExcerptToken,
|
|
||||||
ApiConstructor,
|
ApiConstructor,
|
||||||
ApiConstructSignature,
|
ApiConstructSignature,
|
||||||
ApiFunction,
|
ApiFunction,
|
||||||
@@ -30,7 +36,6 @@ import {
|
|||||||
ApiVariable,
|
ApiVariable,
|
||||||
ApiTypeAlias,
|
ApiTypeAlias,
|
||||||
ApiCallSignature,
|
ApiCallSignature,
|
||||||
type IApiTypeParameterOptions,
|
|
||||||
EnumMemberOrder,
|
EnumMemberOrder,
|
||||||
ExcerptTokenKind,
|
ExcerptTokenKind,
|
||||||
Navigation,
|
Navigation,
|
||||||
@@ -214,6 +219,14 @@ function filePathFromJson(meta: DocgenMetaJson): string {
|
|||||||
return `${meta.path.slice('packages/discord.js/'.length)}/${meta.file}`;
|
return `${meta.path.slice('packages/discord.js/'.length)}/${meta.file}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatVarType(type: DocgenVarTypeJson): string {
|
||||||
|
return (Array.isArray(type) ? type : type.types ?? []).map((t1) => t1.map((t2) => t2.join('')).join('')).join(' | ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFirstType(type: DocgenVarTypeJson): string {
|
||||||
|
return (Array.isArray(type) ? type[0]?.[0]?.[0] : type.types?.[0]?.[0]?.[0]) ?? 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
export class ApiModelGenerator {
|
export class ApiModelGenerator {
|
||||||
private readonly _collector: Collector;
|
private readonly _collector: Collector;
|
||||||
|
|
||||||
@@ -433,6 +446,42 @@ export class ApiModelGenerator {
|
|||||||
name: childDeclaration.astSymbol.localName,
|
name: childDeclaration.astSymbol.localName,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const method of (context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined)?.methods ??
|
||||||
|
[]) {
|
||||||
|
switch (context.parentApiItem.kind) {
|
||||||
|
case ApiItemKind.Class:
|
||||||
|
this._processApiMethod(null, { ...context, name: method.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ApiItemKind.Interface:
|
||||||
|
this._processApiMethodSignature(null, { ...context, name: method.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log(
|
||||||
|
`Found docgen method not in TS typings for ApiItem of kind ${ApiItemKind[context.parentApiItem.kind]}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const property of (context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined)?.props ??
|
||||||
|
[]) {
|
||||||
|
switch (context.parentApiItem.kind) {
|
||||||
|
case ApiItemKind.Class:
|
||||||
|
this._processApiProperty(null, { ...context, name: property.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ApiItemKind.Interface:
|
||||||
|
this._processApiPropertySignature(null, { ...context, name: property.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log(
|
||||||
|
`Found docgen property not in TS typings for ApiItem of kind ${ApiItemKind[context.parentApiItem.kind]}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiCallSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiCallSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
||||||
@@ -955,86 +1004,98 @@ export class ApiModelGenerator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiMethod(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiMethod(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const isStatic: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0;
|
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined;
|
||||||
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
|
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
||||||
|
const isStatic: boolean = astDeclaration
|
||||||
|
? (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0
|
||||||
|
: jsDoc?.scope === 'static';
|
||||||
|
const overloadIndex: number = astDeclaration ? this._collector.getOverloadIndex(astDeclaration) : 1;
|
||||||
const containerKey: string = ApiMethod.getContainerKey(name, isStatic, overloadIndex);
|
const containerKey: string = ApiMethod.getContainerKey(name, isStatic, overloadIndex);
|
||||||
|
|
||||||
let apiMethod: ApiMethod | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiMethod;
|
let apiMethod: ApiMethod | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiMethod;
|
||||||
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined;
|
|
||||||
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
|
||||||
|
|
||||||
if (apiMethod === undefined) {
|
if (apiMethod === undefined) {
|
||||||
const methodDeclaration: ts.MethodDeclaration = astDeclaration.declaration as ts.MethodDeclaration;
|
if (astDeclaration) {
|
||||||
|
const methodDeclaration: ts.MethodDeclaration = astDeclaration.declaration as ts.MethodDeclaration;
|
||||||
|
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
|
|
||||||
const returnTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
const returnTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
nodesToCapture.push({ node: methodDeclaration.type, tokenRange: returnTypeTokenRange });
|
nodesToCapture.push({ node: methodDeclaration.type, tokenRange: returnTypeTokenRange });
|
||||||
|
|
||||||
const typeParameters: IApiTypeParameterOptions[] = this._captureTypeParameters(
|
const typeParameters: IApiTypeParameterOptions[] = this._captureTypeParameters(
|
||||||
nodesToCapture,
|
nodesToCapture,
|
||||||
methodDeclaration.typeParameters,
|
methodDeclaration.typeParameters,
|
||||||
);
|
);
|
||||||
|
|
||||||
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, methodDeclaration.parameters);
|
const parameters: IApiParameterOptions[] = this._captureParameters(
|
||||||
|
nodesToCapture,
|
||||||
|
methodDeclaration.parameters,
|
||||||
|
);
|
||||||
|
|
||||||
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
||||||
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
||||||
const docComment: tsdoc.DocComment | undefined = jsDoc
|
const docComment: tsdoc.DocComment | undefined = jsDoc
|
||||||
? this._tsDocParser.parseString(
|
? this._tsDocParser.parseString(
|
||||||
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
||||||
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
|
jsDoc.params
|
||||||
''
|
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
|
||||||
}${
|
.join('') ?? ''
|
||||||
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
}${
|
||||||
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
||||||
: ''
|
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
||||||
}${
|
: ''
|
||||||
jsDoc.deprecated
|
}${
|
||||||
? ` * @deprecated ${
|
jsDoc.examples?.map((example) => ` * @example\n * \`\`\`js\n * ${example}\n * \`\`\`\n`).join('') ?? ''
|
||||||
typeof jsDoc.deprecated === 'string' ? fixLinkTags(jsDoc.deprecated) : jsDoc.deprecated
|
}${
|
||||||
}\n`
|
jsDoc.deprecated
|
||||||
: ''
|
? ` * @deprecated ${
|
||||||
} */`,
|
typeof jsDoc.deprecated === 'string' ? fixLinkTags(jsDoc.deprecated) : jsDoc.deprecated
|
||||||
).docComment
|
}\n`
|
||||||
: apiItemMetadata.tsdocComment;
|
: ''
|
||||||
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
} */`,
|
||||||
if (releaseTag === ReleaseTag.Internal || releaseTag === ReleaseTag.Alpha) {
|
).docComment
|
||||||
return; // trim out items marked as "@internal" or "@alpha"
|
: apiItemMetadata.tsdocComment;
|
||||||
|
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
||||||
|
if (releaseTag === ReleaseTag.Internal || releaseTag === ReleaseTag.Alpha) {
|
||||||
|
return; // trim out items marked as "@internal" or "@alpha"
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
||||||
|
const isProtected: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Protected) !== 0;
|
||||||
|
const isAbstract: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Abstract) !== 0;
|
||||||
|
const sourceLocation: ISourceLocation = this._getSourceLocation(methodDeclaration);
|
||||||
|
|
||||||
|
apiMethod = new ApiMethod({
|
||||||
|
name,
|
||||||
|
isAbstract,
|
||||||
|
docComment,
|
||||||
|
releaseTag,
|
||||||
|
isProtected,
|
||||||
|
isStatic,
|
||||||
|
isOptional,
|
||||||
|
typeParameters,
|
||||||
|
parameters,
|
||||||
|
overloadIndex,
|
||||||
|
excerptTokens,
|
||||||
|
returnTypeTokenRange,
|
||||||
|
fileUrlPath: jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
||||||
|
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
||||||
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
|
});
|
||||||
|
} else if (jsDoc) {
|
||||||
|
apiMethod = new ApiMethod(this._mapMethod(jsDoc, parentApiItem.getAssociatedPackage()!.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
|
||||||
const isProtected: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Protected) !== 0;
|
|
||||||
const isAbstract: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Abstract) !== 0;
|
|
||||||
const sourceLocation: ISourceLocation = this._getSourceLocation(methodDeclaration);
|
|
||||||
|
|
||||||
apiMethod = new ApiMethod({
|
|
||||||
name,
|
|
||||||
isAbstract,
|
|
||||||
docComment,
|
|
||||||
releaseTag,
|
|
||||||
isProtected,
|
|
||||||
isStatic,
|
|
||||||
isOptional,
|
|
||||||
typeParameters,
|
|
||||||
parameters,
|
|
||||||
overloadIndex,
|
|
||||||
excerptTokens,
|
|
||||||
returnTypeTokenRange,
|
|
||||||
fileUrlPath: jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
|
||||||
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
|
||||||
});
|
|
||||||
|
|
||||||
parentApiItem.addMember(apiMethod);
|
parentApiItem.addMember(apiMethod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiMethodSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiMethodSignature(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
|
const overloadIndex: number = astDeclaration ? this._collector.getOverloadIndex(astDeclaration) : 1;
|
||||||
const containerKey: string = ApiMethodSignature.getContainerKey(name, overloadIndex);
|
const containerKey: string = ApiMethodSignature.getContainerKey(name, overloadIndex);
|
||||||
|
|
||||||
let apiMethodSignature: ApiMethodSignature | undefined = parentApiItem.tryGetMemberByKey(
|
let apiMethodSignature: ApiMethodSignature | undefined = parentApiItem.tryGetMemberByKey(
|
||||||
@@ -1044,58 +1105,63 @@ export class ApiModelGenerator {
|
|||||||
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
const jsDoc = parent?.methods?.find((method) => method.name === name);
|
||||||
|
|
||||||
if (apiMethodSignature === undefined) {
|
if (apiMethodSignature === undefined) {
|
||||||
const methodSignature: ts.MethodSignature = astDeclaration.declaration as ts.MethodSignature;
|
if (astDeclaration) {
|
||||||
|
const methodSignature: ts.MethodSignature = astDeclaration.declaration as ts.MethodSignature;
|
||||||
|
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
|
|
||||||
const returnTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
const returnTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
nodesToCapture.push({ node: methodSignature.type, tokenRange: returnTypeTokenRange });
|
nodesToCapture.push({ node: methodSignature.type, tokenRange: returnTypeTokenRange });
|
||||||
|
|
||||||
const typeParameters: IApiTypeParameterOptions[] = this._captureTypeParameters(
|
const typeParameters: IApiTypeParameterOptions[] = this._captureTypeParameters(
|
||||||
nodesToCapture,
|
nodesToCapture,
|
||||||
methodSignature.typeParameters,
|
methodSignature.typeParameters,
|
||||||
);
|
);
|
||||||
|
|
||||||
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, methodSignature.parameters);
|
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, methodSignature.parameters);
|
||||||
|
|
||||||
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
||||||
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
||||||
const docComment: tsdoc.DocComment | undefined = jsDoc
|
const docComment: tsdoc.DocComment | undefined = jsDoc
|
||||||
? this._tsDocParser.parseString(
|
? this._tsDocParser.parseString(
|
||||||
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
||||||
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
|
jsDoc.params
|
||||||
''
|
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
|
||||||
}${
|
.join('') ?? ''
|
||||||
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
}${
|
||||||
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
jsDoc.returns?.length && !Array.isArray(jsDoc.returns[0])
|
||||||
: ''
|
? ` * @returns ${fixLinkTags(jsDoc.returns[0]!.description ?? '')}`
|
||||||
}${
|
: ''
|
||||||
jsDoc.deprecated
|
}${
|
||||||
? ` * @deprecated ${
|
jsDoc.deprecated
|
||||||
typeof jsDoc.deprecated === 'string' ? fixLinkTags(jsDoc.deprecated) : jsDoc.deprecated
|
? ` * @deprecated ${
|
||||||
}\n`
|
typeof jsDoc.deprecated === 'string' ? fixLinkTags(jsDoc.deprecated) : jsDoc.deprecated
|
||||||
: ''
|
}\n`
|
||||||
} */`,
|
: ''
|
||||||
).docComment
|
} */`,
|
||||||
: apiItemMetadata.tsdocComment;
|
).docComment
|
||||||
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
: apiItemMetadata.tsdocComment;
|
||||||
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
||||||
const sourceLocation: ISourceLocation = this._getSourceLocation(methodSignature);
|
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
||||||
|
const sourceLocation: ISourceLocation = this._getSourceLocation(methodSignature);
|
||||||
|
|
||||||
apiMethodSignature = new ApiMethodSignature({
|
apiMethodSignature = new ApiMethodSignature({
|
||||||
name,
|
name,
|
||||||
docComment,
|
docComment,
|
||||||
releaseTag,
|
releaseTag,
|
||||||
isOptional,
|
isOptional,
|
||||||
typeParameters,
|
typeParameters,
|
||||||
parameters,
|
parameters,
|
||||||
overloadIndex,
|
overloadIndex,
|
||||||
excerptTokens,
|
excerptTokens,
|
||||||
returnTypeTokenRange,
|
returnTypeTokenRange,
|
||||||
fileUrlPath: jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
fileUrlPath: jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
||||||
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
fileLine: jsDoc?.meta.line ?? sourceLocation.sourceFileLine,
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
});
|
});
|
||||||
|
} else if (jsDoc) {
|
||||||
|
apiMethodSignature = new ApiMethodSignature(this._mapMethod(jsDoc, parentApiItem.getAssociatedPackage()!.name));
|
||||||
|
}
|
||||||
|
|
||||||
parentApiItem.addMember(apiMethodSignature);
|
parentApiItem.addMember(apiMethodSignature);
|
||||||
}
|
}
|
||||||
@@ -1133,77 +1199,90 @@ export class ApiModelGenerator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiProperty(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiProperty(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const isStatic: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0;
|
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | DocgenTypedefJson | undefined;
|
||||||
|
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
||||||
|
const isStatic: boolean = astDeclaration
|
||||||
|
? (astDeclaration.modifierFlags & ts.ModifierFlags.Static) !== 0
|
||||||
|
: parentApiItem.kind === ApiItemKind.Class || parentApiItem.kind === ApiItemKind.Interface
|
||||||
|
? (jsDoc as DocgenPropertyJson).scope === 'static'
|
||||||
|
: false;
|
||||||
const containerKey: string = ApiProperty.getContainerKey(name, isStatic);
|
const containerKey: string = ApiProperty.getContainerKey(name, isStatic);
|
||||||
|
|
||||||
let apiProperty: ApiProperty | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiProperty;
|
let apiProperty: ApiProperty | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiProperty;
|
||||||
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | DocgenTypedefJson | undefined;
|
|
||||||
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
|
||||||
|
|
||||||
if (apiProperty === undefined) {
|
if (apiProperty === undefined) {
|
||||||
const declaration: ts.Declaration = astDeclaration.declaration;
|
if (astDeclaration) {
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const declaration: ts.Declaration = astDeclaration.declaration;
|
||||||
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
|
|
||||||
const propertyTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
const propertyTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
let propertyTypeNode: ts.TypeNode | undefined;
|
let propertyTypeNode: ts.TypeNode | undefined;
|
||||||
|
|
||||||
if (ts.isPropertyDeclaration(declaration) || ts.isGetAccessorDeclaration(declaration)) {
|
if (ts.isPropertyDeclaration(declaration) || ts.isGetAccessorDeclaration(declaration)) {
|
||||||
propertyTypeNode = declaration.type;
|
propertyTypeNode = declaration.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ts.isSetAccessorDeclaration(declaration)) {
|
||||||
|
// Note that TypeScript always reports an error if a setter does not have exactly one parameter.
|
||||||
|
propertyTypeNode = declaration.parameters[0]!.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodesToCapture.push({ node: propertyTypeNode, tokenRange: propertyTypeTokenRange });
|
||||||
|
|
||||||
|
let initializerTokenRange: IExcerptTokenRange | undefined;
|
||||||
|
if (ts.isPropertyDeclaration(declaration) && declaration.initializer) {
|
||||||
|
initializerTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
|
nodesToCapture.push({ node: declaration.initializer, tokenRange: initializerTokenRange });
|
||||||
|
}
|
||||||
|
|
||||||
|
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
||||||
|
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
||||||
|
const docComment: tsdoc.DocComment | undefined = jsDoc
|
||||||
|
? this._tsDocParser.parseString(
|
||||||
|
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
||||||
|
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
|
||||||
|
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
|
||||||
|
'deprecated' in jsDoc && jsDoc.deprecated
|
||||||
|
? ` * @deprecated ${
|
||||||
|
typeof jsDoc.deprecated === 'string' ? fixLinkTags(jsDoc.deprecated) : jsDoc.deprecated
|
||||||
|
}\n`
|
||||||
|
: ''
|
||||||
|
} */`,
|
||||||
|
).docComment
|
||||||
|
: apiItemMetadata.tsdocComment;
|
||||||
|
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
||||||
|
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
||||||
|
const isProtected: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Protected) !== 0;
|
||||||
|
const isAbstract: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Abstract) !== 0;
|
||||||
|
const isReadonly: boolean = this._isReadonly(astDeclaration);
|
||||||
|
const sourceLocation: ISourceLocation = this._getSourceLocation(declaration);
|
||||||
|
|
||||||
|
apiProperty = new ApiProperty({
|
||||||
|
name,
|
||||||
|
docComment,
|
||||||
|
releaseTag,
|
||||||
|
isAbstract,
|
||||||
|
isProtected,
|
||||||
|
isStatic,
|
||||||
|
isOptional,
|
||||||
|
isReadonly,
|
||||||
|
excerptTokens,
|
||||||
|
propertyTypeTokenRange,
|
||||||
|
initializerTokenRange,
|
||||||
|
fileUrlPath: jsDoc && 'meta' in jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
||||||
|
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
||||||
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
|
});
|
||||||
|
} else if (parentApiItem.kind === ApiItemKind.Class || parentApiItem.kind === ApiItemKind.Interface) {
|
||||||
|
apiProperty = new ApiProperty(
|
||||||
|
this._mapProp(jsDoc as DocgenPropertyJson, parentApiItem.getAssociatedPackage()!.name),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(`We got a property in ApiItem of kind ${ApiItemKind[parentApiItem.kind]}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts.isSetAccessorDeclaration(declaration)) {
|
|
||||||
// Note that TypeScript always reports an error if a setter does not have exactly one parameter.
|
|
||||||
propertyTypeNode = declaration.parameters[0]!.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
nodesToCapture.push({ node: propertyTypeNode, tokenRange: propertyTypeTokenRange });
|
|
||||||
|
|
||||||
let initializerTokenRange: IExcerptTokenRange | undefined;
|
|
||||||
if (ts.isPropertyDeclaration(declaration) && declaration.initializer) {
|
|
||||||
initializerTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
|
||||||
nodesToCapture.push({ node: declaration.initializer, tokenRange: initializerTokenRange });
|
|
||||||
}
|
|
||||||
|
|
||||||
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
|
||||||
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
|
||||||
const docComment: tsdoc.DocComment | undefined = jsDoc
|
|
||||||
? this._tsDocParser.parseString(
|
|
||||||
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
|
||||||
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
|
|
||||||
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
|
|
||||||
'deprecated' in jsDoc && jsDoc.deprecated
|
|
||||||
? ` * @deprecated ${
|
|
||||||
typeof jsDoc.deprecated === 'string' ? fixLinkTags(jsDoc.deprecated) : jsDoc.deprecated
|
|
||||||
}\n`
|
|
||||||
: ''
|
|
||||||
} */`,
|
|
||||||
).docComment
|
|
||||||
: apiItemMetadata.tsdocComment;
|
|
||||||
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
|
||||||
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
|
||||||
const isProtected: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Protected) !== 0;
|
|
||||||
const isAbstract: boolean = (astDeclaration.modifierFlags & ts.ModifierFlags.Abstract) !== 0;
|
|
||||||
const isReadonly: boolean = this._isReadonly(astDeclaration);
|
|
||||||
const sourceLocation: ISourceLocation = this._getSourceLocation(declaration);
|
|
||||||
|
|
||||||
apiProperty = new ApiProperty({
|
|
||||||
name,
|
|
||||||
docComment,
|
|
||||||
releaseTag,
|
|
||||||
isAbstract,
|
|
||||||
isProtected,
|
|
||||||
isStatic,
|
|
||||||
isOptional,
|
|
||||||
isReadonly,
|
|
||||||
excerptTokens,
|
|
||||||
propertyTypeTokenRange,
|
|
||||||
initializerTokenRange,
|
|
||||||
fileUrlPath: jsDoc && 'meta' in jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
|
||||||
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
|
||||||
});
|
|
||||||
parentApiItem.addMember(apiProperty);
|
parentApiItem.addMember(apiProperty);
|
||||||
} else {
|
} else {
|
||||||
// If the property was already declared before (via a merged interface declaration),
|
// If the property was already declared before (via a merged interface declaration),
|
||||||
@@ -1211,7 +1290,7 @@ export class ApiModelGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _processApiPropertySignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
|
private _processApiPropertySignature(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
|
||||||
const { name, parentApiItem } = context;
|
const { name, parentApiItem } = context;
|
||||||
const containerKey: string = ApiPropertySignature.getContainerKey(name);
|
const containerKey: string = ApiPropertySignature.getContainerKey(name);
|
||||||
|
|
||||||
@@ -1222,41 +1301,49 @@ export class ApiModelGenerator {
|
|||||||
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
const jsDoc = parent?.props?.find((prop) => prop.name === name);
|
||||||
|
|
||||||
if (apiPropertySignature === undefined) {
|
if (apiPropertySignature === undefined) {
|
||||||
const propertySignature: ts.PropertySignature = astDeclaration.declaration as ts.PropertySignature;
|
if (astDeclaration) {
|
||||||
|
const propertySignature: ts.PropertySignature = astDeclaration.declaration as ts.PropertySignature;
|
||||||
|
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
|
|
||||||
const propertyTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
const propertyTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
nodesToCapture.push({ node: propertySignature.type, tokenRange: propertyTypeTokenRange });
|
nodesToCapture.push({ node: propertySignature.type, tokenRange: propertyTypeTokenRange });
|
||||||
|
|
||||||
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
|
||||||
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
||||||
const docComment: tsdoc.DocComment | undefined = jsDoc
|
const docComment: tsdoc.DocComment | undefined = jsDoc
|
||||||
? this._tsDocParser.parseString(
|
? this._tsDocParser.parseString(
|
||||||
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
|
||||||
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
|
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
|
||||||
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
|
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
|
||||||
'deprecated' in jsDoc && jsDoc.deprecated ? ` * @deprecated ${jsDoc.deprecated}\n` : ''
|
'deprecated' in jsDoc && jsDoc.deprecated ? ` * @deprecated ${jsDoc.deprecated}\n` : ''
|
||||||
} */`,
|
} */`,
|
||||||
).docComment
|
).docComment
|
||||||
: apiItemMetadata.tsdocComment;
|
: apiItemMetadata.tsdocComment;
|
||||||
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
||||||
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
const isOptional: boolean = (astDeclaration.astSymbol.followedSymbol.flags & ts.SymbolFlags.Optional) !== 0;
|
||||||
const isReadonly: boolean = this._isReadonly(astDeclaration);
|
const isReadonly: boolean = this._isReadonly(astDeclaration);
|
||||||
const sourceLocation: ISourceLocation = this._getSourceLocation(propertySignature);
|
const sourceLocation: ISourceLocation = this._getSourceLocation(propertySignature);
|
||||||
|
|
||||||
apiPropertySignature = new ApiPropertySignature({
|
apiPropertySignature = new ApiPropertySignature({
|
||||||
name,
|
name,
|
||||||
docComment,
|
docComment,
|
||||||
releaseTag,
|
releaseTag,
|
||||||
isOptional,
|
isOptional,
|
||||||
excerptTokens,
|
excerptTokens,
|
||||||
propertyTypeTokenRange,
|
propertyTypeTokenRange,
|
||||||
isReadonly,
|
isReadonly,
|
||||||
fileUrlPath: jsDoc && 'meta' in jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
fileUrlPath: jsDoc && 'meta' in jsDoc ? filePathFromJson(jsDoc.meta) : sourceLocation.sourceFilePath,
|
||||||
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
fileLine: jsDoc && 'meta' in jsDoc ? jsDoc.meta.line : sourceLocation.sourceFileLine,
|
||||||
fileColumn: sourceLocation.sourceFileColumn,
|
fileColumn: sourceLocation.sourceFileColumn,
|
||||||
});
|
});
|
||||||
|
} else if (parentApiItem.kind === ApiItemKind.Class || parentApiItem.kind === ApiItemKind.Interface) {
|
||||||
|
apiPropertySignature = new ApiPropertySignature(
|
||||||
|
this._mapProp(jsDoc as DocgenPropertyJson, parentApiItem.getAssociatedPackage()!.name),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(`We got a property in ApiItem of kind ${ApiItemKind[parentApiItem.kind]}`);
|
||||||
|
}
|
||||||
|
|
||||||
parentApiItem.addMember(apiPropertySignature);
|
parentApiItem.addMember(apiPropertySignature);
|
||||||
} else {
|
} else {
|
||||||
@@ -1582,25 +1669,27 @@ export class ApiModelGenerator {
|
|||||||
(arr, [type, symbol]) => [
|
(arr, [type, symbol]) => [
|
||||||
...arr,
|
...arr,
|
||||||
{
|
{
|
||||||
kind: ExcerptTokenKind.Reference,
|
kind: type?.includes("'") ? ExcerptTokenKind.Content : ExcerptTokenKind.Reference,
|
||||||
text: type ?? 'unknown',
|
text: type ?? 'unknown',
|
||||||
canonicalReference: DeclarationReference.package(this._apiModel.packages[0]!.name)
|
canonicalReference: type?.includes("'")
|
||||||
.addNavigationStep(Navigation.Members as any, DeclarationReference.parseComponent(type ?? 'unknown'))
|
? undefined
|
||||||
.withMeaning(
|
: DeclarationReference.package(this._apiModel.packages[0]!.name)
|
||||||
lookup[
|
.addNavigationStep(Navigation.Members as any, DeclarationReference.parseComponent(type ?? 'unknown'))
|
||||||
(
|
.withMeaning(
|
||||||
(this._collector.entities.find(
|
lookup[
|
||||||
(entity) => entity.nameForEmit === type && 'astDeclarations' in entity.astEntity,
|
(
|
||||||
)?.astEntity as AstSymbol | undefined) ??
|
(this._collector.entities.find(
|
||||||
(
|
(entity) => entity.nameForEmit === type && 'astDeclarations' in entity.astEntity,
|
||||||
this._collector.entities.find(
|
)?.astEntity as AstSymbol | undefined) ??
|
||||||
(entity) => entity.nameForEmit === type && 'astSymbol' in entity.astEntity,
|
(
|
||||||
)?.astEntity as AstImport | undefined
|
this._collector.entities.find(
|
||||||
)?.astSymbol
|
(entity) => entity.nameForEmit === type && 'astSymbol' in entity.astEntity,
|
||||||
)?.astDeclarations[0]?.declaration.kind ?? ts.SyntaxKind.ClassDeclaration
|
)?.astEntity as AstImport | undefined
|
||||||
] ?? ('class' as any),
|
)?.astSymbol
|
||||||
)
|
)?.astDeclarations[0]?.declaration.kind ?? ts.SyntaxKind.ClassDeclaration
|
||||||
.toString(),
|
] ?? ('class' as any),
|
||||||
|
)
|
||||||
|
.toString(),
|
||||||
},
|
},
|
||||||
{ kind: ExcerptTokenKind.Content, text: symbol ?? '' },
|
{ kind: ExcerptTokenKind.Content, text: symbol ?? '' },
|
||||||
],
|
],
|
||||||
@@ -1608,4 +1697,130 @@ export class ApiModelGenerator {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _mapProp(prop: DocgenPropertyJson, _package: string): IApiPropertyOptions {
|
||||||
|
const mappedVarType = this._mapVarType(prop.type);
|
||||||
|
return {
|
||||||
|
name: prop.name,
|
||||||
|
isAbstract: Boolean(prop.abstract),
|
||||||
|
isProtected: prop.access === 'protected',
|
||||||
|
isStatic: prop.scope === 'static',
|
||||||
|
isOptional: Boolean(prop.nullable),
|
||||||
|
isReadonly: Boolean(prop.readonly),
|
||||||
|
docComment: this._tsDocParser.parseString(
|
||||||
|
`/**\n * ${prop.description}\n${prop.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''}${
|
||||||
|
prop.readonly ? ' * @readonly\n' : ''
|
||||||
|
} */`,
|
||||||
|
).docComment,
|
||||||
|
excerptTokens: [
|
||||||
|
{
|
||||||
|
kind: ExcerptTokenKind.Content,
|
||||||
|
text: `${prop.access} ${prop.scope === 'static' ? 'static ' : ''}${prop.readonly ? 'readonly ' : ''}${
|
||||||
|
prop.name
|
||||||
|
} :`,
|
||||||
|
},
|
||||||
|
...mappedVarType,
|
||||||
|
{
|
||||||
|
kind: ExcerptTokenKind.Reference,
|
||||||
|
text: formatVarType(prop.type),
|
||||||
|
canonicalReference: `${_package}!${getFirstType(prop.type)}:class`,
|
||||||
|
},
|
||||||
|
{ kind: ExcerptTokenKind.Content, text: ';' },
|
||||||
|
],
|
||||||
|
propertyTypeTokenRange: { startIndex: 1, endIndex: 1 + mappedVarType.length },
|
||||||
|
releaseTag: prop.access === 'public' ? ReleaseTag.Public : ReleaseTag.Internal,
|
||||||
|
fileLine: prop.meta?.line ?? 0,
|
||||||
|
fileUrlPath: prop.meta ? `${prop.meta.path.slice(`packages/${_package}/`.length)}/${prop.meta.file}` : '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _mapParam(
|
||||||
|
param: DocgenParamJson,
|
||||||
|
index: number,
|
||||||
|
_package: string,
|
||||||
|
paramTokens: number[],
|
||||||
|
): IApiParameterOptions {
|
||||||
|
return {
|
||||||
|
parameterName: param.name.startsWith('...') ? param.name.slice(3) : param.name,
|
||||||
|
isOptional: Boolean(param.optional),
|
||||||
|
isRest: param.name.startsWith('...'),
|
||||||
|
parameterTypeTokenRange: {
|
||||||
|
startIndex: 1 + index + paramTokens.slice(0, index).reduce((akk, num) => akk + num, 0),
|
||||||
|
endIndex: 1 + index + paramTokens.slice(0, index + 1).reduce((akk, num) => akk + num, 0),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _mapMethod(method: DocgenMethodJson, _package: string): IApiMethodOptions {
|
||||||
|
const excerptTokens: IExcerptToken[] = [];
|
||||||
|
excerptTokens.push({
|
||||||
|
kind: ExcerptTokenKind.Content,
|
||||||
|
text: `${
|
||||||
|
method.scope === 'global'
|
||||||
|
? `export function ${method.name}(`
|
||||||
|
: `${method.access}${method.scope === 'static' ? ' static' : ''} ${method.name}(`
|
||||||
|
}${
|
||||||
|
method.params?.length
|
||||||
|
? `${method.params[0]!.name}${method.params[0]!.nullable || method.params[0]!.optional ? '?' : ''}`
|
||||||
|
: '): '
|
||||||
|
}`,
|
||||||
|
});
|
||||||
|
const paramTokens: number[] = [];
|
||||||
|
for (let index = 0; index < (method.params?.length ?? 0) - 1; index++) {
|
||||||
|
const newTokens = this._mapVarType(method.params![index]!.type);
|
||||||
|
paramTokens.push(newTokens.length);
|
||||||
|
excerptTokens.push(...newTokens);
|
||||||
|
excerptTokens.push({
|
||||||
|
kind: ExcerptTokenKind.Content,
|
||||||
|
text: `, ${method.params![index + 1]!.name}${
|
||||||
|
method.params![index + 1]!.nullable || method.params![index + 1]!.optional ? '?' : ''
|
||||||
|
}: `,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.params?.length) {
|
||||||
|
const newTokens = this._mapVarType(method.params[method.params.length - 1]!.type);
|
||||||
|
paramTokens.push(newTokens.length);
|
||||||
|
excerptTokens.push(...newTokens);
|
||||||
|
excerptTokens.push({ kind: ExcerptTokenKind.Content, text: `): ` });
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnTokens = this._mapVarType(method.returns?.[0] ?? []);
|
||||||
|
excerptTokens.push(...returnTokens);
|
||||||
|
|
||||||
|
excerptTokens.push({ kind: ExcerptTokenKind.Content, text: ';' });
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: method.name,
|
||||||
|
isAbstract: Boolean(method.abstract),
|
||||||
|
isOptional: false,
|
||||||
|
isProtected: method.access === 'protected',
|
||||||
|
isStatic: method.scope === 'static',
|
||||||
|
overloadIndex: 1,
|
||||||
|
parameters: method.params?.map((param, index) => this._mapParam(param, index, _package, paramTokens)) ?? [],
|
||||||
|
releaseTag: method.access === 'public' ? ReleaseTag.Public : ReleaseTag.Internal,
|
||||||
|
returnTypeTokenRange: method.returns?.length
|
||||||
|
? method.params?.length
|
||||||
|
? { startIndex: 2 + 2 * method.params.length, endIndex: 3 + 2 * method.params.length }
|
||||||
|
: { startIndex: 1, endIndex: 2 }
|
||||||
|
: { startIndex: 0, endIndex: 0 },
|
||||||
|
typeParameters: [],
|
||||||
|
docComment: this._tsDocParser.parseString(
|
||||||
|
`/**\n * ${method.description}\n${
|
||||||
|
method.params?.map((param) => ` * @param ${param.name} - ${param.description}\n`).join('') ?? ''
|
||||||
|
}${
|
||||||
|
method.returns?.length && !Array.isArray(method.returns[0])
|
||||||
|
? ` * @returns ${method.returns[0]!.description}`
|
||||||
|
: ''
|
||||||
|
}${method.examples?.map((example) => ` * @example\n * \`\`\`js\n * ${example}\n * \`\`\`\n`).join('') ?? ''}${
|
||||||
|
method.deprecated
|
||||||
|
? ` * @deprecated ${typeof method.deprecated === 'boolean' ? 'yes' : method.deprecated}\n`
|
||||||
|
: ''
|
||||||
|
} */`,
|
||||||
|
).docComment,
|
||||||
|
excerptTokens,
|
||||||
|
fileLine: method.meta.line,
|
||||||
|
fileUrlPath: `${method.meta.path.slice(`packages/${_package}/`.length)}/${method.meta.file}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user