From 775d1efd4607a4097704fe3c4f7ae1156b2c1a6f Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 23 Aug 2018 14:00:34 -0400 Subject: add package sol-doc --- packages/sol-doc/package.json | 35 +++++++ packages/sol-doc/src/index.ts | 2 + packages/sol-doc/src/solidity_doc_format.ts | 5 + packages/sol-doc/src/solidity_doc_generator.ts | 60 +++++++++++ .../test/fixtures/contracts/TokenTransferProxy.sol | 115 +++++++++++++++++++++ .../sol-doc/test/solidity_doc_generator_test.ts | 22 ++++ packages/sol-doc/test/util/chai_setup.ts | 13 +++ packages/sol-doc/tsconfig.json | 7 ++ packages/sol-doc/tslint.json | 3 + 9 files changed, 262 insertions(+) create mode 100644 packages/sol-doc/package.json create mode 100644 packages/sol-doc/src/index.ts create mode 100644 packages/sol-doc/src/solidity_doc_format.ts create mode 100644 packages/sol-doc/src/solidity_doc_generator.ts create mode 100644 packages/sol-doc/test/fixtures/contracts/TokenTransferProxy.sol create mode 100644 packages/sol-doc/test/solidity_doc_generator_test.ts create mode 100644 packages/sol-doc/test/util/chai_setup.ts create mode 100644 packages/sol-doc/tsconfig.json create mode 100644 packages/sol-doc/tslint.json (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json new file mode 100644 index 000000000..91b69b968 --- /dev/null +++ b/packages/sol-doc/package.json @@ -0,0 +1,35 @@ +{ + "name": "@0xproject/sol-doc", + "version": "1.0.0", + "description": "Solidity documentation generator", + "main": "lib/src/index.js", + "types": "lib/src/index.d.js", + "scripts": { + "build": "tsc", + "test": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --timeout 5000 --exit", + "lint": "tslint --project . --format stylish", + "clean": "shx rm -rf lib" + }, + "repository": "https://github.com/0xProject/0x-monorepo.git", + "author": "F. Eugene Aumson", + "license": "Apache-2.0", + "private": false, + "dependencies": { + "@0xproject/react-docs": "^1.0.5", + "@0xproject/sol-compiler": "^1.0.5", + "@0xproject/utils": "^1.0.5", + "ethereum-types": "^1.0.4", + "lodash": "^4.17.10" + }, + "devDependencies": { + "chai": "^4.1.2", + "chai-as-promised": "^7.1.0", + "chai-bignumber": "^2.0.2", + "dirty-chai": "^2.0.1", + "make-promises-safe": "^1.1.0", + "mocha": "^5.2.0", + "shx": "^0.2.2", + "source-map-support": "^0.5.0", + "tslint": "5.11.0" + } +} diff --git a/packages/sol-doc/src/index.ts b/packages/sol-doc/src/index.ts new file mode 100644 index 000000000..f8f55c569 --- /dev/null +++ b/packages/sol-doc/src/index.ts @@ -0,0 +1,2 @@ +export { SolidityDocGenerator } from './solidity_doc_generator'; +export { SolidityDocFormat } from './solidity_doc_format'; diff --git a/packages/sol-doc/src/solidity_doc_format.ts b/packages/sol-doc/src/solidity_doc_format.ts new file mode 100644 index 000000000..edfd5c5b7 --- /dev/null +++ b/packages/sol-doc/src/solidity_doc_format.ts @@ -0,0 +1,5 @@ +import { DocAgnosticFormat, DocSection } from '@0xproject/react-docs'; + +export class SolidityDocFormat implements DocAgnosticFormat { + [sectionName: string]: DocSection; +} diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts new file mode 100644 index 000000000..c57a4779c --- /dev/null +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -0,0 +1,60 @@ +import * as _ from 'lodash'; + +import { MethodAbi } from 'ethereum-types'; + +import { Compiler, CompilerOptions } from '@0xproject/sol-compiler'; +import { logUtils } from '@0xproject/utils'; + +import { SolidityDocFormat } from './solidity_doc_format'; + +export class SolidityDocGenerator { + private readonly _compilerOptions: CompilerOptions; + constructor(contractsDir: string, artifactsDir: string) { + // instantiate sol-compiler, passing in options to say we want abi and devdoc + this._compilerOptions = { + contractsDir, + artifactsDir, + contracts: '*', + compilerSettings: { + outputSelection: { + ['*']: { + ['*']: ['abi', 'devdoc'], + }, + }, + }, + }; + } + /// run `contractsToCompile` through compiler, gathering output + public async generateAsync(contractsToCompile: string[]): Promise { + if (!_.isUndefined(contractsToCompile)) { + this._compilerOptions.contracts = contractsToCompile; + } + + const compiler = new Compiler(this._compilerOptions); + + const doc = new SolidityDocFormat(); + + const compilerOutputs = await compiler.getCompilerOutputsAsync(); + for (const compilerOutput of compilerOutputs) { + const solidityModules = _.keys(compilerOutput.contracts); + for (const solidityModule of solidityModules) { + const compiledSolidityModule = compilerOutput.contracts[solidityModule]; + + const contracts = _.keys(compiledSolidityModule); + for (const contract of contracts) { + const compiledContract = compiledSolidityModule[contract]; + + // TODO: modify typescript-typings/types/solc/index.d.ts... it doesn't currently support devdoc! + // tslint:disable-next-line:no-unnecessary-type-assertion tsc says abi[0] has no property `name` and won't compile without the `as`, but tslint says the `as` is unnecssary. + logUtils.log( + `TODO: extract data from ${contract}'s abi (eg ${ + (compiledContract.abi[0] as MethodAbi).name + }, etc) and devdoc outputs, and insert it into \`doc\``, + ); + } + } + } + + return doc; + } +} diff --git a/packages/sol-doc/test/fixtures/contracts/TokenTransferProxy.sol b/packages/sol-doc/test/fixtures/contracts/TokenTransferProxy.sol new file mode 100644 index 000000000..44570d459 --- /dev/null +++ b/packages/sol-doc/test/fixtures/contracts/TokenTransferProxy.sol @@ -0,0 +1,115 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity ^0.4.14; + +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import { ERC20 as Token } from "zeppelin-solidity/contracts/token/ERC20/ERC20.sol"; + +/// @title TokenTransferProxy - Transfers tokens on behalf of contracts that have been approved via decentralized governance. +/// @author Amir Bandeali - , Will Warren - +contract TokenTransferProxy is Ownable { + + /// @dev Only authorized addresses can invoke functions with this modifier. + modifier onlyAuthorized { + require(authorized[msg.sender]); + _; + } + + modifier targetAuthorized(address target) { + require(authorized[target]); + _; + } + + modifier targetNotAuthorized(address target) { + require(!authorized[target]); + _; + } + + mapping (address => bool) public authorized; + address[] public authorities; + + event LogAuthorizedAddressAdded(address indexed target, address indexed caller); + event LogAuthorizedAddressRemoved(address indexed target, address indexed caller); + + /* + * Public functions + */ + + /// @dev Authorizes an address. + /// @param target Address to authorize. + function addAuthorizedAddress(address target) + public + onlyOwner + targetNotAuthorized(target) + { + authorized[target] = true; + authorities.push(target); + LogAuthorizedAddressAdded(target, msg.sender); + } + + /// @dev Removes authorizion of an address. + /// @param target Address to remove authorization from. + function removeAuthorizedAddress(address target) + public + onlyOwner + targetAuthorized(target) + { + delete authorized[target]; + for (uint i = 0; i < authorities.length; i++) { + if (authorities[i] == target) { + authorities[i] = authorities[authorities.length - 1]; + authorities.length -= 1; + break; + } + } + LogAuthorizedAddressRemoved(target, msg.sender); + } + + /// @dev Calls into ERC20 Token contract, invoking transferFrom. + /// @param token Address of token to transfer. + /// @param from Address to transfer token from. + /// @param to Address to transfer token to. + /// @param value Amount of token to transfer. + /// @return Success of transfer. + function transferFrom( + address token, + address from, + address to, + uint value) + public + onlyAuthorized + returns (bool) + { + return Token(token).transferFrom(from, to, value); + } + + /* + * Public constant functions + */ + + /// @dev Gets all authorized addresses. + /// @return Array of authorized addresses. + function getAuthorizedAddresses() + public + constant + returns (address[]) + { + return authorities; + } +} diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts new file mode 100644 index 000000000..697974c6e --- /dev/null +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -0,0 +1,22 @@ +import * as chai from 'chai'; +import 'mocha'; + +import { SolidityDocGenerator } from '../src/solidity_doc_generator'; + +import { chaiSetup } from './util/chai_setup'; + +chaiSetup.configure(); +const expect = chai.expect; + +describe('#SolidityDocGenerator', () => { + it('should generate', async () => { + const generator = new SolidityDocGenerator( + `${__dirname}/../../test/fixtures/contracts`, + `${__dirname}/../../test/fixtures/artifacts`, + ); + + const doc = await generator.generateAsync(['TokenTransferProxy']); + + expect(doc).to.not.be.undefined(); + }); +}); diff --git a/packages/sol-doc/test/util/chai_setup.ts b/packages/sol-doc/test/util/chai_setup.ts new file mode 100644 index 000000000..1a8733093 --- /dev/null +++ b/packages/sol-doc/test/util/chai_setup.ts @@ -0,0 +1,13 @@ +import * as chai from 'chai'; +import chaiAsPromised = require('chai-as-promised'); +import ChaiBigNumber = require('chai-bignumber'); +import * as dirtyChai from 'dirty-chai'; + +export const chaiSetup = { + configure(): void { + chai.config.includeStack = true; + chai.use(ChaiBigNumber()); + chai.use(dirtyChai); + chai.use(chaiAsPromised); + }, +}; diff --git a/packages/sol-doc/tsconfig.json b/packages/sol-doc/tsconfig.json new file mode 100644 index 000000000..e35816553 --- /dev/null +++ b/packages/sol-doc/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["./src/**/*", "./test/**/*"] +} diff --git a/packages/sol-doc/tslint.json b/packages/sol-doc/tslint.json new file mode 100644 index 000000000..ffaefe83a --- /dev/null +++ b/packages/sol-doc/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["@0xproject/tslint-config"] +} -- cgit From a1959df911741d0424a952fa4a63c5dcc1135524 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 24 Aug 2018 09:18:33 -0400 Subject: add devdoc support to solc typings, and use it --- packages/sol-doc/src/solidity_doc_generator.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index c57a4779c..fa3c40dcc 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -43,13 +43,19 @@ export class SolidityDocGenerator { const contracts = _.keys(compiledSolidityModule); for (const contract of contracts) { const compiledContract = compiledSolidityModule[contract]; + if (_.isUndefined(compiledContract.abi)) { + throw new Error('compiled contract did not contain ABI output.'); + } + if (_.isUndefined(compiledContract.devdoc)) { + throw new Error('compiled contract did not contain devdoc output.'); + } - // TODO: modify typescript-typings/types/solc/index.d.ts... it doesn't currently support devdoc! - // tslint:disable-next-line:no-unnecessary-type-assertion tsc says abi[0] has no property `name` and won't compile without the `as`, but tslint says the `as` is unnecssary. logUtils.log( - `TODO: extract data from ${contract}'s abi (eg ${ + `TODO: extract data from ${contract}'s abi (eg name, which is "${ (compiledContract.abi[0] as MethodAbi).name - }, etc) and devdoc outputs, and insert it into \`doc\``, + }", etc) and devdoc (eg title, which is "${ + compiledContract.devdoc.title + }") outputs, and insert it into \`doc\``, ); } } -- cgit From f429032eef007bafaed108171631f4b3d3233f6b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 08:22:44 -0400 Subject: move shared doc types from react-docs to @0x/types --- packages/sol-doc/package.json | 2 +- packages/sol-doc/src/solidity_doc_format.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index 91b69b968..c1ff0c2f5 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -15,8 +15,8 @@ "license": "Apache-2.0", "private": false, "dependencies": { - "@0xproject/react-docs": "^1.0.5", "@0xproject/sol-compiler": "^1.0.5", + "@0xproject/types": "^1.0.1-rc.6", "@0xproject/utils": "^1.0.5", "ethereum-types": "^1.0.4", "lodash": "^4.17.10" diff --git a/packages/sol-doc/src/solidity_doc_format.ts b/packages/sol-doc/src/solidity_doc_format.ts index edfd5c5b7..e980f59f6 100644 --- a/packages/sol-doc/src/solidity_doc_format.ts +++ b/packages/sol-doc/src/solidity_doc_format.ts @@ -1,4 +1,4 @@ -import { DocAgnosticFormat, DocSection } from '@0xproject/react-docs'; +import { DocAgnosticFormat, DocSection } from '@0xproject/types'; export class SolidityDocFormat implements DocAgnosticFormat { [sectionName: string]: DocSection; -- cgit From 7ed31d2fba79e314eea8c190809781be24a699c7 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 10:04:08 -0400 Subject: correct package.json's privacy specification --- packages/sol-doc/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index c1ff0c2f5..62cf0a9e1 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -13,7 +13,6 @@ "repository": "https://github.com/0xProject/0x-monorepo.git", "author": "F. Eugene Aumson", "license": "Apache-2.0", - "private": false, "dependencies": { "@0xproject/sol-compiler": "^1.0.5", "@0xproject/types": "^1.0.1-rc.6", @@ -31,5 +30,8 @@ "shx": "^0.2.2", "source-map-support": "^0.5.0", "tslint": "5.11.0" + }, + "publishConfig": { + "access": "public" } } -- cgit From 863966787f65fe61057ac45f34827ba70fee844a Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 10:06:40 -0400 Subject: dev-depend on @0xproject/tslint-config --- packages/sol-doc/package.json | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index 62cf0a9e1..9979fff05 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -21,6 +21,7 @@ "lodash": "^4.17.10" }, "devDependencies": { + "@0xproject/tslint-config": "^1.0.6", "chai": "^4.1.2", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.2", -- cgit From f76c88c5491a9ec3a6b902b291dcfaf8ac64ecd5 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 11:24:41 -0400 Subject: remove unused constructor parameter --- packages/sol-doc/src/solidity_doc_generator.ts | 3 +-- packages/sol-doc/test/solidity_doc_generator_test.ts | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index fa3c40dcc..a4eb403a8 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -9,11 +9,10 @@ import { SolidityDocFormat } from './solidity_doc_format'; export class SolidityDocGenerator { private readonly _compilerOptions: CompilerOptions; - constructor(contractsDir: string, artifactsDir: string) { + constructor(contractsDir: string) { // instantiate sol-compiler, passing in options to say we want abi and devdoc this._compilerOptions = { contractsDir, - artifactsDir, contracts: '*', compilerSettings: { outputSelection: { diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 697974c6e..1df3e5b44 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -10,10 +10,7 @@ const expect = chai.expect; describe('#SolidityDocGenerator', () => { it('should generate', async () => { - const generator = new SolidityDocGenerator( - `${__dirname}/../../test/fixtures/contracts`, - `${__dirname}/../../test/fixtures/artifacts`, - ); + const generator = new SolidityDocGenerator(`${__dirname}/../../test/fixtures/contracts`); const doc = await generator.generateAsync(['TokenTransferProxy']); -- cgit From f55234b4a04a3a26e6eda05a5c77a6bd984571ba Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 11:30:43 -0400 Subject: comment public interface --- packages/sol-doc/src/solidity_doc_generator.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index a4eb403a8..f6bbf52ba 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -7,8 +7,16 @@ import { logUtils } from '@0xproject/utils'; import { SolidityDocFormat } from './solidity_doc_format'; +/** + * Compiles solidity files to both their ABI and devdoc outputs, and transforms + * those outputs into the types that feed into documentation generation tools. + */ export class SolidityDocGenerator { private readonly _compilerOptions: CompilerOptions; + /** + * Instantiate the generator. + * @param contractsDir the directory in which to find the contracts to be compiled + */ constructor(contractsDir: string) { // instantiate sol-compiler, passing in options to say we want abi and devdoc this._compilerOptions = { @@ -23,7 +31,11 @@ export class SolidityDocGenerator { }, }; } - /// run `contractsToCompile` through compiler, gathering output + /** + * Invoke the compiler and transform its outputs. + * @param contractsToCompile list of contracts for which to generate doc objects + * @return doc objects for use with documentation generation tools. + */ public async generateAsync(contractsToCompile: string[]): Promise { if (!_.isUndefined(contractsToCompile)) { this._compilerOptions.contracts = contractsToCompile; -- cgit From 297cbd996d7da0cb3232f47734290d0377693faf Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 11:49:54 -0400 Subject: remove unnecessary class SolidityDocFormat --- packages/sol-doc/src/index.ts | 1 - packages/sol-doc/src/solidity_doc_format.ts | 5 ----- packages/sol-doc/src/solidity_doc_generator.ts | 7 +++---- 3 files changed, 3 insertions(+), 10 deletions(-) delete mode 100644 packages/sol-doc/src/solidity_doc_format.ts (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/index.ts b/packages/sol-doc/src/index.ts index f8f55c569..dc88fae90 100644 --- a/packages/sol-doc/src/index.ts +++ b/packages/sol-doc/src/index.ts @@ -1,2 +1 @@ export { SolidityDocGenerator } from './solidity_doc_generator'; -export { SolidityDocFormat } from './solidity_doc_format'; diff --git a/packages/sol-doc/src/solidity_doc_format.ts b/packages/sol-doc/src/solidity_doc_format.ts deleted file mode 100644 index e980f59f6..000000000 --- a/packages/sol-doc/src/solidity_doc_format.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { DocAgnosticFormat, DocSection } from '@0xproject/types'; - -export class SolidityDocFormat implements DocAgnosticFormat { - [sectionName: string]: DocSection; -} diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index f6bbf52ba..aba7b5475 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -3,10 +3,9 @@ import * as _ from 'lodash'; import { MethodAbi } from 'ethereum-types'; import { Compiler, CompilerOptions } from '@0xproject/sol-compiler'; +import { DocAgnosticFormat } from '@0xproject/types'; import { logUtils } from '@0xproject/utils'; -import { SolidityDocFormat } from './solidity_doc_format'; - /** * Compiles solidity files to both their ABI and devdoc outputs, and transforms * those outputs into the types that feed into documentation generation tools. @@ -36,14 +35,14 @@ export class SolidityDocGenerator { * @param contractsToCompile list of contracts for which to generate doc objects * @return doc objects for use with documentation generation tools. */ - public async generateAsync(contractsToCompile: string[]): Promise { + public async generateAsync(contractsToCompile: string[]): Promise { if (!_.isUndefined(contractsToCompile)) { this._compilerOptions.contracts = contractsToCompile; } const compiler = new Compiler(this._compilerOptions); - const doc = new SolidityDocFormat(); + const doc: DocAgnosticFormat = {}; const compilerOutputs = await compiler.getCompilerOutputsAsync(); for (const compilerOutput of compilerOutputs) { -- cgit From b88a56e6b723016cf830511b2da503747e086f54 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 11:51:17 -0400 Subject: reduce proximity b/w instantiation and use of var --- packages/sol-doc/src/solidity_doc_generator.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index aba7b5475..856787e5f 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -40,10 +40,9 @@ export class SolidityDocGenerator { this._compilerOptions.contracts = contractsToCompile; } - const compiler = new Compiler(this._compilerOptions); - const doc: DocAgnosticFormat = {}; + const compiler = new Compiler(this._compilerOptions); const compilerOutputs = await compiler.getCompilerOutputsAsync(); for (const compilerOutput of compilerOutputs) { const solidityModules = _.keys(compilerOutput.contracts); -- cgit From fe7a62ba9a0d1647ea94683a0369b98e2a675f94 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 11:52:21 -0400 Subject: add named var to make `if` condition more readable --- packages/sol-doc/src/solidity_doc_generator.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 856787e5f..bb2f4cea6 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -36,7 +36,8 @@ export class SolidityDocGenerator { * @return doc objects for use with documentation generation tools. */ public async generateAsync(contractsToCompile: string[]): Promise { - if (!_.isUndefined(contractsToCompile)) { + const shouldOverrideCatchAllContractsConfig = !_.isUndefined(contractsToCompile); + if (shouldOverrideCatchAllContractsConfig) { this._compilerOptions.contracts = contractsToCompile; } -- cgit From 0e45497acbb0ad572e549ad81bb72b3b31d7860d Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 30 Aug 2018 12:02:02 -0400 Subject: rename variables --- packages/sol-doc/src/solidity_doc_generator.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index bb2f4cea6..95c89b2e5 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -46,13 +46,13 @@ export class SolidityDocGenerator { const compiler = new Compiler(this._compilerOptions); const compilerOutputs = await compiler.getCompilerOutputsAsync(); for (const compilerOutput of compilerOutputs) { - const solidityModules = _.keys(compilerOutput.contracts); - for (const solidityModule of solidityModules) { - const compiledSolidityModule = compilerOutput.contracts[solidityModule]; + const contractFileNames = _.keys(compilerOutput.contracts); + for (const contractFileName of contractFileNames) { + const contractNameToOutput = compilerOutput.contracts[contractFileName]; - const contracts = _.keys(compiledSolidityModule); - for (const contract of contracts) { - const compiledContract = compiledSolidityModule[contract]; + const contractNames = _.keys(contractNameToOutput); + for (const contractName of contractNames) { + const compiledContract = contractNameToOutput[contractName]; if (_.isUndefined(compiledContract.abi)) { throw new Error('compiled contract did not contain ABI output.'); } @@ -61,7 +61,7 @@ export class SolidityDocGenerator { } logUtils.log( - `TODO: extract data from ${contract}'s abi (eg name, which is "${ + `TODO: extract data from ${contractName}'s abi (eg name, which is "${ (compiledContract.abi[0] as MethodAbi).name }", etc) and devdoc (eg title, which is "${ compiledContract.devdoc.title -- cgit From 823b6c4d7df56e6bc517b72878fb1ff5823a5b6f Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 29 Aug 2018 11:01:04 -0400 Subject: transform solc's ABI output into doc types --- packages/sol-doc/src/index.ts | 2 +- packages/sol-doc/src/solidity_doc_generator.ts | 296 ++++++++++++++++----- .../sol-doc/test/solidity_doc_generator_test.ts | 52 +++- 3 files changed, 284 insertions(+), 66 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/index.ts b/packages/sol-doc/src/index.ts index dc88fae90..03f3c9de6 100644 --- a/packages/sol-doc/src/index.ts +++ b/packages/sol-doc/src/index.ts @@ -1 +1 @@ -export { SolidityDocGenerator } from './solidity_doc_generator'; +export { generateSolDocAsync } from './solidity_doc_generator'; diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 95c89b2e5..312124ca1 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -1,76 +1,252 @@ import * as _ from 'lodash'; -import { MethodAbi } from 'ethereum-types'; +import { + AbiDefinition, + ConstructorAbi, + DataItem, + DevdocOutput, + EventAbi, + FallbackAbi, + MethodAbi, + StandardContractOutput, +} from 'ethereum-types'; import { Compiler, CompilerOptions } from '@0xproject/sol-compiler'; -import { DocAgnosticFormat } from '@0xproject/types'; +import { + DocAgnosticFormat, + DocSection, + Event, + EventArg, + Parameter, + SolidityMethod, + Type, + TypeDocTypes, +} from '@0xproject/types'; import { logUtils } from '@0xproject/utils'; /** - * Compiles solidity files to both their ABI and devdoc outputs, and transforms - * those outputs into the types that feed into documentation generation tools. + * Invoke the Solidity compiler and transform its ABI and devdoc outputs into + * the types that are used as input to documentation generation tools. + * @param contractsToCompile list of contracts for which to generate doc objects + * @param contractsDir the directory in which to find the `contractsToCompile` as well as their dependencies. + * @return doc object for use with documentation generation tools. */ -export class SolidityDocGenerator { - private readonly _compilerOptions: CompilerOptions; - /** - * Instantiate the generator. - * @param contractsDir the directory in which to find the contracts to be compiled - */ - constructor(contractsDir: string) { - // instantiate sol-compiler, passing in options to say we want abi and devdoc - this._compilerOptions = { - contractsDir, - contracts: '*', - compilerSettings: { - outputSelection: { - ['*']: { - ['*']: ['abi', 'devdoc'], - }, +export async function generateSolDocAsync( + contractsToCompile: string[], + contractsDir: string, +): Promise { + const doc: DocAgnosticFormat = {}; + + const compilerOptions = _makeCompilerOptions(contractsToCompile, contractsDir); + const compiler = new Compiler(compilerOptions); + const compilerOutputs = await compiler.getCompilerOutputsAsync(); + for (const compilerOutput of compilerOutputs) { + const contractFileNames = _.keys(compilerOutput.contracts); + for (const contractFileName of contractFileNames) { + const contractNameToOutput = compilerOutput.contracts[contractFileName]; + + const contractNames = _.keys(contractNameToOutput); + for (const contractName of contractNames) { + const compiledContract = contractNameToOutput[contractName]; + if (_.isUndefined(compiledContract.abi)) { + throw new Error('compiled contract did not contain ABI output'); + } + doc[contractName] = _genDocSection(compiledContract); + } + } + } + + return doc; +} + +function _makeCompilerOptions(contractsToCompile: string[], contractsDir: string): CompilerOptions { + const compilerOptions: CompilerOptions = { + contractsDir, + contracts: '*', + compilerSettings: { + outputSelection: { + ['*']: { + ['*']: ['abi', 'devdoc'], }, }, - }; + }, + }; + + const shouldOverrideCatchAllContractsConfig = !_.isUndefined(contractsToCompile); + if (shouldOverrideCatchAllContractsConfig) { + compilerOptions.contracts = contractsToCompile; } - /** - * Invoke the compiler and transform its outputs. - * @param contractsToCompile list of contracts for which to generate doc objects - * @return doc objects for use with documentation generation tools. - */ - public async generateAsync(contractsToCompile: string[]): Promise { - const shouldOverrideCatchAllContractsConfig = !_.isUndefined(contractsToCompile); - if (shouldOverrideCatchAllContractsConfig) { - this._compilerOptions.contracts = contractsToCompile; - } - const doc: DocAgnosticFormat = {}; - - const compiler = new Compiler(this._compilerOptions); - const compilerOutputs = await compiler.getCompilerOutputsAsync(); - for (const compilerOutput of compilerOutputs) { - const contractFileNames = _.keys(compilerOutput.contracts); - for (const contractFileName of contractFileNames) { - const contractNameToOutput = compilerOutput.contracts[contractFileName]; - - const contractNames = _.keys(contractNameToOutput); - for (const contractName of contractNames) { - const compiledContract = contractNameToOutput[contractName]; - if (_.isUndefined(compiledContract.abi)) { - throw new Error('compiled contract did not contain ABI output.'); - } - if (_.isUndefined(compiledContract.devdoc)) { - throw new Error('compiled contract did not contain devdoc output.'); - } - - logUtils.log( - `TODO: extract data from ${contractName}'s abi (eg name, which is "${ - (compiledContract.abi[0] as MethodAbi).name - }", etc) and devdoc (eg title, which is "${ - compiledContract.devdoc.title - }") outputs, and insert it into \`doc\``, - ); - } - } + return compilerOptions; +} + +function _genDocSection(compiledContract: StandardContractOutput): DocSection { + const docSection: DocSection = { + comment: _.isUndefined(compiledContract.devdoc) ? '' : compiledContract.devdoc.title, + constructors: [], + methods: [], + properties: [], + types: [], + functions: [], + events: [], + }; + + for (const abiDefinition of compiledContract.abi) { + switch (abiDefinition.type) { + case 'constructor': + docSection.constructors.push(_genConstructorDoc(abiDefinition, compiledContract.devdoc)); + break; + case 'event': + (docSection.events as Event[]).push(_genEventDoc(abiDefinition)); + // note that we're not sending devdoc to _genEventDoc(). + // that's because the type of the events array doesn't have any fields for documentation! + break; + case 'function': + docSection.methods.push(_genMethodDoc(abiDefinition, compiledContract.devdoc)); + break; + default: + throw new Error(`unknown and unsupported AbiDefinition type '${abiDefinition.type}'`); } + } + + return docSection; +} + +function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: DevdocOutput | undefined): SolidityMethod { + const { parameters, methodSignature } = _genMethodParamsDoc( + '', // TODO: update depending on how constructors are keyed in devdoc + abiDefinition.inputs, + devdocIfExists, + ); + + let comment; + // TODO: use methodSignature as the key to abiEntry.devdoc.methods, and + // from that object extract the "details" (comment) property + comment = 'something from devdoc'; + + return { + isConstructor: true, + name: '', // sad we have to specify this + callPath: '', // TODO: wtf is this? + parameters, + returnType: { name: '', typeDocType: TypeDocTypes.Intrinsic }, // sad we have to specify this + isConstant: false, // constructors are non-const by their nature, right? + isPayable: abiDefinition.payable, + comment, + }; +} + +function _genMethodDoc( + abiDefinition: MethodAbi | FallbackAbi, + devdocIfExists: DevdocOutput | undefined, +): SolidityMethod { + const name = abiDefinition.type === 'fallback' ? '' : abiDefinition.name; - return doc; + const { parameters, methodSignature } = + abiDefinition.type === 'fallback' + ? { parameters: [], methodSignature: `${name}()` } + : _genMethodParamsDoc(name, abiDefinition.inputs, devdocIfExists); + + let comment; + // TODO: use methodSignature as the key to abiEntry.devdoc.methods, and + // from that object extract the "details" (comment) property + comment = 'something from devdoc'; + + const returnType = + abiDefinition.type === 'fallback' + ? { name: '', typeDocType: TypeDocTypes.Intrinsic } + : _genMethodReturnTypeDoc(abiDefinition.outputs, methodSignature, devdocIfExists); + + const isConstant = abiDefinition.type === 'fallback' ? true : abiDefinition.constant; + // TODO: determine whether fallback functions are always constant, as coded just above + + return { + isConstructor: false, + name, + callPath: '', // TODO: wtf is this? + parameters, + returnType, + isConstant, + isPayable: abiDefinition.payable, + comment, + }; +} + +function _genEventDoc(abiDefinition: EventAbi): Event { + const eventDoc: Event = { + name: abiDefinition.name, + eventArgs: _genEventArgsDoc(abiDefinition.inputs, undefined), + }; + return eventDoc; +} + +function _genEventArgsDoc(args: DataItem[], devdocIfExists: DevdocOutput | undefined): EventArg[] { + const eventArgsDoc: EventArg[] = []; + + for (const arg of args) { + const name = arg.name; + + const type: Type = { + name: arg.type, + typeDocType: TypeDocTypes.Intrinsic, + }; + + const eventArgDoc: EventArg = { + isIndexed: false, // TODO: wtf is this? + name, + type, + }; + + eventArgsDoc.push(eventArgDoc); + } + return eventArgsDoc; +} + +/** + * Extract documentation for each method paramater from @param params. + * TODO: Then, use @param name, along with the types of the method + * parameters, to form a method signature. That signature is the key to + * the method documentation held in @param devdocIfExists. + */ +function _genMethodParamsDoc( + name: string, + params: DataItem[], + devdocIfExists: DevdocOutput | undefined, +): { parameters: Parameter[]; methodSignature: string } { + const parameters: Parameter[] = []; + for (const input of params) { + const parameter: Parameter = { + name: input.name, + comment: '', // TODO: get from devdoc. see comment below. + isOptional: false, // Unsupported in Solidity, until resolution of https://github.com/ethereum/solidity/issues/232 + type: { name: input.type, typeDocType: TypeDocTypes.Intrinsic }, + }; + parameters.push(parameter); + } + // TODO: use methodSignature as the key to abiEntry.devdoc.methods, and + // from that object extract the "details" (comment) property + return { parameters, methodSignature: '' }; +} + +function _genMethodReturnTypeDoc( + outputs: DataItem[], + methodSignature: string, + devdocIfExists: DevdocOutput | undefined, +): Type { + const methodReturnTypeDoc: Type = { + name: '', + typeDocType: TypeDocTypes.Intrinsic, + tupleElements: undefined, + }; + if (outputs.length > 1) { + methodReturnTypeDoc.typeDocType = TypeDocTypes.Tuple; + methodReturnTypeDoc.tupleElements = []; + for (const output of outputs) { + methodReturnTypeDoc.tupleElements.push({ name: output.name, typeDocType: TypeDocTypes.Intrinsic }); + } + } else if (outputs.length === 1) { + methodReturnTypeDoc.typeDocType = TypeDocTypes.Intrinsic; + methodReturnTypeDoc.name = outputs[0].name; } + return methodReturnTypeDoc; } diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 1df3e5b44..df6ad8e54 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -1,7 +1,11 @@ +import * as _ from 'lodash'; + import * as chai from 'chai'; import 'mocha'; -import { SolidityDocGenerator } from '../src/solidity_doc_generator'; +import { DocSection } from '@0xproject/types'; + +import { generateSolDocAsync } from '../src/solidity_doc_generator'; import { chaiSetup } from './util/chai_setup'; @@ -9,11 +13,49 @@ chaiSetup.configure(); const expect = chai.expect; describe('#SolidityDocGenerator', () => { - it('should generate', async () => { - const generator = new SolidityDocGenerator(`${__dirname}/../../test/fixtures/contracts`); - - const doc = await generator.generateAsync(['TokenTransferProxy']); + it('should generate a doc object that matches the TokenTransferProxy fixture', async () => { + const doc = await generateSolDocAsync(['TokenTransferProxy'], `${__dirname}/../../test/fixtures/contracts`); expect(doc).to.not.be.undefined(); + + const tokenTransferProxyConstructorCount = 0; + const tokenTransferProxyMethodCount = 8; + const tokenTransferProxyEventCount = 3; + expect(doc.TokenTransferProxy.constructors.length).to.equal(tokenTransferProxyConstructorCount); + expect(doc.TokenTransferProxy.methods.length).to.equal(tokenTransferProxyMethodCount); + if (_.isUndefined(doc.TokenTransferProxy.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.TokenTransferProxy.events.length).to.equal(tokenTransferProxyEventCount); + + const ownableConstructorCount = 1; + const ownableMethodCount = 2; + const ownableEventCount = 1; + expect(doc.Ownable.constructors.length).to.equal(ownableConstructorCount); + expect(doc.Ownable.methods.length).to.equal(ownableMethodCount); + if (_.isUndefined(doc.Ownable.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.Ownable.events.length).to.equal(ownableEventCount); + + const erc20ConstructorCount = 0; + const erc20MethodCount = 6; + const erc20EventCount = 2; + expect(doc.ERC20.constructors.length).to.equal(erc20ConstructorCount); + expect(doc.ERC20.methods.length).to.equal(erc20MethodCount); + if (_.isUndefined(doc.ERC20.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.ERC20.events.length).to.equal(erc20EventCount); + + const erc20BasicConstructorCount = 0; + const erc20BasicMethodCount = 3; + const erc20BasicEventCount = 1; + expect(doc.ERC20Basic.constructors.length).to.equal(erc20BasicConstructorCount); + expect(doc.ERC20Basic.methods.length).to.equal(erc20BasicMethodCount); + if (_.isUndefined(doc.ERC20Basic.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.ERC20Basic.events.length).to.equal(erc20BasicEventCount); }); }); -- cgit From 9a4e6da02f606e97b470a6545b2ce5baf14b03e6 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 29 Aug 2018 11:05:30 -0400 Subject: enable sol-doc tests in circleci --- packages/sol-doc/coverage/.gitkeep | 0 packages/sol-doc/package.json | 3 +++ 2 files changed, 3 insertions(+) create mode 100644 packages/sol-doc/coverage/.gitkeep (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/coverage/.gitkeep b/packages/sol-doc/coverage/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index 9979fff05..e3bc8753c 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -7,6 +7,9 @@ "scripts": { "build": "tsc", "test": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --timeout 5000 --exit", + "test:circleci": "yarn test:coverage", + "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", + "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", "lint": "tslint --project . --format stylish", "clean": "shx rm -rf lib" }, -- cgit From 50b725c687c3968b0a495924700296ce6ce5bbec Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 31 Aug 2018 09:33:26 -0400 Subject: introduce named vars to clarify return statements --- packages/sol-doc/src/solidity_doc_generator.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 312124ca1..457c86c91 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -124,7 +124,7 @@ function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: Devdo // from that object extract the "details" (comment) property comment = 'something from devdoc'; - return { + const constructorDoc: SolidityMethod = { isConstructor: true, name: '', // sad we have to specify this callPath: '', // TODO: wtf is this? @@ -134,6 +134,8 @@ function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: Devdo isPayable: abiDefinition.payable, comment, }; + + return constructorDoc; } function _genMethodDoc( @@ -160,7 +162,7 @@ function _genMethodDoc( const isConstant = abiDefinition.type === 'fallback' ? true : abiDefinition.constant; // TODO: determine whether fallback functions are always constant, as coded just above - return { + const methodDoc: SolidityMethod = { isConstructor: false, name, callPath: '', // TODO: wtf is this? @@ -170,6 +172,7 @@ function _genMethodDoc( isPayable: abiDefinition.payable, comment, }; + return methodDoc; } function _genEventDoc(abiDefinition: EventAbi): Event { -- cgit From 327b4ba5546907f3c2b6fddd2a4d3d767d1f6767 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 31 Aug 2018 10:04:03 -0400 Subject: satisfy linter --- packages/sol-doc/src/solidity_doc_generator.ts | 4 +--- packages/sol-doc/test/solidity_doc_generator_test.ts | 2 -- packages/sol-doc/tsconfig.json | 3 ++- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 457c86c91..debee5b87 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -1,7 +1,6 @@ import * as _ from 'lodash'; import { - AbiDefinition, ConstructorAbi, DataItem, DevdocOutput, @@ -22,7 +21,6 @@ import { Type, TypeDocTypes, } from '@0xproject/types'; -import { logUtils } from '@0xproject/utils'; /** * Invoke the Solidity compiler and transform its ABI and devdoc outputs into @@ -122,7 +120,7 @@ function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: Devdo let comment; // TODO: use methodSignature as the key to abiEntry.devdoc.methods, and // from that object extract the "details" (comment) property - comment = 'something from devdoc'; + comment = `something from devdoc, using ${methodSignature} to find it`; const constructorDoc: SolidityMethod = { isConstructor: true, diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index df6ad8e54..989f29320 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -3,8 +3,6 @@ import * as _ from 'lodash'; import * as chai from 'chai'; import 'mocha'; -import { DocSection } from '@0xproject/types'; - import { generateSolDocAsync } from '../src/solidity_doc_generator'; import { chaiSetup } from './util/chai_setup'; diff --git a/packages/sol-doc/tsconfig.json b/packages/sol-doc/tsconfig.json index e35816553..2ee711adc 100644 --- a/packages/sol-doc/tsconfig.json +++ b/packages/sol-doc/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig", "compilerOptions": { - "outDir": "lib" + "outDir": "lib", + "rootDir": "." }, "include": ["./src/**/*", "./test/**/*"] } -- cgit From 3dc4eb4421d4f0b1294fcaaa4602245005f36e82 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 31 Aug 2018 15:28:12 -0400 Subject: rename 2 variables --- packages/sol-doc/src/solidity_doc_generator.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index debee5b87..240fbbd75 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -211,16 +211,16 @@ function _genEventArgsDoc(args: DataItem[], devdocIfExists: DevdocOutput | undef */ function _genMethodParamsDoc( name: string, - params: DataItem[], + abiParams: DataItem[], devdocIfExists: DevdocOutput | undefined, ): { parameters: Parameter[]; methodSignature: string } { const parameters: Parameter[] = []; - for (const input of params) { + for (const abiParam of abiParams) { const parameter: Parameter = { - name: input.name, + name: abiParam.name, comment: '', // TODO: get from devdoc. see comment below. isOptional: false, // Unsupported in Solidity, until resolution of https://github.com/ethereum/solidity/issues/232 - type: { name: input.type, typeDocType: TypeDocTypes.Intrinsic }, + type: { name: abiParam.type, typeDocType: TypeDocTypes.Intrinsic }, }; parameters.push(parameter); } -- cgit From 800dd5fb4f0ab21388440a46aef21cd0cf0801c3 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 31 Aug 2018 15:34:13 -0400 Subject: ammend generated docs with solc's devdoc output --- packages/sol-doc/src/solidity_doc_generator.ts | 61 ++++++++++++++++------ .../sol-doc/test/solidity_doc_generator_test.ts | 17 ++++++ 2 files changed, 63 insertions(+), 15 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 240fbbd75..a1ef32e79 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -117,10 +117,8 @@ function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: Devdo devdocIfExists, ); - let comment; - // TODO: use methodSignature as the key to abiEntry.devdoc.methods, and - // from that object extract the "details" (comment) property - comment = `something from devdoc, using ${methodSignature} to find it`; + const comment = _devdocMethodDetailsIfExist(methodSignature, devdocIfExists); + // TODO: figure out why devdoc'd constructors don't get output by solc const constructorDoc: SolidityMethod = { isConstructor: true, @@ -136,6 +134,26 @@ function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: Devdo return constructorDoc; } +function _devdocMethodDetailsIfExist( + methodSignature: string, + devdocIfExists: DevdocOutput | undefined, +): string | undefined { + let details; + if (!_.isUndefined(devdocIfExists)) { + const devdocMethodsIfExist = devdocIfExists.methods; + if (!_.isUndefined(devdocMethodsIfExist)) { + const devdocMethodIfExists = devdocMethodsIfExist[methodSignature]; + if (!_.isUndefined(devdocMethodIfExists)) { + const devdocMethodDetailsIfExist = devdocMethodIfExists.details; + if (!_.isUndefined(devdocMethodDetailsIfExist)) { + details = devdocMethodDetailsIfExist; + } + } + } + } + return details; +} + function _genMethodDoc( abiDefinition: MethodAbi | FallbackAbi, devdocIfExists: DevdocOutput | undefined, @@ -147,10 +165,7 @@ function _genMethodDoc( ? { parameters: [], methodSignature: `${name}()` } : _genMethodParamsDoc(name, abiDefinition.inputs, devdocIfExists); - let comment; - // TODO: use methodSignature as the key to abiEntry.devdoc.methods, and - // from that object extract the "details" (comment) property - comment = 'something from devdoc'; + const comment = _devdocMethodDetailsIfExist(methodSignature, devdocIfExists); const returnType = abiDefinition.type === 'fallback' @@ -205,9 +220,6 @@ function _genEventArgsDoc(args: DataItem[], devdocIfExists: DevdocOutput | undef /** * Extract documentation for each method paramater from @param params. - * TODO: Then, use @param name, along with the types of the method - * parameters, to form a method signature. That signature is the key to - * the method documentation held in @param devdocIfExists. */ function _genMethodParamsDoc( name: string, @@ -215,18 +227,37 @@ function _genMethodParamsDoc( devdocIfExists: DevdocOutput | undefined, ): { parameters: Parameter[]; methodSignature: string } { const parameters: Parameter[] = []; + let methodSignature = `${name}(`; + for (const abiParam of abiParams) { const parameter: Parameter = { name: abiParam.name, - comment: '', // TODO: get from devdoc. see comment below. + comment: '', isOptional: false, // Unsupported in Solidity, until resolution of https://github.com/ethereum/solidity/issues/232 type: { name: abiParam.type, typeDocType: TypeDocTypes.Intrinsic }, }; parameters.push(parameter); + methodSignature = `${methodSignature}${abiParam.type},`; } - // TODO: use methodSignature as the key to abiEntry.devdoc.methods, and - // from that object extract the "details" (comment) property - return { parameters, methodSignature: '' }; + + if (methodSignature.slice(-1) === ',') { + methodSignature = methodSignature.slice(0, -1); + } + methodSignature += ')'; + + if (!_.isUndefined(devdocIfExists)) { + const devdocMethodIfExists = devdocIfExists.methods[methodSignature]; + if (!_.isUndefined(devdocMethodIfExists)) { + const devdocParamsIfExist = devdocMethodIfExists.params; + if (!_.isUndefined(devdocParamsIfExist)) { + for (const parameter of parameters) { + parameter.comment = devdocParamsIfExist[parameter.name]; + } + } + } + } + + return { parameters, methodSignature }; } function _genMethodReturnTypeDoc( diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 989f29320..7f11fcdfd 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -3,6 +3,8 @@ import * as _ from 'lodash'; import * as chai from 'chai'; import 'mocha'; +import { SolidityMethod } from '@0xproject/types'; + import { generateSolDocAsync } from '../src/solidity_doc_generator'; import { chaiSetup } from './util/chai_setup'; @@ -55,5 +57,20 @@ describe('#SolidityDocGenerator', () => { throw new Error('events should never be undefined'); } expect(doc.ERC20Basic.events.length).to.equal(erc20BasicEventCount); + + let addAuthorizedAddressMethod: SolidityMethod | undefined; + for (const method of doc.TokenTransferProxy.methods) { + if (method.name === 'addAuthorizedAddress') { + addAuthorizedAddressMethod = method; + } + } + expect( + addAuthorizedAddressMethod, + `method addAuthorizedAddress not found in ${JSON.stringify(doc.TokenTransferProxy.methods)}`, + ).to.not.be.undefined(); + const tokenTransferProxyAddAuthorizedAddressComment = 'Authorizes an address.'; + expect((addAuthorizedAddressMethod as SolidityMethod).comment).to.equal( + tokenTransferProxyAddAuthorizedAddressComment, + ); }); }); -- cgit From d5f964b58e755ccf1e63a61a97da1c161cf22b22 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 13 Sep 2018 13:05:01 -0400 Subject: test w/&w/out passing in `contractsToCompile` --- packages/sol-doc/src/solidity_doc_generator.ts | 8 +- .../sol-doc/test/solidity_doc_generator_test.ts | 127 ++++++++++++--------- 2 files changed, 76 insertions(+), 59 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index a1ef32e79..513468803 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -30,12 +30,12 @@ import { * @return doc object for use with documentation generation tools. */ export async function generateSolDocAsync( - contractsToCompile: string[], contractsDir: string, + contractsToCompile?: string[], ): Promise { const doc: DocAgnosticFormat = {}; - const compilerOptions = _makeCompilerOptions(contractsToCompile, contractsDir); + const compilerOptions = _makeCompilerOptions(contractsDir, contractsToCompile); const compiler = new Compiler(compilerOptions); const compilerOutputs = await compiler.getCompilerOutputsAsync(); for (const compilerOutput of compilerOutputs) { @@ -57,7 +57,7 @@ export async function generateSolDocAsync( return doc; } -function _makeCompilerOptions(contractsToCompile: string[], contractsDir: string): CompilerOptions { +function _makeCompilerOptions(contractsDir: string, contractsToCompile?: string[]): CompilerOptions { const compilerOptions: CompilerOptions = { contractsDir, contracts: '*', @@ -70,7 +70,7 @@ function _makeCompilerOptions(contractsToCompile: string[], contractsDir: string }, }; - const shouldOverrideCatchAllContractsConfig = !_.isUndefined(contractsToCompile); + const shouldOverrideCatchAllContractsConfig = !_.isUndefined(contractsToCompile) && contractsToCompile.length > 0; if (shouldOverrideCatchAllContractsConfig) { compilerOptions.contracts = contractsToCompile; } diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 7f11fcdfd..b71cce6e7 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -3,7 +3,7 @@ import * as _ from 'lodash'; import * as chai from 'chai'; import 'mocha'; -import { SolidityMethod } from '@0xproject/types'; +import { DocAgnosticFormat, SolidityMethod } from '@0xproject/types'; import { generateSolDocAsync } from '../src/solidity_doc_generator'; @@ -12,65 +12,82 @@ import { chaiSetup } from './util/chai_setup'; chaiSetup.configure(); const expect = chai.expect; -describe('#SolidityDocGenerator', () => { - it('should generate a doc object that matches the TokenTransferProxy fixture', async () => { - const doc = await generateSolDocAsync(['TokenTransferProxy'], `${__dirname}/../../test/fixtures/contracts`); +describe('#SolidityDocGenerator', async () => { + const docPromises: Array> = [ + generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`), + generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, []), + generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, ['TokenTransferProxy']), + ]; + docPromises.forEach(docPromise => { + it('should generate a doc object that matches the TokenTransferProxy fixture', async () => { + const doc = await docPromise; + expect(doc).to.not.be.undefined(); - expect(doc).to.not.be.undefined(); - - const tokenTransferProxyConstructorCount = 0; - const tokenTransferProxyMethodCount = 8; - const tokenTransferProxyEventCount = 3; - expect(doc.TokenTransferProxy.constructors.length).to.equal(tokenTransferProxyConstructorCount); - expect(doc.TokenTransferProxy.methods.length).to.equal(tokenTransferProxyMethodCount); - if (_.isUndefined(doc.TokenTransferProxy.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.TokenTransferProxy.events.length).to.equal(tokenTransferProxyEventCount); + expect(doc.TokenTransferProxy).to.not.be.undefined(); + expect(doc.TokenTransferProxy.constructors).to.not.be.undefined(); + const tokenTransferProxyConstructorCount = 0; + const tokenTransferProxyMethodCount = 8; + const tokenTransferProxyEventCount = 3; + expect(doc.TokenTransferProxy.constructors.length).to.equal(tokenTransferProxyConstructorCount); + expect(doc.TokenTransferProxy.methods.length).to.equal(tokenTransferProxyMethodCount); + if (_.isUndefined(doc.TokenTransferProxy.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.TokenTransferProxy.events.length).to.equal(tokenTransferProxyEventCount); - const ownableConstructorCount = 1; - const ownableMethodCount = 2; - const ownableEventCount = 1; - expect(doc.Ownable.constructors.length).to.equal(ownableConstructorCount); - expect(doc.Ownable.methods.length).to.equal(ownableMethodCount); - if (_.isUndefined(doc.Ownable.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.Ownable.events.length).to.equal(ownableEventCount); + expect(doc.Ownable).to.not.be.undefined(); + expect(doc.Ownable.constructors).to.not.be.undefined(); + expect(doc.Ownable.methods).to.not.be.undefined(); + const ownableConstructorCount = 1; + const ownableMethodCount = 2; + const ownableEventCount = 1; + expect(doc.Ownable.constructors.length).to.equal(ownableConstructorCount); + expect(doc.Ownable.methods.length).to.equal(ownableMethodCount); + if (_.isUndefined(doc.Ownable.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.Ownable.events.length).to.equal(ownableEventCount); - const erc20ConstructorCount = 0; - const erc20MethodCount = 6; - const erc20EventCount = 2; - expect(doc.ERC20.constructors.length).to.equal(erc20ConstructorCount); - expect(doc.ERC20.methods.length).to.equal(erc20MethodCount); - if (_.isUndefined(doc.ERC20.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.ERC20.events.length).to.equal(erc20EventCount); + expect(doc.ERC20).to.not.be.undefined(); + expect(doc.ERC20.constructors).to.not.be.undefined(); + expect(doc.ERC20.methods).to.not.be.undefined(); + const erc20ConstructorCount = 0; + const erc20MethodCount = 6; + const erc20EventCount = 2; + expect(doc.ERC20.constructors.length).to.equal(erc20ConstructorCount); + expect(doc.ERC20.methods.length).to.equal(erc20MethodCount); + if (_.isUndefined(doc.ERC20.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.ERC20.events.length).to.equal(erc20EventCount); - const erc20BasicConstructorCount = 0; - const erc20BasicMethodCount = 3; - const erc20BasicEventCount = 1; - expect(doc.ERC20Basic.constructors.length).to.equal(erc20BasicConstructorCount); - expect(doc.ERC20Basic.methods.length).to.equal(erc20BasicMethodCount); - if (_.isUndefined(doc.ERC20Basic.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.ERC20Basic.events.length).to.equal(erc20BasicEventCount); + expect(doc.ERC20Basic).to.not.be.undefined(); + expect(doc.ERC20Basic.constructors).to.not.be.undefined(); + expect(doc.ERC20Basic.methods).to.not.be.undefined(); + const erc20BasicConstructorCount = 0; + const erc20BasicMethodCount = 3; + const erc20BasicEventCount = 1; + expect(doc.ERC20Basic.constructors.length).to.equal(erc20BasicConstructorCount); + expect(doc.ERC20Basic.methods.length).to.equal(erc20BasicMethodCount); + if (_.isUndefined(doc.ERC20Basic.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.ERC20Basic.events.length).to.equal(erc20BasicEventCount); - let addAuthorizedAddressMethod: SolidityMethod | undefined; - for (const method of doc.TokenTransferProxy.methods) { - if (method.name === 'addAuthorizedAddress') { - addAuthorizedAddressMethod = method; + let addAuthorizedAddressMethod: SolidityMethod | undefined; + for (const method of doc.TokenTransferProxy.methods) { + if (method.name === 'addAuthorizedAddress') { + addAuthorizedAddressMethod = method; + } } - } - expect( - addAuthorizedAddressMethod, - `method addAuthorizedAddress not found in ${JSON.stringify(doc.TokenTransferProxy.methods)}`, - ).to.not.be.undefined(); - const tokenTransferProxyAddAuthorizedAddressComment = 'Authorizes an address.'; - expect((addAuthorizedAddressMethod as SolidityMethod).comment).to.equal( - tokenTransferProxyAddAuthorizedAddressComment, - ); + expect( + addAuthorizedAddressMethod, + `method addAuthorizedAddress not found in ${JSON.stringify(doc.TokenTransferProxy.methods)}`, + ).to.not.be.undefined(); + const tokenTransferProxyAddAuthorizedAddressComment = 'Authorizes an address.'; + expect((addAuthorizedAddressMethod as SolidityMethod).comment).to.equal( + tokenTransferProxyAddAuthorizedAddressComment, + ); + }); }); }); -- cgit From a75981da148c8a300544a559bc01be1770d443cf Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 13 Sep 2018 13:56:10 -0400 Subject: test w/&w/out devdoc content in contract --- .../contracts/TokenTransferProxyNoDevdoc.sol | 100 ++++++++++++++++ .../sol-doc/test/solidity_doc_generator_test.ts | 132 ++++++++++++--------- 2 files changed, 176 insertions(+), 56 deletions(-) create mode 100644 packages/sol-doc/test/fixtures/contracts/TokenTransferProxyNoDevdoc.sol (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/test/fixtures/contracts/TokenTransferProxyNoDevdoc.sol b/packages/sol-doc/test/fixtures/contracts/TokenTransferProxyNoDevdoc.sol new file mode 100644 index 000000000..cc45a79e9 --- /dev/null +++ b/packages/sol-doc/test/fixtures/contracts/TokenTransferProxyNoDevdoc.sol @@ -0,0 +1,100 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity ^0.4.14; + +import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import { ERC20 as Token } from "zeppelin-solidity/contracts/token/ERC20/ERC20.sol"; + +contract TokenTransferProxyNoDevdoc is Ownable { + + modifier onlyAuthorized { + require(authorized[msg.sender]); + _; + } + + modifier targetAuthorized(address target) { + require(authorized[target]); + _; + } + + modifier targetNotAuthorized(address target) { + require(!authorized[target]); + _; + } + + mapping (address => bool) public authorized; + address[] public authorities; + + event LogAuthorizedAddressAdded(address indexed target, address indexed caller); + event LogAuthorizedAddressRemoved(address indexed target, address indexed caller); + + /* + * Public functions + */ + + function addAuthorizedAddress(address target) + public + onlyOwner + targetNotAuthorized(target) + { + authorized[target] = true; + authorities.push(target); + LogAuthorizedAddressAdded(target, msg.sender); + } + + function removeAuthorizedAddress(address target) + public + onlyOwner + targetAuthorized(target) + { + delete authorized[target]; + for (uint i = 0; i < authorities.length; i++) { + if (authorities[i] == target) { + authorities[i] = authorities[authorities.length - 1]; + authorities.length -= 1; + break; + } + } + LogAuthorizedAddressRemoved(target, msg.sender); + } + + function transferFrom( + address token, + address from, + address to, + uint value) + public + onlyAuthorized + returns (bool) + { + return Token(token).transferFrom(from, to, value); + } + + /* + * Public constant functions + */ + + function getAuthorizedAddresses() + public + constant + returns (address[]) + { + return authorities; + } +} diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index b71cce6e7..47289c7c6 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -12,67 +12,26 @@ import { chaiSetup } from './util/chai_setup'; chaiSetup.configure(); const expect = chai.expect; -describe('#SolidityDocGenerator', async () => { +describe('#SolidityDocGenerator', () => { + it('should generate a doc object that matches the devdoc-free fixture', async () => { + const doc = await generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, [ + 'TokenTransferProxyNoDevdoc', + ]); + expect(doc).to.not.be.undefined(); + + verifyTokenTransferProxyABIIsDocumented(doc, 'TokenTransferProxyNoDevdoc'); + }); const docPromises: Array> = [ generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`), generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, []), generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, ['TokenTransferProxy']), ]; docPromises.forEach(docPromise => { - it('should generate a doc object that matches the TokenTransferProxy fixture', async () => { + it('should generate a doc object that matches the fixture', async () => { const doc = await docPromise; expect(doc).to.not.be.undefined(); - expect(doc.TokenTransferProxy).to.not.be.undefined(); - expect(doc.TokenTransferProxy.constructors).to.not.be.undefined(); - const tokenTransferProxyConstructorCount = 0; - const tokenTransferProxyMethodCount = 8; - const tokenTransferProxyEventCount = 3; - expect(doc.TokenTransferProxy.constructors.length).to.equal(tokenTransferProxyConstructorCount); - expect(doc.TokenTransferProxy.methods.length).to.equal(tokenTransferProxyMethodCount); - if (_.isUndefined(doc.TokenTransferProxy.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.TokenTransferProxy.events.length).to.equal(tokenTransferProxyEventCount); - - expect(doc.Ownable).to.not.be.undefined(); - expect(doc.Ownable.constructors).to.not.be.undefined(); - expect(doc.Ownable.methods).to.not.be.undefined(); - const ownableConstructorCount = 1; - const ownableMethodCount = 2; - const ownableEventCount = 1; - expect(doc.Ownable.constructors.length).to.equal(ownableConstructorCount); - expect(doc.Ownable.methods.length).to.equal(ownableMethodCount); - if (_.isUndefined(doc.Ownable.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.Ownable.events.length).to.equal(ownableEventCount); - - expect(doc.ERC20).to.not.be.undefined(); - expect(doc.ERC20.constructors).to.not.be.undefined(); - expect(doc.ERC20.methods).to.not.be.undefined(); - const erc20ConstructorCount = 0; - const erc20MethodCount = 6; - const erc20EventCount = 2; - expect(doc.ERC20.constructors.length).to.equal(erc20ConstructorCount); - expect(doc.ERC20.methods.length).to.equal(erc20MethodCount); - if (_.isUndefined(doc.ERC20.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.ERC20.events.length).to.equal(erc20EventCount); - - expect(doc.ERC20Basic).to.not.be.undefined(); - expect(doc.ERC20Basic.constructors).to.not.be.undefined(); - expect(doc.ERC20Basic.methods).to.not.be.undefined(); - const erc20BasicConstructorCount = 0; - const erc20BasicMethodCount = 3; - const erc20BasicEventCount = 1; - expect(doc.ERC20Basic.constructors.length).to.equal(erc20BasicConstructorCount); - expect(doc.ERC20Basic.methods.length).to.equal(erc20BasicMethodCount); - if (_.isUndefined(doc.ERC20Basic.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.ERC20Basic.events.length).to.equal(erc20BasicEventCount); + verifyTokenTransferProxyABIIsDocumented(doc, 'TokenTransferProxy'); let addAuthorizedAddressMethod: SolidityMethod | undefined; for (const method of doc.TokenTransferProxy.methods) { @@ -80,10 +39,6 @@ describe('#SolidityDocGenerator', async () => { addAuthorizedAddressMethod = method; } } - expect( - addAuthorizedAddressMethod, - `method addAuthorizedAddress not found in ${JSON.stringify(doc.TokenTransferProxy.methods)}`, - ).to.not.be.undefined(); const tokenTransferProxyAddAuthorizedAddressComment = 'Authorizes an address.'; expect((addAuthorizedAddressMethod as SolidityMethod).comment).to.equal( tokenTransferProxyAddAuthorizedAddressComment, @@ -91,3 +46,68 @@ describe('#SolidityDocGenerator', async () => { }); }); }); + +function verifyTokenTransferProxyABIIsDocumented(doc: DocAgnosticFormat, contractName: string): void { + expect(doc[contractName]).to.not.be.undefined(); + expect(doc[contractName].constructors).to.not.be.undefined(); + const tokenTransferProxyConstructorCount = 0; + const tokenTransferProxyMethodCount = 8; + const tokenTransferProxyEventCount = 3; + expect(doc[contractName].constructors.length).to.equal(tokenTransferProxyConstructorCount); + expect(doc[contractName].methods.length).to.equal(tokenTransferProxyMethodCount); + const events = doc[contractName].events; + if (_.isUndefined(events)) { + throw new Error('events should never be undefined'); + } + expect(events.length).to.equal(tokenTransferProxyEventCount); + + expect(doc.Ownable).to.not.be.undefined(); + expect(doc.Ownable.constructors).to.not.be.undefined(); + expect(doc.Ownable.methods).to.not.be.undefined(); + const ownableConstructorCount = 1; + const ownableMethodCount = 2; + const ownableEventCount = 1; + expect(doc.Ownable.constructors.length).to.equal(ownableConstructorCount); + expect(doc.Ownable.methods.length).to.equal(ownableMethodCount); + if (_.isUndefined(doc.Ownable.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.Ownable.events.length).to.equal(ownableEventCount); + + expect(doc.ERC20).to.not.be.undefined(); + expect(doc.ERC20.constructors).to.not.be.undefined(); + expect(doc.ERC20.methods).to.not.be.undefined(); + const erc20ConstructorCount = 0; + const erc20MethodCount = 6; + const erc20EventCount = 2; + expect(doc.ERC20.constructors.length).to.equal(erc20ConstructorCount); + expect(doc.ERC20.methods.length).to.equal(erc20MethodCount); + if (_.isUndefined(doc.ERC20.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.ERC20.events.length).to.equal(erc20EventCount); + + expect(doc.ERC20Basic).to.not.be.undefined(); + expect(doc.ERC20Basic.constructors).to.not.be.undefined(); + expect(doc.ERC20Basic.methods).to.not.be.undefined(); + const erc20BasicConstructorCount = 0; + const erc20BasicMethodCount = 3; + const erc20BasicEventCount = 1; + expect(doc.ERC20Basic.constructors.length).to.equal(erc20BasicConstructorCount); + expect(doc.ERC20Basic.methods.length).to.equal(erc20BasicMethodCount); + if (_.isUndefined(doc.ERC20Basic.events)) { + throw new Error('events should never be undefined'); + } + expect(doc.ERC20Basic.events.length).to.equal(erc20BasicEventCount); + + let addAuthorizedAddressMethod: SolidityMethod | undefined; + for (const method of doc[contractName].methods) { + if (method.name === 'addAuthorizedAddress') { + addAuthorizedAddressMethod = method; + } + } + expect( + addAuthorizedAddressMethod, + `method addAuthorizedAddress not found in ${JSON.stringify(doc[contractName].methods)}`, + ).to.not.be.undefined(); +} -- cgit From 3c7155afb07f17c62d7203c43bddeb4a3c5b7b01 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 17 Sep 2018 17:14:23 -0400 Subject: test all the natspec stuff we use in our contracts --- .../test/fixtures/contracts/NatspecEverything.sol | 37 ++++++++ .../sol-doc/test/solidity_doc_generator_test.ts | 104 ++++++++++++++++++++- 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol b/packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol new file mode 100644 index 000000000..3dea03c9a --- /dev/null +++ b/packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol @@ -0,0 +1,37 @@ +pragma solidity ^0.4.24; + +/// @title Contract Title +/// @dev This is a very long documentation comment at the contract level. +/// It actually spans multiple lines, too. +contract NatspecEverything { + int d; + + /// @dev Constructor @dev + /// @param p Constructor @param + constructor(int p) public { d = p; } + + /// @notice publicMethod @notice + /// @dev publicMethod @dev + /// @param p publicMethod @param + /// @return publicMethod @return + function publicMethod(int p) public pure returns(int r) { return p; } + + /// @notice externalMethod @notice + /// @dev externalMethod @dev + /// @param p externalMethod @param + /// @return externalMethod @return + function externalMethod(int p) external pure returns(int r) { return p; } + + /// @dev Here is a really long developer documentation comment, which spans + /// multiple lines, for the purposes of making sure that broken lines are + /// consolidated into one devdoc comment. + function methodWithLongDevdoc(int p) public pure returns(int) { return p; } + + /// @dev AnEvent @dev + /// @param p on this event is an integer. + event AnEvent(int p); + + /// @dev methodWithSolhintDirective @dev + // solhint-disable no-empty-blocks + function methodWithSolhintDirective() public pure {} +} diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 47289c7c6..bae67001b 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -3,7 +3,7 @@ import * as _ from 'lodash'; import * as chai from 'chai'; import 'mocha'; -import { DocAgnosticFormat, SolidityMethod } from '@0xproject/types'; +import { DocAgnosticFormat, Event, SolidityMethod } from '@0xproject/types'; import { generateSolDocAsync } from '../src/solidity_doc_generator'; @@ -43,6 +43,108 @@ describe('#SolidityDocGenerator', () => { expect((addAuthorizedAddressMethod as SolidityMethod).comment).to.equal( tokenTransferProxyAddAuthorizedAddressComment, ); + + const expectedParamComment = 'Address to authorize.'; + expect((addAuthorizedAddressMethod as SolidityMethod).parameters[0].comment).to.equal(expectedParamComment); + }); + }); + describe('when processing all the permutations of devdoc stuff that we use in our contracts', () => { + let doc: DocAgnosticFormat; + before(async () => { + doc = await generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, ['NatspecEverything']); + expect(doc).to.not.be.undefined(); + expect(doc.NatspecEverything).to.not.be.undefined(); + }); + it('should emit the contract @title as its comment', () => { + expect(doc.NatspecEverything.comment).to.equal('Contract Title'); + }); + describe('should emit public method documentation for', () => { + let methodDoc: SolidityMethod; + before(() => { + // tslint:disable-next-line:no-unnecessary-type-assertion + methodDoc = doc.NatspecEverything.methods.find(method => { + return method.name === 'publicMethod'; + }) as SolidityMethod; + if (_.isUndefined(methodDoc)) { + throw new Error('publicMethod not found'); + } + }); + it('method name', () => { + expect(methodDoc.name).to.equal('publicMethod'); + }); + it('method comment', () => { + expect(methodDoc.comment).to.equal('publicMethod @dev'); + }); + it('parameter name', () => { + expect(methodDoc.parameters[0].name).to.equal('p'); + }); + it('parameter comment', () => { + expect(methodDoc.parameters[0].comment).to.equal('publicMethod @param'); + }); + it('return type name', () => { + expect(methodDoc.returnType.name).to.equal('r'); + }); + }); + describe('should emit external method documentation for', () => { + let methodDoc: SolidityMethod; + before(() => { + // tslint:disable-next-line:no-unnecessary-type-assertion + methodDoc = doc.NatspecEverything.methods.find(method => { + return method.name === 'externalMethod'; + }) as SolidityMethod; + if (_.isUndefined(methodDoc)) { + throw new Error('externalMethod not found'); + } + }); + it('method name', () => { + expect(methodDoc.name).to.equal('externalMethod'); + }); + it('method comment', () => { + expect(methodDoc.comment).to.equal('externalMethod @dev'); + }); + it('parameter name', () => { + expect(methodDoc.parameters[0].name).to.equal('p'); + }); + it('parameter comment', () => { + expect(methodDoc.parameters[0].comment).to.equal('externalMethod @param'); + }); + it('return type name', () => { + expect(methodDoc.returnType.name).to.equal('r'); + }); + }); + it('should not truncate a multi-line devdoc comment', () => { + // tslint:disable-next-line:no-unnecessary-type-assertion + const methodDoc: SolidityMethod = doc.NatspecEverything.methods.find(method => { + return method.name === 'methodWithLongDevdoc'; + }) as SolidityMethod; + if (_.isUndefined(methodDoc)) { + throw new Error('methodWithLongDevdoc not found'); + } + expect(methodDoc.comment).to.equal( + 'Here is a really long developer documentation comment, which spans multiple lines, for the purposes of making sure that broken lines are consolidated into one devdoc comment.', + ); + }); + describe('should emit event documentation for', () => { + let eventDoc: Event; + before(() => { + eventDoc = (doc.NatspecEverything.events as Event[])[0]; + }); + it('event name', () => { + expect(eventDoc.name).to.equal('AnEvent'); + }); + it('parameter name', () => { + expect(eventDoc.eventArgs[0].name).to.equal('p'); + }); + }); + it('should not let solhint directives obscure natspec content', () => { + // tslint:disable-next-line:no-unnecessary-type-assertion + const methodDoc: SolidityMethod = doc.NatspecEverything.methods.find(method => { + return method.name === 'methodWithSolhintDirective'; + }) as SolidityMethod; + if (_.isUndefined(methodDoc)) { + throw new Error('methodWithSolhintDirective not found'); + } + expect(methodDoc.comment).to.equal('methodWithSolhintDirective @dev'); }); }); }); -- cgit From 5b07669bd0e128a92c8a71d797ac95d77337209b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 17 Sep 2018 17:23:55 -0400 Subject: add and test support for fallback functions --- packages/sol-doc/src/solidity_doc_generator.ts | 6 +++++- packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 513468803..3501e9a52 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -1,6 +1,7 @@ import * as _ from 'lodash'; import { + AbiDefinition, ConstructorAbi, DataItem, DevdocOutput, @@ -100,10 +101,13 @@ function _genDocSection(compiledContract: StandardContractOutput): DocSection { // that's because the type of the events array doesn't have any fields for documentation! break; case 'function': + case 'fallback': docSection.methods.push(_genMethodDoc(abiDefinition, compiledContract.devdoc)); break; default: - throw new Error(`unknown and unsupported AbiDefinition type '${abiDefinition.type}'`); + throw new Error( + `unknown and unsupported AbiDefinition type '${(abiDefinition as AbiDefinition).type}'`, + ); } } diff --git a/packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol b/packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol index 3dea03c9a..c6ad3db81 100644 --- a/packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol +++ b/packages/sol-doc/test/fixtures/contracts/NatspecEverything.sol @@ -16,6 +16,9 @@ contract NatspecEverything { /// @return publicMethod @return function publicMethod(int p) public pure returns(int r) { return p; } + /// @dev Fallback @dev + function () public {} + /// @notice externalMethod @notice /// @dev externalMethod @dev /// @param p externalMethod @param -- cgit From 9201273939598a13ed00084acdb384403c36fcc4 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 17 Sep 2018 17:27:33 -0400 Subject: add and test support for return comment --- packages/sol-doc/src/solidity_doc_generator.ts | 6 ++++++ packages/sol-doc/test/solidity_doc_generator_test.ts | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 3501e9a52..e0dcb692a 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -176,6 +176,11 @@ function _genMethodDoc( ? { name: '', typeDocType: TypeDocTypes.Intrinsic } : _genMethodReturnTypeDoc(abiDefinition.outputs, methodSignature, devdocIfExists); + const returnComment = + _.isUndefined(devdocIfExists) || _.isUndefined(devdocIfExists.methods[methodSignature]) + ? undefined + : devdocIfExists.methods[methodSignature].return; + const isConstant = abiDefinition.type === 'fallback' ? true : abiDefinition.constant; // TODO: determine whether fallback functions are always constant, as coded just above @@ -185,6 +190,7 @@ function _genMethodDoc( callPath: '', // TODO: wtf is this? parameters, returnType, + returnComment, isConstant, isPayable: abiDefinition.payable, comment, diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index bae67001b..23ffe7b9e 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -84,6 +84,9 @@ describe('#SolidityDocGenerator', () => { it('return type name', () => { expect(methodDoc.returnType.name).to.equal('r'); }); + it('return comment', () => { + expect(methodDoc.returnComment).to.equal('publicMethod @return'); + }); }); describe('should emit external method documentation for', () => { let methodDoc: SolidityMethod; @@ -111,6 +114,9 @@ describe('#SolidityDocGenerator', () => { it('return type name', () => { expect(methodDoc.returnType.name).to.equal('r'); }); + it('return comment', () => { + expect(methodDoc.returnComment).to.equal('externalMethod @return'); + }); }); it('should not truncate a multi-line devdoc comment', () => { // tslint:disable-next-line:no-unnecessary-type-assertion -- cgit From 401ef2edef50a73ec387d95ac9998f9badb4b34a Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 17 Sep 2018 17:35:11 -0400 Subject: minorly tweak comments --- packages/sol-doc/src/solidity_doc_generator.ts | 1 - packages/sol-doc/test/solidity_doc_generator_test.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index e0dcb692a..6b561d8a6 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -122,7 +122,6 @@ function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: Devdo ); const comment = _devdocMethodDetailsIfExist(methodSignature, devdocIfExists); - // TODO: figure out why devdoc'd constructors don't get output by solc const constructorDoc: SolidityMethod = { isConstructor: true, diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 23ffe7b9e..896690ce6 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -13,7 +13,7 @@ chaiSetup.configure(); const expect = chai.expect; describe('#SolidityDocGenerator', () => { - it('should generate a doc object that matches the devdoc-free fixture', async () => { + it('should generate a doc object that matches the devdoc-free TokenTransferProxy fixture', async () => { const doc = await generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, [ 'TokenTransferProxyNoDevdoc', ]); @@ -27,7 +27,7 @@ describe('#SolidityDocGenerator', () => { generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, ['TokenTransferProxy']), ]; docPromises.forEach(docPromise => { - it('should generate a doc object that matches the fixture', async () => { + it('should generate a doc object that matches the TokenTransferProxy fixture', async () => { const doc = await docPromise; expect(doc).to.not.be.undefined(); -- cgit From 4ade674ada7596f1a7c5d0113815c5964e82db0f Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Thu, 13 Sep 2018 14:25:54 -0400 Subject: test multiple return values from a solidity method --- .../test/fixtures/contracts/MultipleReturnValues.sol | 7 +++++++ packages/sol-doc/test/solidity_doc_generator_test.ts | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 packages/sol-doc/test/fixtures/contracts/MultipleReturnValues.sol (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/test/fixtures/contracts/MultipleReturnValues.sol b/packages/sol-doc/test/fixtures/contracts/MultipleReturnValues.sol new file mode 100644 index 000000000..1e898622c --- /dev/null +++ b/packages/sol-doc/test/fixtures/contracts/MultipleReturnValues.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.4.24; + +contract MultipleReturnValues { + function methodWithMultipleReturnValues() public pure returns(int, int) { + return (0, 0); + } +} diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 896690ce6..5004b1a90 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -153,6 +153,26 @@ describe('#SolidityDocGenerator', () => { expect(methodDoc.comment).to.equal('methodWithSolhintDirective @dev'); }); }); + it('should document a method that returns multiple values', async () => { + const doc = await generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, ['MultipleReturnValues']); + expect(doc.MultipleReturnValues).to.not.be.undefined(); + expect(doc.MultipleReturnValues.methods).to.not.be.undefined(); + let methodWithMultipleReturnValues: SolidityMethod | undefined; + for (const method of doc.MultipleReturnValues.methods) { + if (method.name === 'methodWithMultipleReturnValues') { + methodWithMultipleReturnValues = method; + } + } + if (_.isUndefined(methodWithMultipleReturnValues)) { + throw new Error('method should not be undefined'); + } + const returnType = methodWithMultipleReturnValues.returnType; + expect(returnType.typeDocType).to.equal('tuple'); + if (_.isUndefined(returnType.tupleElements)) { + throw new Error('returnType.tupleElements should not be undefined'); + } + expect(returnType.tupleElements.length).to.equal(2); + }); }); function verifyTokenTransferProxyABIIsDocumented(doc: DocAgnosticFormat, contractName: string): void { -- cgit From 91de15d50e77db615da900ffa7aba6d32f40a28e Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 17 Sep 2018 18:46:11 -0400 Subject: remove stale comments --- packages/sol-doc/src/solidity_doc_generator.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 6b561d8a6..8093020b9 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -115,21 +115,17 @@ function _genDocSection(compiledContract: StandardContractOutput): DocSection { } function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: DevdocOutput | undefined): SolidityMethod { - const { parameters, methodSignature } = _genMethodParamsDoc( - '', // TODO: update depending on how constructors are keyed in devdoc - abiDefinition.inputs, - devdocIfExists, - ); + const { parameters, methodSignature } = _genMethodParamsDoc('', abiDefinition.inputs, devdocIfExists); const comment = _devdocMethodDetailsIfExist(methodSignature, devdocIfExists); const constructorDoc: SolidityMethod = { isConstructor: true, name: '', // sad we have to specify this - callPath: '', // TODO: wtf is this? + callPath: '', parameters, returnType: { name: '', typeDocType: TypeDocTypes.Intrinsic }, // sad we have to specify this - isConstant: false, // constructors are non-const by their nature, right? + isConstant: false, isPayable: abiDefinition.payable, comment, }; @@ -181,12 +177,11 @@ function _genMethodDoc( : devdocIfExists.methods[methodSignature].return; const isConstant = abiDefinition.type === 'fallback' ? true : abiDefinition.constant; - // TODO: determine whether fallback functions are always constant, as coded just above const methodDoc: SolidityMethod = { isConstructor: false, name, - callPath: '', // TODO: wtf is this? + callPath: '', parameters, returnType, returnComment, -- cgit From 4bab402e95fd2242ad3a472e2b5076c5026da50a Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 17 Sep 2018 19:02:48 -0400 Subject: doc constructors as returning a Reference... ...not an Intrinsic --- packages/sol-doc/src/solidity_doc_generator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 8093020b9..6c67f921d 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -124,7 +124,7 @@ function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: Devdo name: '', // sad we have to specify this callPath: '', parameters, - returnType: { name: '', typeDocType: TypeDocTypes.Intrinsic }, // sad we have to specify this + returnType: { name: '', typeDocType: TypeDocTypes.Reference }, // sad we have to specify this isConstant: false, isPayable: abiDefinition.payable, comment, -- cgit From 30622631ff588b4b87a05e4ce3ca2906ed1edf9f Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 17 Sep 2018 19:03:44 -0400 Subject: use Array.join rather than string concatenation --- packages/sol-doc/src/solidity_doc_generator.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 6c67f921d..78c56e7fa 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -231,8 +231,6 @@ function _genMethodParamsDoc( devdocIfExists: DevdocOutput | undefined, ): { parameters: Parameter[]; methodSignature: string } { const parameters: Parameter[] = []; - let methodSignature = `${name}(`; - for (const abiParam of abiParams) { const parameter: Parameter = { name: abiParam.name, @@ -241,13 +239,13 @@ function _genMethodParamsDoc( type: { name: abiParam.type, typeDocType: TypeDocTypes.Intrinsic }, }; parameters.push(parameter); - methodSignature = `${methodSignature}${abiParam.type},`; } - if (methodSignature.slice(-1) === ',') { - methodSignature = methodSignature.slice(0, -1); - } - methodSignature += ')'; + const methodSignature = `${name}(${abiParams + .map(abiParam => { + return abiParam.type; + }) + .join(',')})`; if (!_.isUndefined(devdocIfExists)) { const devdocMethodIfExists = devdocIfExists.methods[methodSignature]; -- cgit From 3e5d427d4e873080f2a369db7f844cbadd610fcb Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Fri, 21 Sep 2018 10:56:17 -0400 Subject: feat: add sol-doc command-line interface modified sol-compiler to output progress/warning/error/etc messages to stderr rather than stdout, so that sol-doc can put its output (and nothing else) to stdout. for posterity, added sol-doc cli usage as npm scripts to package.json. --- packages/sol-doc/package.json | 10 ++++++++-- packages/sol-doc/src/cli.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 packages/sol-doc/src/cli.ts (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index e3bc8753c..500b1cbde 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -11,7 +11,12 @@ "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", "lint": "tslint --project . --format stylish", - "clean": "shx rm -rf lib" + "clean": "shx rm -rf lib", + "generate-v2-protocol-docs": "(cd ../contracts/src/2.0.0; node ../../../../node_modules/.bin/sol-doc --contracts-dir . --contracts $(cd protocol; ls -C1 */*.sol */interfaces/*.sol) ) > v2.0.0.json", + "deploy-v2-protocol-docs": "aws --profile 0xproject s3 cp --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json v2.0.0.json s3://staging-doc-jsons/contracts/" + }, + "bin": { + "sol-doc": "bin/sol-doc.js" }, "repository": "https://github.com/0xProject/0x-monorepo.git", "author": "F. Eugene Aumson", @@ -21,7 +26,8 @@ "@0xproject/types": "^1.0.1-rc.6", "@0xproject/utils": "^1.0.5", "ethereum-types": "^1.0.4", - "lodash": "^4.17.10" + "lodash": "^4.17.10", + "yargs": "^12.0.2" }, "devDependencies": { "@0xproject/tslint-config": "^1.0.6", diff --git a/packages/sol-doc/src/cli.ts b/packages/sol-doc/src/cli.ts new file mode 100644 index 000000000..59fc185de --- /dev/null +++ b/packages/sol-doc/src/cli.ts @@ -0,0 +1,26 @@ +import 'source-map-support/register'; +import * as yargs from 'yargs'; + +import { generateSolDocAsync } from './solidity_doc_generator'; + +const JSON_TABWIDTH = 4; + +(async () => { + const argv = yargs + .option('contracts-dir', { + type: 'string', + description: 'path of contracts directory to compile', + }) + .option('contracts', { + type: 'string', + description: 'comma separated list of contracts to compile', + }) + .demandOption('contracts-dir') + .array('contracts') + .help().argv; + process.stdout.write( + JSON.stringify(await generateSolDocAsync(argv.contractsDir, argv.contracts), null, JSON_TABWIDTH), + ); +})().catch(err => { + throw err; +}); -- cgit From 37cb18e1daa8bf33b92b94b93851e91d50383c1e Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Sat, 22 Sep 2018 10:21:27 -0400 Subject: fix: rename variable --- packages/sol-doc/src/solidity_doc_generator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 78c56e7fa..2586cf91c 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -26,17 +26,17 @@ import { /** * Invoke the Solidity compiler and transform its ABI and devdoc outputs into * the types that are used as input to documentation generation tools. - * @param contractsToCompile list of contracts for which to generate doc objects + * @param contractsToDocument list of contracts for which to generate doc objects * @param contractsDir the directory in which to find the `contractsToCompile` as well as their dependencies. * @return doc object for use with documentation generation tools. */ export async function generateSolDocAsync( contractsDir: string, - contractsToCompile?: string[], + contractsToDocument?: string[], ): Promise { const doc: DocAgnosticFormat = {}; - const compilerOptions = _makeCompilerOptions(contractsDir, contractsToCompile); + const compilerOptions = _makeCompilerOptions(contractsDir, contractsToDocument); const compiler = new Compiler(compilerOptions); const compilerOutputs = await compiler.getCompilerOutputsAsync(); for (const compilerOutput of compilerOutputs) { -- cgit From 9f0dfb1e1a4c97e462cf298e0452be1d0fcf2216 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Sat, 22 Sep 2018 10:31:47 -0400 Subject: feat: make sol-doc only document what's requested if a list of contracts-to-document is passed into sol-doc, then the output should only contain documentation for the contracts requested. if an empty/undefined list is passed, then it should document all contracts that were found. --- packages/sol-doc/src/solidity_doc_generator.ts | 21 ++++++++++++++--- .../sol-doc/test/solidity_doc_generator_test.ts | 26 +++++++++------------- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 2586cf91c..074fb1f37 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -1,3 +1,5 @@ +import * as path from 'path'; + import * as _ from 'lodash'; import { @@ -34,8 +36,7 @@ export async function generateSolDocAsync( contractsDir: string, contractsToDocument?: string[], ): Promise { - const doc: DocAgnosticFormat = {}; - + const docWithDependencies: DocAgnosticFormat = {}; const compilerOptions = _makeCompilerOptions(contractsDir, contractsToDocument); const compiler = new Compiler(compilerOptions); const compilerOutputs = await compiler.getCompilerOutputsAsync(); @@ -50,11 +51,25 @@ export async function generateSolDocAsync( if (_.isUndefined(compiledContract.abi)) { throw new Error('compiled contract did not contain ABI output'); } - doc[contractName] = _genDocSection(compiledContract); + docWithDependencies[contractName] = _genDocSection(compiledContract); } } } + let doc: DocAgnosticFormat = {}; + if (_.isUndefined(contractsToDocument) || contractsToDocument.length === 0) { + doc = docWithDependencies; + } else { + for (const contractToDocument of contractsToDocument) { + const contractBasename = path.basename(contractToDocument); + const contractName = + contractBasename.lastIndexOf('.sol') === -1 + ? contractBasename + : contractBasename.substring(0, contractBasename.lastIndexOf('.sol')); + doc[contractName] = docWithDependencies[contractName]; + } + } + return doc; } diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 5004b1a90..0cbb786af 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -24,14 +24,13 @@ describe('#SolidityDocGenerator', () => { const docPromises: Array> = [ generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`), generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, []), - generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, ['TokenTransferProxy']), ]; docPromises.forEach(docPromise => { - it('should generate a doc object that matches the TokenTransferProxy fixture', async () => { + it('should generate a doc object that matches the TokenTransferProxy fixture with its dependencies', async () => { const doc = await docPromise; expect(doc).to.not.be.undefined(); - verifyTokenTransferProxyABIIsDocumented(doc, 'TokenTransferProxy'); + verifyTokenTransferProxyAndDepsABIsAreDocumented(doc, 'TokenTransferProxy'); let addAuthorizedAddressMethod: SolidityMethod | undefined; for (const method of doc.TokenTransferProxy.methods) { @@ -48,6 +47,12 @@ describe('#SolidityDocGenerator', () => { expect((addAuthorizedAddressMethod as SolidityMethod).parameters[0].comment).to.equal(expectedParamComment); }); }); + it('should generate a doc object that matches the TokenTransferProxy fixture', async () => { + const doc: DocAgnosticFormat = await generateSolDocAsync(`${__dirname}/../../test/fixtures/contracts`, [ + 'TokenTransferProxy', + ]); + verifyTokenTransferProxyABIIsDocumented(doc, 'TokenTransferProxy'); + }); describe('when processing all the permutations of devdoc stuff that we use in our contracts', () => { let doc: DocAgnosticFormat; before(async () => { @@ -188,19 +193,10 @@ function verifyTokenTransferProxyABIIsDocumented(doc: DocAgnosticFormat, contrac throw new Error('events should never be undefined'); } expect(events.length).to.equal(tokenTransferProxyEventCount); +} - expect(doc.Ownable).to.not.be.undefined(); - expect(doc.Ownable.constructors).to.not.be.undefined(); - expect(doc.Ownable.methods).to.not.be.undefined(); - const ownableConstructorCount = 1; - const ownableMethodCount = 2; - const ownableEventCount = 1; - expect(doc.Ownable.constructors.length).to.equal(ownableConstructorCount); - expect(doc.Ownable.methods.length).to.equal(ownableMethodCount); - if (_.isUndefined(doc.Ownable.events)) { - throw new Error('events should never be undefined'); - } - expect(doc.Ownable.events.length).to.equal(ownableEventCount); +function verifyTokenTransferProxyAndDepsABIsAreDocumented(doc: DocAgnosticFormat, contractName: string): void { + verifyTokenTransferProxyABIIsDocumented(doc, contractName); expect(doc.ERC20).to.not.be.undefined(); expect(doc.ERC20.constructors).to.not.be.undefined(); -- cgit From 880cd6e440c76d819cdb04d2971375cf9e0ea97b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 24 Sep 2018 10:21:12 -0400 Subject: fix: document return value's type, not its name --- packages/sol-doc/src/solidity_doc_generator.ts | 4 ++-- packages/sol-doc/test/solidity_doc_generator_test.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 074fb1f37..b2b5daff3 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -291,11 +291,11 @@ function _genMethodReturnTypeDoc( methodReturnTypeDoc.typeDocType = TypeDocTypes.Tuple; methodReturnTypeDoc.tupleElements = []; for (const output of outputs) { - methodReturnTypeDoc.tupleElements.push({ name: output.name, typeDocType: TypeDocTypes.Intrinsic }); + methodReturnTypeDoc.tupleElements.push({ name: output.type, typeDocType: TypeDocTypes.Intrinsic }); } } else if (outputs.length === 1) { methodReturnTypeDoc.typeDocType = TypeDocTypes.Intrinsic; - methodReturnTypeDoc.name = outputs[0].name; + methodReturnTypeDoc.name = outputs[0].type; } return methodReturnTypeDoc; } diff --git a/packages/sol-doc/test/solidity_doc_generator_test.ts b/packages/sol-doc/test/solidity_doc_generator_test.ts index 0cbb786af..c780d3d31 100644 --- a/packages/sol-doc/test/solidity_doc_generator_test.ts +++ b/packages/sol-doc/test/solidity_doc_generator_test.ts @@ -86,8 +86,8 @@ describe('#SolidityDocGenerator', () => { it('parameter comment', () => { expect(methodDoc.parameters[0].comment).to.equal('publicMethod @param'); }); - it('return type name', () => { - expect(methodDoc.returnType.name).to.equal('r'); + it('return type', () => { + expect(methodDoc.returnType.name).to.equal('int256'); }); it('return comment', () => { expect(methodDoc.returnComment).to.equal('publicMethod @return'); @@ -116,8 +116,8 @@ describe('#SolidityDocGenerator', () => { it('parameter comment', () => { expect(methodDoc.parameters[0].comment).to.equal('externalMethod @param'); }); - it('return type name', () => { - expect(methodDoc.returnType.name).to.equal('r'); + it('return type', () => { + expect(methodDoc.returnType.name).to.equal('int256'); }); it('return comment', () => { expect(methodDoc.returnComment).to.equal('externalMethod @return'); -- cgit From bd7565ceda1c54b51b601c0f6adf56161d7b6511 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 24 Sep 2018 12:36:26 -0400 Subject: fix: save v1 contract doc/deploy commands For posterity, save commands needed to use sol-doc to generate and deploy documentation objects for v1 contracts. --- packages/sol-doc/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index 500b1cbde..a3ded23f8 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -12,8 +12,10 @@ "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", "lint": "tslint --project . --format stylish", "clean": "shx rm -rf lib", + "generate-v1-protocol-docs": "(cd ../contracts/src/1.0.0; node ../../../../node_modules/.bin/sol-doc --contracts-dir . --contracts Exchange/Exchange_v1.sol TokenRegistry/TokenRegistry.sol TokenTransferProxy/TokenTransferProxy_v1.sol) > v1.0.0.json", "generate-v2-protocol-docs": "(cd ../contracts/src/2.0.0; node ../../../../node_modules/.bin/sol-doc --contracts-dir . --contracts $(cd protocol; ls -C1 */*.sol */interfaces/*.sol) ) > v2.0.0.json", - "deploy-v2-protocol-docs": "aws --profile 0xproject s3 cp --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json v2.0.0.json s3://staging-doc-jsons/contracts/" + "deploy-v2-protocol-docs": "aws --profile 0xproject s3 cp --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json v2.0.0.json s3://staging-doc-jsons/contracts/", + "deploy-v1-protocol-docs": "aws --profile 0xproject s3 cp --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json v1.0.0.json s3://staging-doc-jsons/contracts/" }, "bin": { "sol-doc": "bin/sol-doc.js" -- cgit From a9002558207883f66e3bb180415985d823f03772 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 24 Sep 2018 13:05:35 -0400 Subject: fix: document indexed event arguments --- packages/sol-doc/src/solidity_doc_generator.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index b2b5daff3..0df4a4af1 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -8,6 +8,7 @@ import { DataItem, DevdocOutput, EventAbi, + EventParameter, FallbackAbi, MethodAbi, StandardContractOutput, @@ -215,7 +216,7 @@ function _genEventDoc(abiDefinition: EventAbi): Event { return eventDoc; } -function _genEventArgsDoc(args: DataItem[], devdocIfExists: DevdocOutput | undefined): EventArg[] { +function _genEventArgsDoc(args: EventParameter[], devdocIfExists: DevdocOutput | undefined): EventArg[] { const eventArgsDoc: EventArg[] = []; for (const arg of args) { @@ -227,7 +228,7 @@ function _genEventArgsDoc(args: DataItem[], devdocIfExists: DevdocOutput | undef }; const eventArgDoc: EventArg = { - isIndexed: false, // TODO: wtf is this? + isIndexed: arg.indexed, name, type, }; -- cgit From 57fca16d7b1dc61c060c90fa440b1dc947aefb93 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 24 Sep 2018 13:18:10 -0400 Subject: fix: use contract name for constructor method name and for its return value --- packages/sol-doc/src/solidity_doc_generator.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index 0df4a4af1..b0c9ff314 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -52,7 +52,7 @@ export async function generateSolDocAsync( if (_.isUndefined(compiledContract.abi)) { throw new Error('compiled contract did not contain ABI output'); } - docWithDependencies[contractName] = _genDocSection(compiledContract); + docWithDependencies[contractName] = _genDocSection(compiledContract, contractName); } } } @@ -95,7 +95,7 @@ function _makeCompilerOptions(contractsDir: string, contractsToCompile?: string[ return compilerOptions; } -function _genDocSection(compiledContract: StandardContractOutput): DocSection { +function _genDocSection(compiledContract: StandardContractOutput, contractName: string): DocSection { const docSection: DocSection = { comment: _.isUndefined(compiledContract.devdoc) ? '' : compiledContract.devdoc.title, constructors: [], @@ -109,7 +109,7 @@ function _genDocSection(compiledContract: StandardContractOutput): DocSection { for (const abiDefinition of compiledContract.abi) { switch (abiDefinition.type) { case 'constructor': - docSection.constructors.push(_genConstructorDoc(abiDefinition, compiledContract.devdoc)); + docSection.constructors.push(_genConstructorDoc(contractName, abiDefinition, compiledContract.devdoc)); break; case 'event': (docSection.events as Event[]).push(_genEventDoc(abiDefinition)); @@ -130,17 +130,21 @@ function _genDocSection(compiledContract: StandardContractOutput): DocSection { return docSection; } -function _genConstructorDoc(abiDefinition: ConstructorAbi, devdocIfExists: DevdocOutput | undefined): SolidityMethod { +function _genConstructorDoc( + contractName: string, + abiDefinition: ConstructorAbi, + devdocIfExists: DevdocOutput | undefined, +): SolidityMethod { const { parameters, methodSignature } = _genMethodParamsDoc('', abiDefinition.inputs, devdocIfExists); const comment = _devdocMethodDetailsIfExist(methodSignature, devdocIfExists); const constructorDoc: SolidityMethod = { isConstructor: true, - name: '', // sad we have to specify this + name: contractName, callPath: '', parameters, - returnType: { name: '', typeDocType: TypeDocTypes.Reference }, // sad we have to specify this + returnType: { name: contractName, typeDocType: TypeDocTypes.Reference }, // sad we have to specify this isConstant: false, isPayable: abiDefinition.payable, comment, -- cgit From 9af5e3ba8e2e5547dcc5e9d9ae194be09847f8ac Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 24 Sep 2018 13:36:55 -0400 Subject: fix: add CHANGELOG.json --- packages/sol-doc/CHANGELOG.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 packages/sol-doc/CHANGELOG.json (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/CHANGELOG.json b/packages/sol-doc/CHANGELOG.json new file mode 100644 index 000000000..c5bd78356 --- /dev/null +++ b/packages/sol-doc/CHANGELOG.json @@ -0,0 +1,12 @@ +[ + { + "version": "1.0.0", + "changes": [ + { + "note": + "Utility to generate documentation for Solidity smart contracts, outputting a format compliant with @0xproject/types.DocAgnosticFormat", + "pr": 1004 + } + ] + } +] -- cgit From 574270d061f664176df012c5ef0b649e6d581e6d Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Mon, 24 Sep 2018 15:45:19 -0400 Subject: fix: increase mocha timeout value prior CI runs were failing because of this. --- packages/sol-doc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index a3ded23f8..b6162c963 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -6,7 +6,7 @@ "types": "lib/src/index.d.js", "scripts": { "build": "tsc", - "test": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --timeout 5000 --exit", + "test": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --timeout 6000 --exit", "test:circleci": "yarn test:coverage", "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", -- cgit From 600ffd93a626f9ce8168bc460c731ba8cd27d715 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 25 Sep 2018 15:25:10 -0400 Subject: fix: use latest versions of @0xproject packages https://github.com/0xProject/0x-monorepo/pull/1004#discussion_r219977747 https://github.com/0xProject/0x-monorepo/pull/1004 --- packages/sol-doc/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index b6162c963..cd0e5bbf0 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -24,15 +24,15 @@ "author": "F. Eugene Aumson", "license": "Apache-2.0", "dependencies": { - "@0xproject/sol-compiler": "^1.0.5", - "@0xproject/types": "^1.0.1-rc.6", - "@0xproject/utils": "^1.0.5", + "@0xproject/sol-compiler": "^1.1.4", + "@0xproject/types": "^1.1.0", + "@0xproject/utils": "^1.0.10", "ethereum-types": "^1.0.4", "lodash": "^4.17.10", "yargs": "^12.0.2" }, "devDependencies": { - "@0xproject/tslint-config": "^1.0.6", + "@0xproject/tslint-config": "^1.0.7", "chai": "^4.1.2", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.2", -- cgit From ac5376a1ca29f8cba3c94f759654ea50d4947f84 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 25 Sep 2018 15:26:42 -0400 Subject: fix: rename JSON_TABWIDTH to JSON_TAB_WIDTH https://github.com/0xProject/0x-monorepo/pull/1004#discussion_r219977842 https://github.com/0xProject/0x-monorepo/pull/1004 --- packages/sol-doc/src/cli.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/cli.ts b/packages/sol-doc/src/cli.ts index 59fc185de..1cdc35b64 100644 --- a/packages/sol-doc/src/cli.ts +++ b/packages/sol-doc/src/cli.ts @@ -3,7 +3,7 @@ import * as yargs from 'yargs'; import { generateSolDocAsync } from './solidity_doc_generator'; -const JSON_TABWIDTH = 4; +const JSON_TAB_WIDTH = 4; (async () => { const argv = yargs @@ -19,7 +19,7 @@ const JSON_TABWIDTH = 4; .array('contracts') .help().argv; process.stdout.write( - JSON.stringify(await generateSolDocAsync(argv.contractsDir, argv.contracts), null, JSON_TABWIDTH), + JSON.stringify(await generateSolDocAsync(argv.contractsDir, argv.contracts), null, JSON_TAB_WIDTH), ); })().catch(err => { throw err; -- cgit From 1db5ff617fe772d885e1cfd9ba67f645d8d4ee35 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 25 Sep 2018 15:29:09 -0400 Subject: fix: split line for readability https://github.com/0xProject/0x-monorepo/pull/1004#discussion_r219978696 https://github.com/0xProject/0x-monorepo/pull/1004 --- packages/sol-doc/src/cli.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/cli.ts b/packages/sol-doc/src/cli.ts index 1cdc35b64..b29a89147 100644 --- a/packages/sol-doc/src/cli.ts +++ b/packages/sol-doc/src/cli.ts @@ -18,9 +18,8 @@ const JSON_TAB_WIDTH = 4; .demandOption('contracts-dir') .array('contracts') .help().argv; - process.stdout.write( - JSON.stringify(await generateSolDocAsync(argv.contractsDir, argv.contracts), null, JSON_TAB_WIDTH), - ); + const doc = await generateSolDocAsync(argv.contractsDir, argv.contracts); + process.stdout.write(JSON.stringify(doc, null, JSON_TAB_WIDTH)); })().catch(err => { throw err; }); -- cgit From 7fbfd9ccd935812796ce297bb81fd8a4b72aa734 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 25 Sep 2018 15:31:13 -0400 Subject: fix: print error and exit process; don't re-throw https://github.com/0xProject/0x-monorepo/pull/1004#discussion_r219979003 https://github.com/0xProject/0x-monorepo/pull/1004 --- packages/sol-doc/src/cli.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/cli.ts b/packages/sol-doc/src/cli.ts index b29a89147..eb0f00bf6 100644 --- a/packages/sol-doc/src/cli.ts +++ b/packages/sol-doc/src/cli.ts @@ -1,6 +1,8 @@ import 'source-map-support/register'; import * as yargs from 'yargs'; +import { logUtils } from '@0xproject/utils'; + import { generateSolDocAsync } from './solidity_doc_generator'; const JSON_TAB_WIDTH = 4; @@ -21,5 +23,6 @@ const JSON_TAB_WIDTH = 4; const doc = await generateSolDocAsync(argv.contractsDir, argv.contracts); process.stdout.write(JSON.stringify(doc, null, JSON_TAB_WIDTH)); })().catch(err => { - throw err; + logUtils.warn(err); + process.exit(1); }); -- cgit From 2e7b218f4032cb213b947322e3e07ccb8709ca2b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Tue, 25 Sep 2018 15:32:52 -0400 Subject: fix: comments https://github.com/0xProject/0x-monorepo/pull/1004#discussion_r219990314 https://github.com/0xProject/0x-monorepo/pull/1004#discussion_r220007992 https://github.com/0xProject/0x-monorepo/pull/1004 --- packages/sol-doc/src/solidity_doc_generator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/src/solidity_doc_generator.ts b/packages/sol-doc/src/solidity_doc_generator.ts index b0c9ff314..5ddf001a6 100644 --- a/packages/sol-doc/src/solidity_doc_generator.ts +++ b/packages/sol-doc/src/solidity_doc_generator.ts @@ -27,8 +27,8 @@ import { } from '@0xproject/types'; /** - * Invoke the Solidity compiler and transform its ABI and devdoc outputs into - * the types that are used as input to documentation generation tools. + * Invoke the Solidity compiler and transform its ABI and devdoc outputs into a + * JSON format easily consumed by documentation rendering tools. * @param contractsToDocument list of contracts for which to generate doc objects * @param contractsDir the directory in which to find the `contractsToCompile` as well as their dependencies. * @return doc object for use with documentation generation tools. @@ -243,7 +243,7 @@ function _genEventArgsDoc(args: EventParameter[], devdocIfExists: DevdocOutput | } /** - * Extract documentation for each method paramater from @param params. + * Extract documentation for each method parameter from @param params. */ function _genMethodParamsDoc( name: string, -- cgit From 2bdaa58d71fb1e62fd07e6bf1be56d841446090b Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 26 Sep 2018 09:22:06 -0400 Subject: fix: use latest versions of @0xproject packages --- packages/sol-doc/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/sol-doc') diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index cd0e5bbf0..618cb7ef7 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -24,9 +24,9 @@ "author": "F. Eugene Aumson", "license": "Apache-2.0", "dependencies": { - "@0xproject/sol-compiler": "^1.1.4", - "@0xproject/types": "^1.1.0", - "@0xproject/utils": "^1.0.10", + "@0xproject/sol-compiler": "^1.1.5", + "@0xproject/types": "^1.1.1", + "@0xproject/utils": "^1.0.11", "ethereum-types": "^1.0.4", "lodash": "^4.17.10", "yargs": "^12.0.2" -- cgit