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/react-docs/src/index.ts | 1 + packages/sol-compiler/src/index.ts | 1 + 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 + 11 files changed, 264 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 diff --git a/packages/react-docs/src/index.ts b/packages/react-docs/src/index.ts index e4424f679..8b3a146db 100644 --- a/packages/react-docs/src/index.ts +++ b/packages/react-docs/src/index.ts @@ -18,6 +18,7 @@ export { DocsInfo } from './docs_info'; export { DocsInfoConfig, DocAgnosticFormat, + DocSection, DoxityDocObj, DocsMenu, SupportedDocJson, diff --git a/packages/sol-compiler/src/index.ts b/packages/sol-compiler/src/index.ts index f8c2b577a..1ad07a9ff 100644 --- a/packages/sol-compiler/src/index.ts +++ b/packages/sol-compiler/src/index.ts @@ -6,3 +6,4 @@ export { CompilerSettingsMetadata, OptimizerSettings, } from 'ethereum-types'; +export { StandardOutput } from 'solc'; 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