BREAKING CHANGE: document contracts from sol-doc

Change website to accept smart contract documentation in the format
generated by sol-doc rather than that generated by Doxity.
This commit is contained in:
F. Eugene Aumson
2018-09-22 11:06:48 -04:00
parent 9f0dfb1e1a
commit 98d06d6d25
12 changed files with 48 additions and 236 deletions

View File

@@ -329,7 +329,7 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
return <div>{externalExports}</div>;
}
private _renderNetworkBadgesIfExists(sectionName: string): React.ReactNode {
if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
if (this.props.docsInfo.type !== SupportedDocJson.Solidity) {
return null;
}

View File

@@ -1,18 +1,15 @@
import { MenuSubsectionsBySection } from '@0xproject/react-shared';
import { DocAgnosticFormat, GeneratedDocJson, TypeDefinitionByName } from '@0xproject/types';
import { DocAgnosticFormat, TypeDefinitionByName } from '@0xproject/types';
import * as _ from 'lodash';
import {
ContractsByVersionByNetworkId,
DocsInfoConfig,
DocsMenu,
DoxityDocObj,
SectionNameToMarkdownByVersion,
SectionsMap,
SupportedDocJson,
} from './types';
import { doxityUtils } from './utils/doxity_utils';
import { TypeDocUtils } from './utils/typedoc_utils';
export class DocsInfo {
public id: string;
@@ -93,12 +90,4 @@ export class DocsInfo {
const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name') as any;
return typeDefinitionByName;
}
public convertToDocAgnosticFormat(docObj: DoxityDocObj | GeneratedDocJson): DocAgnosticFormat {
if (this.type === SupportedDocJson.Doxity) {
return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj);
} else {
const typeDocUtils = new TypeDocUtils(docObj as GeneratedDocJson, this);
return typeDocUtils.convertToDocAgnosticFormat();
}
}
}

View File

@@ -14,9 +14,10 @@ export { Signature } from './components/signature';
export { SourceLink } from './components/source_link';
export { TypeDefinition } from './components/type_definition';
export { Type } from './components/type';
export { TypeDocUtils } from './utils/typedoc_utils';
export { DocsInfo } from './docs_info';
export { DocsInfoConfig, DoxityDocObj, DocsMenu, SupportedDocJson } from './types';
export { DocsInfoConfig, DocsMenu, SupportedDocJson } from './types';
export { constants } from './utils/constants';

View File

@@ -38,7 +38,7 @@ export enum KindString {
}
export enum SupportedDocJson {
Doxity = 'DOXITY',
Solidity = 'SOLIDITY',
TypeDoc = 'TYPEDOC',
}
@@ -50,40 +50,6 @@ export interface ContractsByVersionByNetworkId {
};
}
export interface DoxityDocObj {
[contractName: string]: DoxityContractObj;
}
export interface DoxityContractObj {
title: string;
fileName: string;
name: string;
abiDocs: DoxityAbiDoc[];
}
export interface DoxityAbiDoc {
constant: boolean;
inputs: DoxityInput[];
name: string;
outputs: DoxityOutput[];
payable: boolean;
type: string;
details?: string;
return?: string;
}
export interface DoxityOutput {
name: string;
type: string;
}
export interface DoxityInput {
name: string;
type: string;
description: string;
indexed?: boolean;
}
export interface AddressByContractName {
[contractName: string]: string;
}

View File

@@ -4,7 +4,7 @@ export const constants = {
TYPES_SECTION_NAME: 'types',
EXTERNAL_EXPORTS_SECTION_NAME: 'external exports',
TYPE_TO_SYNTAX: {
[SupportedDocJson.Doxity]: 'solidity',
[SupportedDocJson.Solidity]: 'solidity',
[SupportedDocJson.TypeDoc]: 'typescript',
} as { [supportedDocType: string]: string },
};

View File

