Skip to content

Commit

Permalink
Added type alias documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei15193 committed Oct 17, 2024
1 parent d313d3f commit 1905e7b
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 40 deletions.
171 changes: 155 additions & 16 deletions docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,37 @@ void async function () {

if (project.children)
await Promise.all(project.children.map(async declaration => {
const subDirectory1 = declaration.sources?.at(0)?.fileName.split('/').at(0);
let subDirectory2: string;
let documentation: string | null = null;
switch (declaration.kind) {
case ReflectionKind.TypeAlias:
subDirectory2 = 'aliases';
documentation = getAliasDocumentation(declaration);
break;

case ReflectionKind.Interface:
subDirectory2 = 'interfaces';
documentation = getInterfaceDocumentation(declaration);
break;

case ReflectionKind.Class:
subDirectory2 = 'classes';
documentation = getClassDocumentation(declaration);
break;

case ReflectionKind.Function:
subDirectory2 = 'functions';
documentation = getFunctionDocumentation(declaration);
break;
}

if (documentation !== null)
await writeFileAsync(path.join(outputDirectory, `${getIdentifier(declaration)}.md`), documentation);
if (documentation !== null) {
const directoryPath = path.join(outputDirectory, subDirectory1!, subDirectory2!);

await mkdirAsync(directoryPath, { recursive: true });
await writeFileAsync(path.join(directoryPath, `${getIdentifier(declaration)}.md`), documentation);
}
}));

function findDeclaration(target: Reflection | ReflectionSymbolId | string | undefined): DeclarationReflection {
Expand All @@ -58,6 +72,32 @@ void async function () {
return declaration;
}

function getAliasDocumentation(aliasDeclaration: DeclarationReflection): string {
return `
###### [API](https://github.com/Andrei15193/react-model-view-viewmodel/wiki#api) / ${getFullName(aliasDeclaration)} alias
${getDeprecationNotice(aliasDeclaration)}
${getSummary(aliasDeclaration)}
\`\`\`ts
${getDeclaration(aliasDeclaration)}
\`\`\`
${getSourceCodeLink(aliasDeclaration)}
${getGenericParameters(aliasDeclaration)}
${getDescription(aliasDeclaration)}
${getRemarks(aliasDeclaration)}
${getGuidance(aliasDeclaration)}
${getReferences(aliasDeclaration)}
`.replace(/\n{3,}/g, '\n\n').trim();
}

function getInterfaceDocumentation(interfaceDeclaration: DeclarationReflection): string {
return `
###### [API](https://github.com/Andrei15193/react-model-view-viewmodel/wiki#api) / ${getFullName(interfaceDeclaration)} interface
Expand Down Expand Up @@ -195,6 +235,7 @@ ${getReferences(functionSignature)}
case ReflectionKind.Method:
return declaration.parent!.name + '.' + getSimpleName(declaration);

case ReflectionKind.TypeAlias:
case ReflectionKind.Class:
case ReflectionKind.Interface:
case ReflectionKind.Function:
Expand Down Expand Up @@ -239,6 +280,56 @@ ${getReferences(functionSignature)}

function getDeclaration(declaration: DeclarationReflection | SignatureReflection): string {
switch (declaration.kind) {
case ReflectionKind.TypeAlias:
let aliasDeclaration = `type ${declaration.name}`;

if (declaration.typeParameters && declaration.typeParameters.length > 0)
aliasDeclaration += `<${declaration.typeParameters.map(getTypeParameterDeclaration).join(', ')}>`;

switch (declaration.type?.type) {
case 'union':
return aliasDeclaration
+ '\n= '
+ declaration
.type
.types
.map(type => {
if (type.type === 'tuple')
return `[\n ${type.elements.map(getTypeReferenceDeclaration).join(',\n ')}\n ]`;
else
return getTypeReferenceDeclaration(type);
})
.join('\n| ')
+ ';';

case 'reflection':
if (
declaration.type.declaration.kind === ReflectionKind.TypeLiteral
&& declaration.type.declaration.signatures
&& declaration.type.declaration.signatures.length === 1
&& declaration.type.declaration.signatures.at(0)!.name === declaration.type.declaration.name
)
return aliasDeclaration + '\n = ' + getTypeReferenceDeclaration(declaration.type!) + ';';
else
return aliasDeclaration + ' = ' + getTypeReferenceDeclaration(declaration.type!) + ';';

case 'indexedAccess':
return aliasDeclaration + '\n = ' + getTypeReferenceDeclaration(declaration.type!) + ';';

default:
throw new Error(`Unhandled '${declaration.type?.type}' declaration type.`);
}

case ReflectionKind.Interface:
let interfaceDeclaration = `interface ${declaration.name}`;

if (declaration.typeParameters && declaration.typeParameters.length > 0)
interfaceDeclaration += `<${declaration.typeParameters.map(getTypeParameterDeclaration).join(', ')}>`;
if (declaration.extendedTypes && declaration.extendedTypes.length > 0)
interfaceDeclaration += `\n extends ${declaration.extendedTypes.map(getTypeReferenceDeclaration).join(', ')}`;

return interfaceDeclaration;

case ReflectionKind.Class:
let classDeclaration = `class ${declaration.name}`;

Expand All @@ -254,16 +345,6 @@ ${getReferences(functionSignature)}

return classDeclaration;

case ReflectionKind.Interface:
let interfaceDeclaration = `interface ${declaration.name}`;

if (declaration.typeParameters && declaration.typeParameters.length > 0)
interfaceDeclaration += `<${declaration.typeParameters.map(getTypeParameterDeclaration).join(', ')}>`;
if (declaration.extendedTypes && declaration.extendedTypes.length > 0)
interfaceDeclaration += `\n extends ${declaration.extendedTypes.map(getTypeReferenceDeclaration).join(', ')}`;

return interfaceDeclaration;

case ReflectionKind.CallSignature:
let functionDeclaration = 'function ' + declaration.name;

Expand Down Expand Up @@ -322,9 +403,67 @@ ${getReferences(functionSignature)}
case 'reference':
return `${typeReference.name}${typeReference.typeArguments && typeReference.typeArguments.length > 0 ? `<${typeReference.typeArguments.map(getTypeReferenceDeclaration).join(', ')}>` : ''}`;

case 'reflection':
switch (typeReference.declaration.kind) {
case ReflectionKind.TypeAlias:
case ReflectionKind.Class:
case ReflectionKind.Interface:
let typeReferenceDeclaration = typeReference.declaration.name;
if (typeReference.declaration.typeParameters && typeReference.declaration.typeParameters.length > 0) {
typeReferenceDeclaration += '<';
typeReferenceDeclaration += typeReference
.declaration
.typeParameters
.map(genericParameter => getTypeReferenceDeclaration(genericParameter.type!))
.join(', ');
typeReferenceDeclaration += '>';
}

return typeReferenceDeclaration;

case ReflectionKind.TypeLiteral:
if (typeReference.declaration.type)
return getTypeReferenceDeclaration(typeReference.declaration.type);
else if (typeReference.declaration.signatures) {
if (typeReference.declaration.signatures.length === 1 && typeReference.declaration.signatures.at(0)!.name === typeReference.declaration.name) {
const signature = typeReference.declaration.signatures.at(0)!
return `(${(signature.parameters || []).map(getParameterDeclaration).join(', ')}) => ${getTypeReferenceDeclaration(signature.type!)}`;
}
else {
let signaturesDeclarations = '{\n ';
signaturesDeclarations += typeReference
.declaration
.signatures
.map(signature => {
if (signature.kind === ReflectionKind.ConstructorSignature)
return `new (${(signature.parameters || []).map(getParameterDeclaration).join(', ')}): ${getTypeReferenceDeclaration(signature.type!)};`;
else {
const genericTypeDeclaration = signature.typeParameters?.map(getTypeParameterDeclaration).join(', ') || '';
return `${signature.name}${genericTypeDeclaration.length > 0 ? '<' + genericTypeDeclaration + '>' : ''}(${(signature.parameters || []).map(getParameterDeclaration).join(', ')}): ${getTypeReferenceDeclaration(signature.type!)};`;
}
})
.join('\n ');
signaturesDeclarations += '\n}';

return signaturesDeclarations;
}
}
else
throw new Error(`Unhandled '${typeReference.declaration}' type literal reflection reference declaration.`);

case ReflectionKind.IndexSignature:
return typeReference.declaration.name;

default:
throw new Error(`Unhandled '${typeReference.declaration}' reflection reference declaration.`);
}

case 'intersection':
return typeReference.types.map(getTypeReferenceDeclaration).join(' | ');

case 'union':
return typeReference.types.map(getTypeReferenceDeclaration).join(' | ');

case 'intrinsic':
return typeReference.name;

Expand All @@ -350,9 +489,6 @@ ${getReferences(functionSignature)}
case 'typeOperator':
return `${typeReference.operator} ${getTypeReferenceDeclaration(typeReference.target)}`;

case 'union':
return typeReference.types.map(getTypeReferenceDeclaration).join(' | ');

case 'array':
switch (typeReference.elementType.type) {
case 'reference':
Expand All @@ -371,6 +507,9 @@ ${getReferences(functionSignature)}
else
throw new Error('Unhandled predicate type declaration.');

case 'indexedAccess':
return getTypeReferenceDeclaration(typeReference.objectType) + `[${getTypeReferenceDeclaration(typeReference.indexType)}]`;

default:
throw new Error(`Unhandled '${typeReference.type}' type declaration.`);
}
Expand Down Expand Up @@ -777,7 +916,7 @@ ${getReferences(functionSignature)}
function getReferences(declaration: DeclarationReflection | SignatureReflection): string {
const references = declaration.comment?.blockTags.filter(blockTag => blockTag.tag === '@see') || [];
if (references.length > 0)
return '### See also\n\n' + references.reduce((result, reference) => result + `* ${getBlock(reference.content)}\n`, '');
return '### See also\n\n' + references.map(reference => getBlock(reference.content).replace(/^[ \t]-/gm, '*')).join('\n');
else
return '';
}
Expand Down
17 changes: 10 additions & 7 deletions src/dependencies/DependencyContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,24 +184,27 @@ export class DependencyContainer implements IDependencyContainer, IDependencyRes

/**
* Resolves a dependency based on its configuration, if any. All unconfigured dependencies are transient.
*
* @template T The dependency type to resolve.
*
* @param dependency The dependnecy to resolve.
*
* @returns The resolved dependency.
*/
public resolve<T>(dependency: ResolvableSimpleDependency<T>): T;
/**
* Resolves a complex dependency. All such dependencies are transient as they require
* additional dependencies on the constructor.
*
* @template T The dependency type to resolve.
* @template TAdditional A tuple representing additional parameters required by the constructor.
*
* @param dependency The complex dependnecy to resolve.
* @param additionalDependencies Additional dependencies requested by the constructor besides the dependency resolver.
* @returns The resolved dependency.
*
* @returns The resolved dependency.
*/
public resolve<T, TAdditional extends readonly any[]>(dependency: ComplexDependency<T, TAdditional>, additionalDependencies: TAdditional): T;
/**
* Resolves a dependency based on its configuration. All complex dependencies are transient, all unconfigured dependencies are transient.
* @param dependency The dependency to resolve.
* @param additionalDependencies Additional dependencies requested by the constructor besides the dependency resolver.
*/
public resolve<T, TAdditional extends readonly any[] = []>(dependency: ResolvableSimpleDependency<T> | ComplexDependency<T, TAdditional>, additionalDependencies: TAdditional): T;

public resolve<T, TAdditional extends readonly any[]>(dependency: ResolvableSimpleDependency<T> | ComplexDependency<T, TAdditional>, additionalDependencies?: TAdditional): T {
try {
Expand Down
30 changes: 28 additions & 2 deletions src/dependencies/DependencyResolverContext.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import type { IDependencyResolver } from "./IDependencyResolver";
import type { IDependencyResolver, ResolvableSimpleDependency } from "./IDependencyResolver";
import type { IDependencyContainer, ConfigurableDependency } from "./IDependencyContainer";
import type { useDependency } from './UseDependency';
import { DependencyContainer } from "./DependencyContainer";
import { type PropsWithChildren, createContext, createElement, useContext, useMemo, useRef } from "react";

const DependencyResolverContext = createContext<IDependencyResolver>(new DependencyContainer());

/**
* Gets the currently configured dependency resolver.
*
* @returns Returns the currently configured dependency resolver.
*
* @see {@link IDependencyResolver}
* @see {@link IDependencyContainer}
* @see {@link ConfigurableDependency}
* @see {@link ResolvableSimpleDependency}
* @see {@link useDependency}
* @see {@link DependencyResolverProvider}
* @see {@link DependencyResolverScope}
*/
export function useDependencyResolver(): IDependencyResolver {
return useContext(DependencyResolverContext);
}

/**
* Represents the dependency resolver context provider props.
*
* @see {@link DependencyResolverProvider}
*/
export interface IDependencyResolverProviderProps {
/**
Expand All @@ -24,8 +37,15 @@ export interface IDependencyResolverProviderProps {

/**
* Configures a dependency resolver in the context of child components.
*
* @returns Returns the `children` in the context of the provided `dependencyResolver`.
*
* @see {@link IDependencyResolver}
* @see {@link IDependencyContainer}
* @see {@link useDependency}
*/
export function DependencyResolverProvider({ dependencyResolver, children }: PropsWithChildren<IDependencyResolverProviderProps>): JSX.Element {
export function DependencyResolverProvider(props: PropsWithChildren<IDependencyResolverProviderProps>): JSX.Element {
const { dependencyResolver, children } = props;
return createElement(DependencyResolverContext.Provider, {
value: dependencyResolver,
children
Expand All @@ -34,6 +54,8 @@ export function DependencyResolverProvider({ dependencyResolver, children }: Pro

/**
* Represents the dependency resolver scope context provider props.
*
* @see {@link DependencyResolverScope}
*/
export interface IDependencyResolverScopeProps {
/**
Expand All @@ -47,6 +69,10 @@ const emptyDeps: readonly any[] = [];

/**
* Configures a dependency resolver scope in the context of child components.
*
* @see {@link IDependencyResolver}
* @see {@link IDependencyContainer}
* @see {@link useDependency}
*/
export function DependencyResolverScope({ deps, children }: PropsWithChildren<IDependencyResolverScopeProps>): JSX.Element {
const normalizedDeps = deps === null || deps === undefined || !Array.isArray(deps) || deps.length === 0
Expand Down
Loading

0 comments on commit 1905e7b

Please sign in to comment.