From 794b155827868d67f1cec45bbe8c3a3e4be02597 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 18 Mar 2018 18:44:52 +0100 Subject: [PATCH] Add support for displaying exported functions --- packages/react-docs/CHANGELOG.md | 3 ++ .../src/components/documentation.tsx | 26 +++++++--- .../react-docs/src/components/interface.tsx | 10 ++-- .../{method_signature.tsx => signature.tsx} | 35 +++++++------ .../{method_block.tsx => signature_block.tsx} | 24 +++++---- packages/react-docs/src/components/type.tsx | 10 ++-- .../src/components/type_definition.tsx | 10 ++-- packages/react-docs/src/index.ts | 4 +- packages/react-docs/src/types.ts | 16 ++++++ .../react-docs/src/utils/typedoc_utils.ts | 52 ++++++++++++++++--- 10 files changed, 139 insertions(+), 51 deletions(-) rename packages/react-docs/src/components/{method_signature.tsx => signature.tsx} (76%) rename packages/react-docs/src/components/{method_block.tsx => signature_block.tsx} (87%) diff --git a/packages/react-docs/CHANGELOG.md b/packages/react-docs/CHANGELOG.md index 7f860739f0..aa1c3c210c 100644 --- a/packages/react-docs/CHANGELOG.md +++ b/packages/react-docs/CHANGELOG.md @@ -5,3 +5,6 @@ * Move example out into a separate sub-package * Consolidate all `console.log` calls into `logUtils` in the `@0xproject/utils` package (#452) * Handle `reflection` type rendering so that anonymous function type declarations render properly + * Rename `MethodSignature` to `Signature` and change it's props so that it can be used to render method and function signatures. + * Rename `MethodBlock` to `SignatureBlock` since it is not used to render method and function signature blocks. + * Add support for documenting exported functions. diff --git a/packages/react-docs/src/components/documentation.tsx b/packages/react-docs/src/components/documentation.tsx index b46358159a..67523dcc38 100644 --- a/packages/react-docs/src/components/documentation.tsx +++ b/packages/react-docs/src/components/documentation.tsx @@ -25,6 +25,7 @@ import { SolidityMethod, SupportedDocJson, TypeDefinitionByName, + TypescriptFunction, TypescriptMethod, } from '../types'; import { constants } from '../utils/constants'; @@ -33,7 +34,7 @@ import { utils } from '../utils/utils'; import { Badge } from './badge'; import { Comment } from './comment'; import { EventDefinition } from './event_definition'; -import { MethodBlock } from './method_block'; +import { SignatureBlock } from './signature_block'; import { SourceLink } from './source_link'; import { Type } from './type'; import { TypeDefinition } from './type_definition'; @@ -216,8 +217,12 @@ export class Documentation extends React.Component { - const isConstructor = false; - return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName); + return this._renderSignatureBlocks(method, sectionName, typeDefinitionByName); + }); + + const sortedFunctions = _.sortBy(docSection.functions, 'name'); + const functionDefs = _.map(sortedFunctions, func => { + return this._renderSignatureBlocks(func, sectionName, typeDefinitionByName); }); const sortedEvents = _.sortBy(docSection.events, 'name'); @@ -262,6 +267,12 @@ export class Documentation extends React.Component{methodDefs} )} + {docSection.functions.length > 0 && ( +
+

Functions

+
{functionDefs}
+
+ )} {!_.isUndefined(docSection.events) && docSection.events.length > 0 && (
@@ -318,7 +329,7 @@ export class Documentation extends React.Component { - return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName); + return this._renderSignatureBlocks(constructor, sectionName, typeDefinitionByName); }); return
{constructorDefs}
; } @@ -340,14 +351,13 @@ export class Documentation extends React.Component ); } - private _renderMethodBlocks( - method: SolidityMethod | TypescriptMethod, + private _renderSignatureBlocks( + method: SolidityMethod | TypescriptFunction | TypescriptMethod, sectionName: string, - isConstructor: boolean, typeDefinitionByName: TypeDefinitionByName, ): React.ReactNode { return ( - ) : ( - = (props: MethodSignatureProps) => { +export const Signature: React.SFC = (props: SignatureProps) => { const sectionName = constants.TYPES_SECTION_NAME; - const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName); + const parameters = renderParameters(props.parameters, props.docsInfo, sectionName, props.typeDefinitionByName); const paramStringArray: any[] = []; // HACK: For now we don't put params on newlines if there are less then 2 of them. // Ideally we would check the character length of the resulting method signature and @@ -51,21 +56,21 @@ export const MethodSignature: React.SFC = (props: MethodSi if (!hasMoreThenTwoParams) { paramStringArray.pop(); } - const methodName = props.shouldHideMethodName ? '' : props.method.name; - const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter) + const methodName = props.shouldHideMethodName ? '' : props.name; + const typeParameterIfExists = _.isUndefined(props.typeParameter) ? undefined - : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName); + : renderTypeParameter(props.typeParameter, props.docsInfo, sectionName, props.typeDefinitionByName); return ( - {props.method.callPath} + {props.callPath} {methodName} {typeParameterIfExists}({hasMoreThenTwoParams &&
} {paramStringArray}) - {props.method.returnType && ( + {props.returnType && ( {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '} = (props: MethodSi ); }; -MethodSignature.defaultProps = defaultProps; +Signature.defaultProps = defaultProps; function renderParameters( - method: TypescriptMethod | SolidityMethod, + parameters: Parameter[], docsInfo: DocsInfo, sectionName: string, typeDefinitionByName?: TypeDefinitionByName, ) { - const parameters = method.parameters; const params = _.map(parameters, (p: Parameter) => { const isOptional = p.isOptional; const type = ( @@ -106,12 +110,11 @@ function renderParameters( } function renderTypeParameter( - method: TypescriptMethod, + typeParameter: TypeParameter, docsInfo: DocsInfo, sectionName: string, typeDefinitionByName?: TypeDefinitionByName, ) { - const typeParameter = method.typeParameter; const typeParam = ( {`<${typeParameter.name} extends `} diff --git a/packages/react-docs/src/components/method_block.tsx b/packages/react-docs/src/components/signature_block.tsx similarity index 87% rename from packages/react-docs/src/components/method_block.tsx rename to packages/react-docs/src/components/signature_block.tsx index 44a1db8afe..6475d39956 100644 --- a/packages/react-docs/src/components/method_block.tsx +++ b/packages/react-docs/src/components/signature_block.tsx @@ -3,16 +3,16 @@ import * as _ from 'lodash'; import * as React from 'react'; import { DocsInfo } from '../docs_info'; -import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } from '../types'; +import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptFunction, TypescriptMethod } from '../types'; import { constants } from '../utils/constants'; import { typeDocUtils } from '../utils/typedoc_utils'; import { Comment } from './comment'; -import { MethodSignature } from './method_signature'; +import { Signature } from './signature'; import { SourceLink } from './source_link'; -export interface MethodBlockProps { - method: SolidityMethod | TypescriptMethod; +export interface SignatureBlockProps { + method: SolidityMethod | TypescriptFunction | TypescriptMethod; sectionName: string; libraryVersion: string; typeDefinitionByName: TypeDefinitionByName; @@ -20,7 +20,7 @@ export interface MethodBlockProps { sourceUrl: string; } -export interface MethodBlockState { +export interface SignatureBlockState { shouldShowAnchor: boolean; } @@ -35,8 +35,8 @@ const styles: Styles = { }, }; -export class MethodBlock extends React.Component { - constructor(props: MethodBlockProps) { +export class SignatureBlock extends React.Component { + constructor(props: SignatureBlockProps) { super(props); this.state = { shouldShowAnchor: false, @@ -56,7 +56,7 @@ export class MethodBlock extends React.Component - {!method.isConstructor && ( + {!(method as TypescriptMethod).isConstructor && (
{(method as TypescriptMethod).isStatic && this._renderChip('Static')} {(method as SolidityMethod).isConstant && this._renderChip('Constant')} @@ -72,8 +72,12 @@ export class MethodBlock extends React.Component )} - ) : ( - ; properties: Property[]; types: CustomType[]; + functions?: TypescriptFunction[]; events?: Event[]; } @@ -117,6 +120,11 @@ export interface TypescriptMethod extends BaseMethod { typeParameter?: TypeParameter; } +export interface TypescriptFunction extends BaseFunction { + source?: Source; + typeParameter?: TypeParameter; +} + export interface SolidityMethod extends BaseMethod { isConstant?: boolean; isPayable?: boolean; @@ -205,6 +213,14 @@ export interface BaseMethod { comment?: string; } +export interface BaseFunction { + name: string; + returnComment?: string | undefined; + parameters: Parameter[]; + returnType: Type; + comment?: string; +} + export interface TypeDefinitionByName { [typeName: string]: CustomType; } diff --git a/packages/react-docs/src/utils/typedoc_utils.ts b/packages/react-docs/src/utils/typedoc_utils.ts index e4cea1e401..4c76172347 100644 --- a/packages/react-docs/src/utils/typedoc_utils.ts +++ b/packages/react-docs/src/utils/typedoc_utils.ts @@ -15,6 +15,7 @@ import { TypeDocNode, TypeDocType, TypeParameter, + TypescriptFunction, TypescriptMethod, } from '../types'; import { utils } from '../utils/utils'; @@ -81,17 +82,16 @@ export const typeDocUtils = { } } - // Since the `types.ts` file is the only file that does not export a module/class but - // instead has each type export itself, we do not need to go down two levels of nesting - // for it. let entities; let packageComment = ''; - if (sectionName === docsInfo.sections.types) { - entities = packageDefinitionWithMergedChildren.children; - } else { + // HACK: We assume 1 exported class per file + const isClassExport = packageDefinitionWithMergedChildren.children[0].kindString === KindString.Class; + if (isClassExport) { entities = packageDefinitionWithMergedChildren.children[0].children; const commentObj = packageDefinitionWithMergedChildren.children[0].comment; packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment; + } else { + entities = packageDefinitionWithMergedChildren.children; } const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName); @@ -105,6 +105,7 @@ export const typeDocUtils = { comment: '', constructors: [], methods: [], + functions: [], properties: [], types: [], }; @@ -124,6 +125,13 @@ export const typeDocUtils = { docSection.constructors.push(constructor); break; + case KindString.Function: + if (entity.flags.isExported) { + const func = typeDocUtils._convertFunction(entity, docsInfo.sections, sectionName, docsInfo.id); + docSection.functions.push(func); + } + break; + case KindString.Method: if (entity.flags.isPublic) { isConstructor = false; @@ -303,6 +311,38 @@ export const typeDocUtils = { }; return method; }, + _convertFunction( + entity: TypeDocNode, + sections: SectionsMap, + sectionName: string, + docId: string, + ): TypescriptFunction { + const signature = entity.signatures[0]; + const source = entity.sources[0]; + const hasComment = !_.isUndefined(signature.comment); + + const parameters = _.map(signature.parameters, param => { + return typeDocUtils._convertParameter(param, sections, sectionName, docId); + }); + const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId); + const typeParameter = _.isUndefined(signature.typeParameter) + ? undefined + : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId); + + const func = { + name: signature.name, + comment: hasComment ? signature.comment.shortText : undefined, + returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined, + source: { + fileName: source.fileName, + line: source.line, + }, + parameters, + returnType, + typeParameter, + }; + return func; + }, _convertTypeParameter( entity: TypeDocNode, sections: SectionsMap,