import React from 'react';
import { ReflectionKind } from 'typedoc/dist/lib/models/reflections/abstract';
import type { JSONOutput } from 'typedoc';
import {
TokenPunctuation,
TokenAttrName,
TokenKeyword,
TokenPlain,
TokenLiteral
} from './tokens';
import renderArrowSignature from './renderArrowSignature';
import renderFunctionSignature from './renderFunctionSignature';
import Indent from './Indent';
import renderType from './renderType';
import renderTypeParameters from './renderTypeParameters';
import reduceReflectionsWith from './reduceReflectionsWith';
import Params from './Params';
function renderArrowSignatures(
signatures: JSONOutput.SignatureReflection[],
params: Params
) {
if (!signatures) {
return 'unknown';
}
return <>{signatures.map((s) => renderArrowSignature(s, params))}>;
}
function renderFunctionSignatures(
signatures: JSONOutput.SignatureReflection[],
params: Params
) {
return <>{signatures.map((s) => renderFunctionSignature(s, params))}>;
}
function renderConst(name: string) {
return (
<>
const
{name}
:
>
);
}
function renderAttribute(
name: string,
typeElm: any,
flags: JSONOutput.ReflectionFlags,
params: Params
) {
const nameToken = {name};
return (
<>
{flags.isStatic && static }
{params.resolveMembersLinks ? (
{nameToken}
) : (
nameToken
)}
{flags.isOptional && ?}
{': '}
{typeElm}
{';'}
>
);
}
function renderEnumMember(name: string, typeElm: any, params: Params) {
const nameToken = {name};
return (
<>
{params.resolveMembersLinks ? (
{nameToken}
) : (
nameToken
)}
{' = '}
{typeElm}
{';'}
>
);
}
function renderPropsAndMethods(
reflection: JSONOutput.DeclarationReflection,
params: Params
) {
const props = reflection.children?.filter(
(c) => c.kind === ReflectionKind.Property
);
const methods = reflection.children?.filter(
(c) => c.kind === ReflectionKind.Method
);
return (
<>
{props?.reduce(
reduceReflectionsWith(null, params, renderReflection),
null
)}
{methods?.reduce(
reduceReflectionsWith(null, params, renderReflection),
null
)}
>
);
}
function renderFunction(
reflection: JSONOutput.DeclarationReflection,
params: Params
) {
return (
<>
function
{reflection.name}
{renderFunctionSignatures(reflection.signatures, params)}
>
);
}
export default function renderReflection(
reflection: JSONOutput.DeclarationReflection,
params: Params
) {
let nextParams: Params = params;
switch (reflection.kind) {
case ReflectionKind.Function:
return renderFunction(
reflection,
params.withMemberLinks().withTypeParamsLinks()
);
case ReflectionKind.TypeAlias:
return (
<>
type
{reflection.name}
{renderTypeParameters(
reflection.typeParameter,
params.withTypeParamsLinks()
)}
{' = '}
{renderType(reflection.type, params)}
>
);
case ReflectionKind.Enum:
return (
<>
enum
{reflection.name}
{'{'}
{reflection.children.reduce(
reduceReflectionsWith(null, params.withIndent(), renderReflection),
null
)}
{'}'}
>
);
case ReflectionKind.Class:
return (
<>
class
{reflection.name}
{renderTypeParameters(
reflection.typeParameter,
params.withTypeParamsLinks()
)}
{'{'}
{renderPropsAndMethods(
reflection,
params.withMemberLinks().withIndent()
)}
{'}'}
>
);
case ReflectionKind.Interface:
nextParams = params.withIndent().withMemberLinks();
return (
<>
interface
{reflection.name}
{renderTypeParameters(
reflection.typeParameter,
params.withTypeParamsLinks()
)}
{'{'}
{reflection.signatures && (
<>
{renderFunctionSignatures(reflection.signatures, nextParams)}
;
>
)}
{renderPropsAndMethods(reflection, nextParams.withMemberLinks())}
{'}'}
>
);
case ReflectionKind.Parameter:
return renderAttribute(
reflection.name,
renderType(reflection.type, params),
reflection.flags,
params
);
case ReflectionKind.Property:
nextParams = params.withoutMemberLinks();
return renderAttribute(
reflection.name,
renderType(reflection.type, nextParams),
reflection.flags,
params
);
case ReflectionKind.TypeLiteral:
if (!reflection.groups && !reflection.signatures) {
console.warn('Unhandled Type Literal with no group', reflection);
return any;
}
if (reflection.signatures) {
return renderArrowSignatures(reflection.signatures, params);
}
let ret: any = null;
for (const group of reflection.groups!) {
if (group.kind === ReflectionKind.Property) {
const props = reflection.children.filter((c) =>
group.children.includes(c.id)
);
ret = (
<>
{'{'}
{props.map((p) => renderReflection(p, params.withIndent()))}
{'}'}
>
);
} else {
throw new Error(`Unhandled group of type ${group.title}`);
}
}
return ret;
case ReflectionKind.Method:
return reflection.signatures?.map((s) => {
return renderAttribute(
reflection.name,
renderArrowSignatures([s], params.withoutMemberLinks()),
reflection.flags,
params
);
});
case ReflectionKind.Function:
return renderArrowSignatures(
(reflection as JSONOutput.DeclarationReflection).signatures,
params
);
case ReflectionKind.CallSignature:
return (
<>
{renderConst(reflection.name)}
{renderArrowSignature(reflection, params)}
>
);
case ReflectionKind.Variable:
if (reflection.signatures) {
// For docs legibility, consider const with signature like functions
return renderFunction(reflection, params.withMemberLinks());
}
return (
<>
{renderConst(reflection.name)}
{renderType(reflection.type, params)}
>
);
case ReflectionKind.EnumMember:
return renderEnumMember(
reflection.name,
{reflection.defaultValue},
params
);
default:
console.warn(
'Unhandled Declaration Reflection of kind',
reflection.kindString,
reflection
);
throw new Error(
`Unhandled Declaration Reflection of kind ${reflection.kindString}`
);
}
}