@@ -1,173 +0,0 @@
import * as _ from 'lodash';
import {
DocAgnosticFormat,
DocSection,
EventArg,
Parameter,
Property,
SolidityMethod,
Type,
TypeDocTypes,
} from '@0xproject/types';
import { AbiTypes, DoxityAbiDoc, DoxityContractObj, DoxityDocObj, DoxityInput } from '../types';
export const doxityUtils = {
convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
const docAgnosticFormat: DocAgnosticFormat = {};
_.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
return abiDoc.type === AbiTypes.Constructor;
});
const constructors = [];
if (!_.isUndefined(doxityConstructor)) {
const constructor = {
isConstructor: true,
name: doxityContractObj.name,
comment: doxityConstructor.details,
returnComment: doxityConstructor.return,
callPath: '',
parameters: doxityUtils._convertParameters(doxityConstructor.inputs),
returnType: doxityUtils._convertType(doxityContractObj.name),
};
constructors.push(constructor);
}
const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
doxityContractObj.abiDocs,
(abiDoc: DoxityAbiDoc) => {
return doxityUtils._isMethod(abiDoc);
},
);
const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
doxityMethods,
(doxityMethod: DoxityAbiDoc) => {
const outputs = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs : [];
let returnTypeIfExists: Type;
if (outputs.length === 0) {
// no-op. It's already undefined
} else if (outputs.length === 1) {
const outputsType = outputs[0].type;
returnTypeIfExists = doxityUtils._convertType(outputsType);
} else {
const outputsType = `[${_.map(outputs, output => output.type).join(', ')}]`;
returnTypeIfExists = doxityUtils._convertType(outputsType);
}
// For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
const callPath =
contractName !== 'ZRXToken'
? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
: `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
const method = {
isConstructor: false,
isConstant: doxityMethod.constant,
isPayable: doxityMethod.payable,
name: doxityMethod.name,
comment: doxityMethod.details,
returnComment: doxityMethod.return,
callPath,
parameters: doxityUtils._convertParameters(doxityMethod.inputs),
returnType: returnTypeIfExists,
};
return method;
},
);
const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
doxityContractObj.abiDocs,
(abiDoc: DoxityAbiDoc) => {
return doxityUtils._isProperty(abiDoc);
},
);
const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
// We assume that none of our functions return more then a single return value
let typeName = doxityProperty.outputs[0].type;
if (!_.isEmpty(doxityProperty.inputs)) {
// Properties never have more then a single input
typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
}
const property = {
name: doxityProperty.name,
type: doxityUtils._convertType(typeName),
comment: doxityProperty.details,
};
return property;
});
const doxityEvents = _.filter(
doxityContractObj.abiDocs,
(abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
);
const events = _.map(doxityEvents, doxityEvent => {
const event = {
name: doxityEvent.name,
eventArgs: doxityUtils._convertEventArgs(doxityEvent.inputs),
};
return event;
});
const docSection: DocSection = {
comment: doxityContractObj.title,
constructors,
methods,
properties,
types: [],
functions: [],
events,
};
docAgnosticFormat[contractName] = docSection;
});
return docAgnosticFormat;
},
_convertParameters(inputs: DoxityInput[]): Parameter[] {
const parameters = _.map(inputs, input => {
const parameter = {
name: input.name,
comment: input.description,
isOptional: false,
type: doxityUtils._convertType(input.type),
};
return parameter;
});
return parameters;
},
_convertType(typeName: string): Type {
const type = {
name: typeName,
typeDocType: TypeDocTypes.Intrinsic,
};
return type;
},
_isMethod(abiDoc: DoxityAbiDoc): boolean {
if (abiDoc.type !== AbiTypes.Function) {
return false;
}
const hasInputs = !_.isEmpty(abiDoc.inputs);
const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
return isMethod;
},
_isProperty(abiDoc: DoxityAbiDoc): boolean {
if (abiDoc.type !== AbiTypes.Function) {
return false;
}
const hasInputs = !_.isEmpty(abiDoc.inputs);
const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
return isProperty;
},
_convertEventArgs(inputs: DoxityInput[]): EventArg[] {
const eventArgs = _.map(inputs, input => {
const eventArg = {
isIndexed: input.indexed,
name: input.name,
type: doxityUtils._convertType(input.type),
};
return eventArg;
});
return eventArgs;
},
};