From 054b41ceabc5505cb172568f6eb1412bd01389de Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Fri, 25 Jan 2019 01:06:59 -0500 Subject: [PATCH 01/15] ResolverEngine works with sol-compiler --- packages/sol-compiler/src/compiler.ts | 70 +++++++----- packages/sol-compiler/src/utils/compiler.ts | 49 ++++---- .../typescript-typings/types/solc/index.d.ts | 2 +- yarn.lock | 107 +++++++++++++++++- 4 files changed, 179 insertions(+), 49 deletions(-) diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index d38ccbf394..7325b0dd21 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -9,6 +9,7 @@ import { SpyResolver, URLResolver, } from '@0x/sol-resolver'; +import { SolidityImportResolver, ImportFile, gatherSources, ResolverEngine } from 'resolver-engine'; import { logUtils } from '@0x/utils'; import * as chokidar from 'chokidar'; import { CompilerOptions, ContractArtifact, ContractVersionData, StandardOutput } from 'ethereum-types'; @@ -77,7 +78,8 @@ interface ContractData { * to artifact files. */ export class Compiler { - private readonly _resolver: Resolver; + private readonly _oldResolver: Resolver; + private readonly _resolver: ResolverEngine; private readonly _nameResolver: NameResolver; private readonly _contractsDir: string; private readonly _compilerSettings: solc.CompilerSettings; @@ -110,7 +112,8 @@ export class Compiler { resolver.appendResolver(new RelativeFSResolver(this._contractsDir)); resolver.appendResolver(new FSResolver()); resolver.appendResolver(this._nameResolver); - this._resolver = resolver; + this._resolver = SolidityImportResolver(); + this._oldResolver = resolver; } /** * Compiles selected Solidity files found in `contractsDir` and writes JSON artifacts to `artifactsDir`. @@ -166,19 +169,22 @@ export class Compiler { onFileChangedAsync(); // tslint:disable-line no-floating-promises }); } + + //TODO (squadack) przywrócić działanie - SpyResolver private _getPathsToWatch(): string[] { - const contractNames = this._getContractNamesToCompile(); - const spyResolver = new SpyResolver(this._resolver); - for (const contractName of contractNames) { - const contractSource = spyResolver.resolve(contractName); - // NOTE: We ignore the return value here. We don't want to compute the source tree hash. - // We just want to call a SpyResolver on each contracts and it's dependencies and - // this is a convenient way to reuse the existing code that does that. - // We can then get all the relevant paths from the `spyResolver` below. - getSourceTreeHash(spyResolver, contractSource.path); - } - const pathsToWatch = _.uniq(spyResolver.resolvedContractSources.map(cs => cs.absolutePath)); - return pathsToWatch; + // const contractNames = this._getContractNamesToCompile(); + // const spyResolver = new SpyResolver(this._resolver); + // for (const contractName of contractNames) { + // const contractSource = spyResolver.resolve(contractName); + // // NOTE: We ignore the return value here. We don't want to compute the source tree hash. + // // We just want to call a SpyResolver on each contracts and it's dependencies and + // // this is a convenient way to reuse the existing code that does that. + // // We can then get all the relevant paths from the `spyResolver` below. + // getSourceTreeHash(spyResolver, contractSource.path); + // } + // const pathsToWatch = _.uniq(spyResolver.resolvedContractSources.map(cs => cs.absolutePath)); + // return pathsToWatch; + return []; } private _getContractNamesToCompile(): string[] { let contractNamesToCompile; @@ -207,11 +213,15 @@ export class Compiler { const contractPathToData: ContractPathToData = {}; for (const contractName of contractNames) { - const contractSource = this._resolver.resolve(contractName); - const sourceTreeHashHex = getSourceTreeHash( - this._resolver, - path.join(this._contractsDir, contractSource.path), - ).toString('hex'); + // const contractSource = await this._resolver.require(contractName); + // TODO stary resolver! + const oldContractSource = this._oldResolver.resolve(contractName); + const contractSource: ImportFile = { + source: oldContractSource.source, + url: oldContractSource.absolutePath, + }; + const kek = await getSourceTreeHash(this._resolver, contractSource.url); + const sourceTreeHashHex = kek.toString('hex'); const contractData = { contractName, currentArtifactIfExists: await getContractArtifactIfExistsAsync(this._artifactsDir, contractName), @@ -220,7 +230,7 @@ export class Compiler { if (!this._shouldCompile(contractData)) { continue; } - contractPathToData[contractSource.path] = contractData; + contractPathToData[contractSource.url] = contractData; const solcVersion = _.isUndefined(this._solcVersionIfExists) ? semver.maxSatisfying(_.keys(binPaths), parseSolidityVersionRange(contractSource.source)) : this._solcVersionIfExists; @@ -236,10 +246,11 @@ export class Compiler { }; } // add input to the right version batch - versionToInputs[solcVersion].standardInput.sources[contractSource.path] = { - content: contractSource.source, - }; - versionToInputs[solcVersion].contractsToCompile.push(contractSource.path); + // versionToInputs[solcVersion].standardInput.sources[contractSource.path] = { + // content: contractSource.source, + // }; + // versionToInputs[solcVersion].contractsToCompile.push(contractSource.path); + versionToInputs[solcVersion].contractsToCompile.push(contractSource.url); } const compilerOutputs: StandardOutput[] = []; @@ -253,8 +264,15 @@ export class Compiler { }) with Solidity v${solcVersion}...`, ); + const depList = await gatherSources(input.contractsToCompile, process.cwd()); + for (const infile of depList) { + input.standardInput.sources[infile.url] = { + content: infile.source, + }; + } + const { solcInstance, fullSolcVersion } = await getSolcAsync(solcVersion); - const compilerOutput = compile(this._resolver, solcInstance, input.standardInput); + const compilerOutput = compile(solcInstance, input.standardInput); compilerOutputs.push(compilerOutput); for (const contractPath of input.contractsToCompile) { @@ -309,7 +327,7 @@ export class Compiler { // contains listings for every contract compiled during the compiler invocation that compiled the contract // to be persisted, which could include many that are irrelevant to the contract at hand. So, gather up only // the relevant sources: - const { sourceCodes, sources } = getSourcesWithDependencies( + const { sourceCodes, sources } = await getSourcesWithDependencies( this._resolver, contractPath, compilerOutput.sources, diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index db308f2b57..4a333830a7 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -13,6 +13,7 @@ import { binPaths } from '../solc/bin_paths'; import { constants } from './constants'; import { fsWrapper } from './fs_wrapper'; import { CompilationError } from './types'; +import { ImportFile, ResolverEngine } from 'resolver-engine'; /** * Gets contract data on network or returns if an artifact does not exist. @@ -122,14 +123,15 @@ export function parseDependencies(contractSource: ContractSource): string[] { * @param standardInput Solidity standard JSON input */ export function compile( - resolver: Resolver, + // resolver: Resolver, solcInstance: solc.SolcInstance, standardInput: solc.StandardInput, ): solc.StandardOutput { const standardInputStr = JSON.stringify(standardInput); const standardOutputStr = solcInstance.compileStandardWrapper(standardInputStr, importPath => { - const sourceCodeIfExists = resolver.resolve(importPath); - return { contents: sourceCodeIfExists.source }; + // HACK(squadack) i don't want to use callback + // all sources should be resolved beforehand + throw Error('used callback'); }); const compiled: solc.StandardOutput = JSON.parse(standardOutputStr); if (!_.isUndefined(compiled.errors)) { @@ -163,15 +165,16 @@ function printCompilationErrorsAndWarnings(solcErrors: solc.SolcError[]): void { * Gets the source tree hash for a file and its dependencies. * @param fileName Name of contract file. */ -export function getSourceTreeHash(resolver: Resolver, importPath: string): Buffer { - const contractSource = resolver.resolve(importPath); +export async function getSourceTreeHash(resolver: ResolverEngine, importPath: string): Promise { + const imFile: ImportFile = await resolver.require(importPath); + const contractSource = { source: imFile.source, path: imFile.url, absolutePath: imFile.url }; const dependencies = parseDependencies(contractSource); const sourceHash = ethUtil.sha3(contractSource.source); if (dependencies.length === 0) { return sourceHash; } else { - const dependencySourceTreeHashes = _.map(dependencies, (dependency: string) => - getSourceTreeHash(resolver, dependency), + const dependencySourceTreeHashes = await Promise.all( + _.map(dependencies, async (dependency: string) => getSourceTreeHash(resolver, dependency)), ); const sourceTreeHashesBuffer = Buffer.concat([sourceHash, ...dependencySourceTreeHashes]); const sourceTreeHash = ethUtil.sha3(sourceTreeHashesBuffer); @@ -187,14 +190,15 @@ export function getSourceTreeHash(resolver: Resolver, importPath: string): Buffe * taken from the corresponding ID's in @param fullSources, and the content for @return sourceCodes is read from * disk (via the aforementioned `resolver.source`). */ -export function getSourcesWithDependencies( - resolver: Resolver, +export async function getSourcesWithDependencies( + resolver: ResolverEngine, contractPath: string, fullSources: { [sourceName: string]: { id: number } }, -): { sourceCodes: { [sourceName: string]: string }; sources: { [sourceName: string]: { id: number } } } { +): Promise<{ sourceCodes: { [sourceName: string]: string }; sources: { [sourceName: string]: { id: number } } }> { const sources = { [contractPath]: { id: fullSources[contractPath].id } }; - const sourceCodes = { [contractPath]: resolver.resolve(contractPath).source }; - recursivelyGatherDependencySources( + const pamparampam = await resolver.require(contractPath); + const sourceCodes = { [contractPath]: pamparampam.source }; + await recursivelyGatherDependencySources( resolver, contractPath, sourceCodes[contractPath], @@ -205,14 +209,14 @@ export function getSourcesWithDependencies( return { sourceCodes, sources }; } -function recursivelyGatherDependencySources( - resolver: Resolver, +async function recursivelyGatherDependencySources( + resolver: ResolverEngine, contractPath: string, contractSource: string, fullSources: { [sourceName: string]: { id: number } }, sourcesToAppendTo: { [sourceName: string]: { id: number } }, sourceCodesToAppendTo: { [sourceName: string]: string }, -): void { +): Promise { const importStatementMatches = contractSource.match(/\nimport[^;]*;/g); if (importStatementMatches === null) { return; @@ -247,17 +251,24 @@ function recursivelyGatherDependencySources( * while others are absolute ("Token.sol", "@0x/contracts/Wallet.sol") * And we need to append the base path for relative imports. */ - importPath = path.resolve(`/${contractFolder}`, importPath).replace('/', ''); + importPath = path.resolve(`/${contractFolder}`, importPath); + // HACK(squadack) + // chcemy uciąć wiodący slash tylko jeśli jest to faktycznie ścieżka bezwględna + // TODO obejść to jakoś + if (!importPath.startsWith('/home')) { + importPath = importPath.replace('/', ''); + } } if (_.isUndefined(sourcesToAppendTo[importPath])) { sourcesToAppendTo[importPath] = { id: fullSources[importPath].id }; - sourceCodesToAppendTo[importPath] = resolver.resolve(importPath).source; + const sialala = await resolver.require(importPath); + sourceCodesToAppendTo[importPath] = sialala.source; - recursivelyGatherDependencySources( + await recursivelyGatherDependencySources( resolver, importPath, - resolver.resolve(importPath).source, + sialala.source, fullSources, sourcesToAppendTo, sourceCodesToAppendTo, diff --git a/packages/typescript-typings/types/solc/index.d.ts b/packages/typescript-typings/types/solc/index.d.ts index f4c05cd7c9..fefad9f6a4 100644 --- a/packages/typescript-typings/types/solc/index.d.ts +++ b/packages/typescript-typings/types/solc/index.d.ts @@ -95,7 +95,7 @@ declare module 'solc' { optimizerEnabled: number, findImports: (importPath: string) => ImportContents, ): CompilationResult; - compileStandardWrapper(input: string, findImports: (importPath: string) => ImportContents): string; + compileStandardWrapper(input: string, findImports?: (importPath: string) => ImportContents): string; } export function loadRemoteVersion( versionName: string, diff --git a/yarn.lock b/yarn.lock index 1f29ee2fb4..420b44d8db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2152,6 +2152,11 @@ aes-js@^0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d" +aes-js@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== + agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -3721,7 +3726,7 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "^2.0.0" -bs58@=4.0.1: +bs58@=4.0.1, bs58@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" dependencies: @@ -3744,6 +3749,15 @@ bs58check@^1.0.8: bs58 "^3.1.0" create-hash "^1.1.0" +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + bser@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" @@ -6499,6 +6513,19 @@ ethereumjs-util@^5.2.0: safe-buffer "^5.1.1" secp256k1 "^3.0.1" +ethereumjs-util@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.0.0.tgz#f14841c182b918615afefd744207c7932c8536c0" + integrity sha512-E3yKUyl0Fs95nvTFQZe/ZSNcofhDzUsDlA5y2uoRmf1+Ec7gpGhNCsgKkZBRh7Br5op8mJcYF/jFbmjj909+nQ== + dependencies: + bn.js "^4.11.0" + create-hash "^1.1.2" + ethjs-util "^0.1.6" + keccak "^1.0.2" + rlp "^2.0.0" + safe-buffer "^5.1.1" + secp256k1 "^3.0.1" + ethereumjs-vm@2.3.5: version "2.3.5" resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz#e69306737b8a7ea80c633ceb9b7dd561897007de" @@ -6543,6 +6570,21 @@ ethereumjs-wallet@0.6.0: utf8 "^2.1.1" uuid "^2.0.1" +ethereumjs-wallet@~0.6.0: + version "0.6.3" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.3.tgz#b0eae6f327637c2aeb9ccb9047b982ac542e6ab1" + integrity sha512-qiXPiZOsStem+Dj/CQHbn5qex+FVkuPmGH7SvSnA9F3tdRDt8dLMyvIj3+U05QzVZNPYh4HXEdnzoYI4dZkr9w== + dependencies: + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereumjs-util "^6.0.0" + hdkey "^1.1.0" + randombytes "^2.0.6" + safe-buffer "^5.1.2" + scrypt.js "^0.3.0" + utf8 "^3.0.0" + uuid "^3.3.2" + ethers@~4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.4.tgz#d3f85e8b27f4b59537e06526439b0fb15b44dc65" @@ -6588,6 +6630,14 @@ ethjs-util@^0.1.3: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" +ethjs-util@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + ev-emitter@^1.0.0, ev-emitter@^1.0.1, ev-emitter@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-1.1.1.tgz#8f18b0ce5c76a5d18017f71c0a795c65b9138f2a" @@ -7472,7 +7522,7 @@ ganache-core@0xProject/ganache-core#monorepo-dep: ethereumjs-tx "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default" ethereumjs-util "^5.2.0" ethereumjs-vm "2.3.5" - ethereumjs-wallet "~0.6.0" + ethereumjs-wallet "0.6.0" fake-merkle-patricia-tree "~1.0.1" heap "~0.2.6" js-scrypt "^0.2.0" @@ -8222,6 +8272,15 @@ hdkey@^0.7.0, hdkey@^0.7.1: coinstring "^2.0.0" secp256k1 "^3.0.1" +hdkey@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" + integrity sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ== + dependencies: + coinstring "^2.0.0" + safe-buffer "^5.1.1" + secp256k1 "^3.0.1" + he@1.1.1, he@1.1.x: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -13405,7 +13464,7 @@ randomatic@^1.1.3: is-number "^3.0.0" kind-of "^4.0.0" -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" dependencies: @@ -13549,6 +13608,16 @@ react-dom@^16.3.2: object-assign "^4.1.1" prop-types "^15.6.0" +react-dom@^16.4.2: + version "16.7.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8" + integrity sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.12.0" + react-dom@^16.5.2: version "16.5.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.5.2.tgz#b69ee47aa20bab5327b2b9d7c1fe2a30f2cfa9d7" @@ -13890,6 +13959,16 @@ react@^16.3.2: object-assign "^4.1.1" prop-types "^15.6.0" +react@^16.4.2: + version "16.7.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" + integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.12.0" + react@^16.5.2: version "16.5.2" resolved "https://registry.yarnpkg.com/react/-/react-16.5.2.tgz#19f6b444ed139baa45609eee6dc3d318b3895d42" @@ -14772,6 +14851,14 @@ schedule@^0.5.0: dependencies: object-assign "^4.1.1" +scheduler@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b" + integrity sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^0.4.4: version "0.4.7" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" @@ -14809,6 +14896,15 @@ scrypt.js@0.2.0, scrypt.js@^0.2.0: scrypt "^6.0.2" scryptsy "^1.2.1" +scrypt.js@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.3.0.tgz#6c62d61728ad533c8c376a2e5e3e86d41a95c4c0" + integrity sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A== + dependencies: + scryptsy "^1.2.1" + optionalDependencies: + scrypt "^6.0.2" + scrypt@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" @@ -17076,6 +17172,11 @@ utf8@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" +utf8@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" From 6a14c47255f028a891d41a966e3b8ad3f6c05976 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Tue, 29 Jan 2019 07:55:42 -0500 Subject: [PATCH 02/15] reordered imports --- packages/sol-compiler/src/compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index 7325b0dd21..f803af9915 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -9,7 +9,6 @@ import { SpyResolver, URLResolver, } from '@0x/sol-resolver'; -import { SolidityImportResolver, ImportFile, gatherSources, ResolverEngine } from 'resolver-engine'; import { logUtils } from '@0x/utils'; import * as chokidar from 'chokidar'; import { CompilerOptions, ContractArtifact, ContractVersionData, StandardOutput } from 'ethereum-types'; @@ -17,6 +16,7 @@ import * as fs from 'fs'; import * as _ from 'lodash'; import * as path from 'path'; import * as pluralize from 'pluralize'; +import { gatherSources, ImportFile, ResolverEngine, SolidityImportResolver } from 'resolver-engine'; import * as semver from 'semver'; import solc = require('solc'); From 42f8129a21e83827ec5a0b65a31e213a668ba6b1 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Tue, 29 Jan 2019 16:41:31 -0500 Subject: [PATCH 03/15] used glob to create new NameResolver and remove the need to use getAll() from the old one --- packages/sol-compiler/package.json | 2 + packages/sol-compiler/src/compiler.ts | 36 +++--- .../sol-compiler/src/utils/name_resolver.ts | 103 +++++++++++++++++ yarn.lock | 108 +++++------------- 4 files changed, 157 insertions(+), 92 deletions(-) create mode 100644 packages/sol-compiler/src/utils/name_resolver.ts diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 26c8e88337..37d98b4381 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -45,6 +45,7 @@ "@0x/dev-utils": "^1.0.24", "@0x/tslint-config": "^2.0.2", "@types/chokidar": "^1.7.5", + "@types/glob": "^7.1.1", "@types/mkdirp": "^0.5.2", "@types/pluralize": "^0.0.29", "@types/require-from-string": "^1.2.0", @@ -79,6 +80,7 @@ "chokidar": "^2.0.4", "ethereum-types": "^1.1.6", "ethereumjs-util": "^5.1.1", + "glob": "^7.1.3", "lodash": "^4.17.5", "mkdirp": "^0.5.1", "pluralize": "^7.0.0", diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index f803af9915..bc5519b583 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -9,10 +9,11 @@ import { SpyResolver, URLResolver, } from '@0x/sol-resolver'; -import { logUtils } from '@0x/utils'; +import { logUtils, promisify } from '@0x/utils'; import * as chokidar from 'chokidar'; import { CompilerOptions, ContractArtifact, ContractVersionData, StandardOutput } from 'ethereum-types'; import * as fs from 'fs'; +import glob = require('glob'); import * as _ from 'lodash'; import * as path from 'path'; import * as pluralize from 'pluralize'; @@ -34,8 +35,12 @@ import { } from './utils/compiler'; import { constants } from './utils/constants'; import { fsWrapper } from './utils/fs_wrapper'; +// TODO rename panoramix XD +import { NameResolver as panoramix } from './utils/name_resolver'; import { utils } from './utils/utils'; +const globAsync = promisify(glob); + type TYPE_ALL_FILES_IDENTIFIER = '*'; const ALL_CONTRACTS_IDENTIFIER = '*'; const ALL_FILES_IDENTIFIER = '*'; @@ -112,7 +117,8 @@ export class Compiler { resolver.appendResolver(new RelativeFSResolver(this._contractsDir)); resolver.appendResolver(new FSResolver()); resolver.appendResolver(this._nameResolver); - this._resolver = SolidityImportResolver(); + this._contractsDir = path.resolve(this._contractsDir); + this._resolver = SolidityImportResolver().addResolver(panoramix(this._contractsDir)); this._oldResolver = resolver; } /** @@ -121,7 +127,7 @@ export class Compiler { public async compileAsync(): Promise { await createDirIfDoesNotExistAsync(this._artifactsDir); await createDirIfDoesNotExistAsync(constants.SOLC_BIN_DIR); - await this._compileContractsAsync(this._getContractNamesToCompile(), true); + await this._compileContractsAsync(await this._getContractNamesToCompileAsync(), true); } /** * Compiles Solidity files specified during instantiation, and returns the @@ -132,7 +138,7 @@ export class Compiler { * that version. */ public async getCompilerOutputsAsync(): Promise { - const promisedOutputs = this._compileContractsAsync(this._getContractNamesToCompile(), false); + const promisedOutputs = this._compileContractsAsync(await this._getContractNamesToCompileAsync(), false); return promisedOutputs; } public async watchAsync(): Promise { @@ -170,7 +176,7 @@ export class Compiler { }); } - //TODO (squadack) przywrócić działanie - SpyResolver + // TODO (squadack) przywrócić działanie - SpyResolver private _getPathsToWatch(): string[] { // const contractNames = this._getContractNamesToCompile(); // const spyResolver = new SpyResolver(this._resolver); @@ -186,12 +192,12 @@ export class Compiler { // return pathsToWatch; return []; } - private _getContractNamesToCompile(): string[] { + private async _getContractNamesToCompileAsync(): Promise { let contractNamesToCompile; if (this._specifiedContracts === ALL_CONTRACTS_IDENTIFIER) { - const allContracts = this._nameResolver.getAll(); + const allContracts = await globAsync(this._contractsDir + '/**/*' + constants.SOLIDITY_FILE_EXTENSION); contractNamesToCompile = _.map(allContracts, contractSource => - path.basename(contractSource.path, constants.SOLIDITY_FILE_EXTENSION), + path.basename(contractSource, constants.SOLIDITY_FILE_EXTENSION), ); } else { contractNamesToCompile = this._specifiedContracts.map(specifiedContract => @@ -213,13 +219,13 @@ export class Compiler { const contractPathToData: ContractPathToData = {}; for (const contractName of contractNames) { - // const contractSource = await this._resolver.require(contractName); - // TODO stary resolver! - const oldContractSource = this._oldResolver.resolve(contractName); - const contractSource: ImportFile = { - source: oldContractSource.source, - url: oldContractSource.absolutePath, - }; + const contractSource = await this._resolver.require(contractName); + // const oldContractSource = this._oldResolver.resolve(contractName); + // const contractSource: ImportFile = { + // source: oldContractSource.source, + // url: oldContractSource.absolutePath, + // }; + // TODO rename kek xD const kek = await getSourceTreeHash(this._resolver, contractSource.url); const sourceTreeHashHex = kek.toString('hex'); const contractData = { diff --git a/packages/sol-compiler/src/utils/name_resolver.ts b/packages/sol-compiler/src/utils/name_resolver.ts new file mode 100644 index 0000000000..c6b40dfa98 --- /dev/null +++ b/packages/sol-compiler/src/utils/name_resolver.ts @@ -0,0 +1,103 @@ +import { promisify } from '@0x/utils'; +import * as fs from 'fs'; +import * as path from 'path'; + +import glob = require('glob'); +import { SubResolver } from 'resolver-engine'; + +// import { ContractSource } from '../types'; + +// import { EnumerableResolver } from './enumerable_resolver'; +const globAsync = promisify(glob); + +const SOLIDITY_FILE_EXTENSION = '.sol'; + +export function NameResolver(contractDir: string): SubResolver { + return async (resolvePath: string) => { + const results = await globAsync(contractDir + '/**/' + resolvePath + SOLIDITY_FILE_EXTENSION); + if (results.length === 1) { + return results[0]; + } + return null; + }; +} + +// try { +// new Promise((resolve, reject) => { +// glob("**/*.sol", (err, matches) => { +// if (err) { +// return reject(err); +// } +// return resolve(matches); +// throw new Error("Dupa"); +// }) +// }).then(file => console.log(file)).catch(err => err); +// catch (err) { + +// } + +// await globAsync("**/*.sol"); + +// GlobResolver(uri): string[]; + +// NameResolver() { +// GlobResolver(con) +// } + +// export class NameResolver extends EnumerableResolver { +// private readonly _contractsDir: string; +// constructor(contractsDir: string) { +// super(); +// this._contractsDir = contractsDir; +// } +// public resolveIfExists(lookupContractName: string): ContractSource | undefined { +// let contractSource: ContractSource | undefined; +// const onFile = (filePath: string) => { +// const contractName = path.basename(filePath, SOLIDITY_FILE_EXTENSION); +// if (contractName === lookupContractName) { +// const absoluteContractPath = path.join(this._contractsDir, filePath); +// const source = fs.readFileSync(absoluteContractPath).toString(); +// contractSource = { source, path: filePath, absolutePath: absoluteContractPath }; +// return true; +// } +// return undefined; +// }; +// this._traverseContractsDir(this._contractsDir, onFile); +// return contractSource; +// } +// public getAll(): ContractSource[] { +// const contractSources: ContractSource[] = []; +// const onFile = (filePath: string) => { +// const absoluteContractPath = path.join(this._contractsDir, filePath); +// const source = fs.readFileSync(absoluteContractPath).toString(); +// const contractSource = { source, path: filePath, absolutePath: absoluteContractPath }; +// contractSources.push(contractSource); +// }; +// this._traverseContractsDir(this._contractsDir, onFile); +// return contractSources; +// } +// // tslint:disable-next-line:prefer-function-over-method +// private _traverseContractsDir(dirPath: string, onFile: (filePath: string) => true | void): boolean { +// let dirContents: string[] = []; +// try { +// dirContents = fs.readdirSync(dirPath); +// } catch (err) { +// throw new Error(`No directory found at ${dirPath}`); +// } +// for (const fileName of dirContents) { +// const absoluteEntryPath = path.join(dirPath, fileName); +// const isDirectory = fs.lstatSync(absoluteEntryPath).isDirectory(); +// const entryPath = path.relative(this._contractsDir, absoluteEntryPath); +// let isComplete; +// if (isDirectory) { +// isComplete = this._traverseContractsDir(absoluteEntryPath, onFile); +// } else if (fileName.endsWith(SOLIDITY_FILE_EXTENSION)) { +// isComplete = onFile(entryPath); +// } +// if (isComplete) { +// return isComplete; +// } +// } +// return false; +// } +// } diff --git a/yarn.lock b/yarn.lock index 420b44d8db..b796d0e78a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1448,6 +1448,15 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + "@types/handlebars@^4.0.36": version "4.0.37" resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.37.tgz#a3bc3eba0c0f03f753cac00841a5b21e26a02c03" @@ -2152,11 +2161,6 @@ aes-js@^0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d" -aes-js@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" - integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== - agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -3726,7 +3730,7 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "^2.0.0" -bs58@=4.0.1, bs58@^4.0.0: +bs58@=4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" dependencies: @@ -3749,15 +3753,6 @@ bs58check@^1.0.8: bs58 "^3.1.0" create-hash "^1.1.0" -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - bser@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" @@ -6513,19 +6508,6 @@ ethereumjs-util@^5.2.0: safe-buffer "^5.1.1" secp256k1 "^3.0.1" -ethereumjs-util@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.0.0.tgz#f14841c182b918615afefd744207c7932c8536c0" - integrity sha512-E3yKUyl0Fs95nvTFQZe/ZSNcofhDzUsDlA5y2uoRmf1+Ec7gpGhNCsgKkZBRh7Br5op8mJcYF/jFbmjj909+nQ== - dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - ethjs-util "^0.1.6" - keccak "^1.0.2" - rlp "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - ethereumjs-vm@2.3.5: version "2.3.5" resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz#e69306737b8a7ea80c633ceb9b7dd561897007de" @@ -6570,21 +6552,6 @@ ethereumjs-wallet@0.6.0: utf8 "^2.1.1" uuid "^2.0.1" -ethereumjs-wallet@~0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.3.tgz#b0eae6f327637c2aeb9ccb9047b982ac542e6ab1" - integrity sha512-qiXPiZOsStem+Dj/CQHbn5qex+FVkuPmGH7SvSnA9F3tdRDt8dLMyvIj3+U05QzVZNPYh4HXEdnzoYI4dZkr9w== - dependencies: - aes-js "^3.1.1" - bs58check "^2.1.2" - ethereumjs-util "^6.0.0" - hdkey "^1.1.0" - randombytes "^2.0.6" - safe-buffer "^5.1.2" - scrypt.js "^0.3.0" - utf8 "^3.0.0" - uuid "^3.3.2" - ethers@~4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.4.tgz#d3f85e8b27f4b59537e06526439b0fb15b44dc65" @@ -6630,14 +6597,6 @@ ethjs-util@^0.1.3: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -ethjs-util@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - ev-emitter@^1.0.0, ev-emitter@^1.0.1, ev-emitter@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-1.1.1.tgz#8f18b0ce5c76a5d18017f71c0a795c65b9138f2a" @@ -7823,7 +7782,8 @@ glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glo glob@7.1.3, glob@^7.1.3: version "7.1.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -8001,10 +7961,22 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@4.1.15, graceful-fs@^3.0.0, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@~1.2.0: +graceful-fs@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + integrity sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg= + dependencies: + natives "^1.1.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.15" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" +graceful-fs@~1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" + integrity sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q= + "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" @@ -8272,15 +8244,6 @@ hdkey@^0.7.0, hdkey@^0.7.1: coinstring "^2.0.0" secp256k1 "^3.0.1" -hdkey@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" - integrity sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ== - dependencies: - coinstring "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - he@1.1.1, he@1.1.x: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -11473,6 +11436,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natives@^1.1.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.6.tgz#a603b4a498ab77173612b9ea1acdec4d980f00bb" + integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -13464,7 +13432,7 @@ randomatic@^1.1.3: is-number "^3.0.0" kind-of "^4.0.0" -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" dependencies: @@ -14896,15 +14864,6 @@ scrypt.js@0.2.0, scrypt.js@^0.2.0: scrypt "^6.0.2" scryptsy "^1.2.1" -scrypt.js@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.3.0.tgz#6c62d61728ad533c8c376a2e5e3e86d41a95c4c0" - integrity sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A== - dependencies: - scryptsy "^1.2.1" - optionalDependencies: - scrypt "^6.0.2" - scrypt@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" @@ -17172,11 +17131,6 @@ utf8@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" -utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" From 67e8a41c3a74ed8dc727d1dae69d91c05e330fd2 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Tue, 29 Jan 2019 17:24:36 -0500 Subject: [PATCH 04/15] removed sol-resolver dependencies --- packages/sol-compiler/src/compiler.ts | 21 ------------------- packages/sol-compiler/src/utils/compiler.ts | 9 ++++---- .../sol-compiler/test/compiler_utils_test.ts | 12 ++++++++--- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index bc5519b583..d5c9eb911e 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -1,14 +1,4 @@ import { assert } from '@0x/assert'; -import { - FallthroughResolver, - FSResolver, - NameResolver, - NPMResolver, - RelativeFSResolver, - Resolver, - SpyResolver, - URLResolver, -} from '@0x/sol-resolver'; import { logUtils, promisify } from '@0x/utils'; import * as chokidar from 'chokidar'; import { CompilerOptions, ContractArtifact, ContractVersionData, StandardOutput } from 'ethereum-types'; @@ -83,9 +73,7 @@ interface ContractData { * to artifact files. */ export class Compiler { - private readonly _oldResolver: Resolver; private readonly _resolver: ResolverEngine; - private readonly _nameResolver: NameResolver; private readonly _contractsDir: string; private readonly _compilerSettings: solc.CompilerSettings; private readonly _artifactsDir: string; @@ -109,17 +97,8 @@ export class Compiler { this._compilerSettings = passedOpts.compilerSettings || config.compilerSettings || DEFAULT_COMPILER_SETTINGS; this._artifactsDir = passedOpts.artifactsDir || config.artifactsDir || DEFAULT_ARTIFACTS_DIR; this._specifiedContracts = passedOpts.contracts || config.contracts || ALL_CONTRACTS_IDENTIFIER; - this._nameResolver = new NameResolver(path.resolve(this._contractsDir)); - const resolver = new FallthroughResolver(); - resolver.appendResolver(new URLResolver()); - const packagePath = path.resolve(''); - resolver.appendResolver(new NPMResolver(packagePath)); - resolver.appendResolver(new RelativeFSResolver(this._contractsDir)); - resolver.appendResolver(new FSResolver()); - resolver.appendResolver(this._nameResolver); this._contractsDir = path.resolve(this._contractsDir); this._resolver = SolidityImportResolver().addResolver(panoramix(this._contractsDir)); - this._oldResolver = resolver; } /** * Compiles selected Solidity files found in `contractsDir` and writes JSON artifacts to `artifactsDir`. diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index 4a333830a7..b2405c83b0 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -1,4 +1,3 @@ -import { ContractSource, Resolver } from '@0x/sol-resolver'; import { fetchAsync, logUtils } from '@0x/utils'; import chalk from 'chalk'; import { ContractArtifact } from 'ethereum-types'; @@ -89,12 +88,14 @@ export function getNormalizedErrMsg(errMsg: string): string { return normalizedErrMsg; } +//TODO squadack - czy tego po prostu nie wywalic? mamy swoją funkcję do wyciągania dependencies /** * Parses the contract source code and extracts the dendencies * @param source Contract source code * @return List of dependendencies */ -export function parseDependencies(contractSource: ContractSource): string[] { +// export function parseDependencies(contractSource: ContractSource): string[] { +export function parseDependencies(contractSource: ImportFile): string[] { // TODO: Use a proper parser const source = contractSource.source; const IMPORT_REGEX = /(import\s)/; @@ -107,7 +108,7 @@ export function parseDependencies(contractSource: ContractSource): string[] { if (!_.isNull(dependencyMatch)) { let dependencyPath = dependencyMatch[1]; if (dependencyPath.startsWith('.')) { - dependencyPath = path.join(path.dirname(contractSource.path), dependencyPath); + dependencyPath = path.join(path.dirname(contractSource.url), dependencyPath); // TODO squadack implicite zamieniłem path na absolutePath(url) } dependencies.push(dependencyPath); } @@ -168,7 +169,7 @@ function printCompilationErrorsAndWarnings(solcErrors: solc.SolcError[]): void { export async function getSourceTreeHash(resolver: ResolverEngine, importPath: string): Promise { const imFile: ImportFile = await resolver.require(importPath); const contractSource = { source: imFile.source, path: imFile.url, absolutePath: imFile.url }; - const dependencies = parseDependencies(contractSource); + const dependencies = parseDependencies(imFile); const sourceHash = ethUtil.sha3(contractSource.source); if (dependencies.length === 0) { return sourceHash; diff --git a/packages/sol-compiler/test/compiler_utils_test.ts b/packages/sol-compiler/test/compiler_utils_test.ts index b8c18110c0..0cddd998d4 100644 --- a/packages/sol-compiler/test/compiler_utils_test.ts +++ b/packages/sol-compiler/test/compiler_utils_test.ts @@ -52,7 +52,9 @@ describe('Compiler utils', () => { const source = await fsWrapper.readFileAsync(path, { encoding: 'utf8', }); - const dependencies = parseDependencies({ source, path, absolutePath: path }); + // const dependencies = parseDependencies({ source, path, absolutePath: path }); + // TODO squadack weryfikacja + const dependencies = parseDependencies({ source, url: path }); const expectedDependencies = [ 'zeppelin-solidity/contracts/token/ERC20/ERC20.sol', 'packages/sol-compiler/lib/test/fixtures/contracts/TokenTransferProxy.sol', @@ -68,7 +70,9 @@ describe('Compiler utils', () => { const source = await fsWrapper.readFileAsync(path, { encoding: 'utf8', }); - expect(parseDependencies({ source, path, absolutePath: path })).to.be.deep.equal([ + // TODO squadack weyfikacja + // expect(parseDependencies({ source, path, absolutePath: path })).to.be.deep.equal([ + expect(parseDependencies({ source, url: path })).to.be.deep.equal([ 'zeppelin-solidity/contracts/ownership/Ownable.sol', 'zeppelin-solidity/contracts/token/ERC20/ERC20.sol', ]); @@ -77,7 +81,9 @@ describe('Compiler utils', () => { it.skip('correctly parses commented out dependencies', async () => { const path = ''; const source = `// import "./TokenTransferProxy.sol";`; - expect(parseDependencies({ path, source, absolutePath: path })).to.be.deep.equal([]); + // TODO squadack weryfikacja + // expect(parseDependencies({ path, source, absolutePath: path })).to.be.deep.equal([]); + expect(parseDependencies({ source, url: path })).to.be.deep.equal([]); }); }); }); From b40f600111519c516b5d4bc6f1f243c8c1b9b518 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 07:54:17 -0500 Subject: [PATCH 05/15] changed resolver-engine imports --- packages/sol-compiler/src/compiler.ts | 9 +- packages/sol-compiler/src/utils/compiler.ts | 4 +- .../sol-compiler/src/utils/name_resolver.ts | 85 +------------------ 3 files changed, 10 insertions(+), 88 deletions(-) diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index d5c9eb911e..248ed495b7 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -7,7 +7,10 @@ import glob = require('glob'); import * as _ from 'lodash'; import * as path from 'path'; import * as pluralize from 'pluralize'; -import { gatherSources, ImportFile, ResolverEngine, SolidityImportResolver } from 'resolver-engine'; + +import { ResolverEngine } from '@resolver-engine/core'; +import { gatherSources, gatherSourcesAndCanonizeImports, ImportFile } from '@resolver-engine/imports'; +import { ImportsFsEngine } from '@resolver-engine/imports-fs'; import * as semver from 'semver'; import solc = require('solc'); @@ -98,7 +101,7 @@ export class Compiler { this._artifactsDir = passedOpts.artifactsDir || config.artifactsDir || DEFAULT_ARTIFACTS_DIR; this._specifiedContracts = passedOpts.contracts || config.contracts || ALL_CONTRACTS_IDENTIFIER; this._contractsDir = path.resolve(this._contractsDir); - this._resolver = SolidityImportResolver().addResolver(panoramix(this._contractsDir)); + this._resolver = ImportsFsEngine().addResolver(panoramix(this._contractsDir)); } /** * Compiles selected Solidity files found in `contractsDir` and writes JSON artifacts to `artifactsDir`. @@ -249,7 +252,7 @@ export class Compiler { }) with Solidity v${solcVersion}...`, ); - const depList = await gatherSources(input.contractsToCompile, process.cwd()); + const depList = await gatherSources(input.contractsToCompile, process.cwd(), this._resolver); for (const infile of depList) { input.standardInput.sources[infile.url] = { content: infile.source, diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index b2405c83b0..fd1eb4da5e 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -1,4 +1,6 @@ import { fetchAsync, logUtils } from '@0x/utils'; +import { ResolverEngine } from '@resolver-engine/core'; +import { ImportFile } from '@resolver-engine/imports'; import chalk from 'chalk'; import { ContractArtifact } from 'ethereum-types'; import * as ethUtil from 'ethereumjs-util'; @@ -12,7 +14,6 @@ import { binPaths } from '../solc/bin_paths'; import { constants } from './constants'; import { fsWrapper } from './fs_wrapper'; import { CompilationError } from './types'; -import { ImportFile, ResolverEngine } from 'resolver-engine'; /** * Gets contract data on network or returns if an artifact does not exist. @@ -263,6 +264,7 @@ async function recursivelyGatherDependencySources( if (_.isUndefined(sourcesToAppendTo[importPath])) { sourcesToAppendTo[importPath] = { id: fullSources[importPath].id }; + //TODO squadack rename sialala const sialala = await resolver.require(importPath); sourceCodesToAppendTo[importPath] = sialala.source; diff --git a/packages/sol-compiler/src/utils/name_resolver.ts b/packages/sol-compiler/src/utils/name_resolver.ts index c6b40dfa98..8fa6129ffd 100644 --- a/packages/sol-compiler/src/utils/name_resolver.ts +++ b/packages/sol-compiler/src/utils/name_resolver.ts @@ -1,13 +1,10 @@ import { promisify } from '@0x/utils'; +import { SubResolver } from '@resolver-engine/core'; import * as fs from 'fs'; import * as path from 'path'; import glob = require('glob'); -import { SubResolver } from 'resolver-engine'; -// import { ContractSource } from '../types'; - -// import { EnumerableResolver } from './enumerable_resolver'; const globAsync = promisify(glob); const SOLIDITY_FILE_EXTENSION = '.sol'; @@ -21,83 +18,3 @@ export function NameResolver(contractDir: string): SubResolver { return null; }; } - -// try { -// new Promise((resolve, reject) => { -// glob("**/*.sol", (err, matches) => { -// if (err) { -// return reject(err); -// } -// return resolve(matches); -// throw new Error("Dupa"); -// }) -// }).then(file => console.log(file)).catch(err => err); -// catch (err) { - -// } - -// await globAsync("**/*.sol"); - -// GlobResolver(uri): string[]; - -// NameResolver() { -// GlobResolver(con) -// } - -// export class NameResolver extends EnumerableResolver { -// private readonly _contractsDir: string; -// constructor(contractsDir: string) { -// super(); -// this._contractsDir = contractsDir; -// } -// public resolveIfExists(lookupContractName: string): ContractSource | undefined { -// let contractSource: ContractSource | undefined; -// const onFile = (filePath: string) => { -// const contractName = path.basename(filePath, SOLIDITY_FILE_EXTENSION); -// if (contractName === lookupContractName) { -// const absoluteContractPath = path.join(this._contractsDir, filePath); -// const source = fs.readFileSync(absoluteContractPath).toString(); -// contractSource = { source, path: filePath, absolutePath: absoluteContractPath }; -// return true; -// } -// return undefined; -// }; -// this._traverseContractsDir(this._contractsDir, onFile); -// return contractSource; -// } -// public getAll(): ContractSource[] { -// const contractSources: ContractSource[] = []; -// const onFile = (filePath: string) => { -// const absoluteContractPath = path.join(this._contractsDir, filePath); -// const source = fs.readFileSync(absoluteContractPath).toString(); -// const contractSource = { source, path: filePath, absolutePath: absoluteContractPath }; -// contractSources.push(contractSource); -// }; -// this._traverseContractsDir(this._contractsDir, onFile); -// return contractSources; -// } -// // tslint:disable-next-line:prefer-function-over-method -// private _traverseContractsDir(dirPath: string, onFile: (filePath: string) => true | void): boolean { -// let dirContents: string[] = []; -// try { -// dirContents = fs.readdirSync(dirPath); -// } catch (err) { -// throw new Error(`No directory found at ${dirPath}`); -// } -// for (const fileName of dirContents) { -// const absoluteEntryPath = path.join(dirPath, fileName); -// const isDirectory = fs.lstatSync(absoluteEntryPath).isDirectory(); -// const entryPath = path.relative(this._contractsDir, absoluteEntryPath); -// let isComplete; -// if (isDirectory) { -// isComplete = this._traverseContractsDir(absoluteEntryPath, onFile); -// } else if (fileName.endsWith(SOLIDITY_FILE_EXTENSION)) { -// isComplete = onFile(entryPath); -// } -// if (isComplete) { -// return isComplete; -// } -// } -// return false; -// } -// } From 7ce6334685987b981f6ada242804feaa76ce668b Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 09:58:52 -0500 Subject: [PATCH 06/15] added new SpyResolver that mimics behaviour of old one --- .../sol-compiler/src/utils/spy_resolver.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 packages/sol-compiler/src/utils/spy_resolver.ts diff --git a/packages/sol-compiler/src/utils/spy_resolver.ts b/packages/sol-compiler/src/utils/spy_resolver.ts new file mode 100644 index 0000000000..5b44c76d5d --- /dev/null +++ b/packages/sol-compiler/src/utils/spy_resolver.ts @@ -0,0 +1,18 @@ +import { ResolverEngine } from '@resolver-engine/core'; +import { ImportFile } from '@resolver-engine/imports'; + +export class SpyResolver extends ResolverEngine { + public resolvedContractSources: ImportFile[] = []; + private readonly _resolver: ResolverEngine; + + constructor(resolver: ResolverEngine) { + super(); + this._resolver = resolver; + } + + public async require(uri: string, workingDir?: string): Promise { + const resolvedFile = await this._resolver.require(uri, workingDir); + this.resolvedContractSources.push(resolvedFile); + return resolvedFile; + } +} From 9b840ba10eb5962720567b489576d848793a91cf Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 10:02:14 -0500 Subject: [PATCH 07/15] brought back watch (with new SpyResolver) --- packages/sol-compiler/src/compiler.ts | 49 ++++++++----------- packages/sol-compiler/src/utils/compiler.ts | 7 ++- .../sol-compiler/test/compiler_utils_test.ts | 6 +-- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index 248ed495b7..87afe65ad4 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -9,7 +9,7 @@ import * as path from 'path'; import * as pluralize from 'pluralize'; import { ResolverEngine } from '@resolver-engine/core'; -import { gatherSources, gatherSourcesAndCanonizeImports, ImportFile } from '@resolver-engine/imports'; +import { gatherSources, ImportFile } from '@resolver-engine/imports'; import { ImportsFsEngine } from '@resolver-engine/imports-fs'; import * as semver from 'semver'; import solc = require('solc'); @@ -28,8 +28,8 @@ import { } from './utils/compiler'; import { constants } from './utils/constants'; import { fsWrapper } from './utils/fs_wrapper'; -// TODO rename panoramix XD -import { NameResolver as panoramix } from './utils/name_resolver'; +import { NameResolver } from './utils/name_resolver'; +import { SpyResolver } from './utils/spy_resolver'; import { utils } from './utils/utils'; const globAsync = promisify(glob); @@ -101,7 +101,7 @@ export class Compiler { this._artifactsDir = passedOpts.artifactsDir || config.artifactsDir || DEFAULT_ARTIFACTS_DIR; this._specifiedContracts = passedOpts.contracts || config.contracts || ALL_CONTRACTS_IDENTIFIER; this._contractsDir = path.resolve(this._contractsDir); - this._resolver = ImportsFsEngine().addResolver(panoramix(this._contractsDir)); + this._resolver = ImportsFsEngine().addResolver(NameResolver(this._contractsDir)); } /** * Compiles selected Solidity files found in `contractsDir` and writes JSON artifacts to `artifactsDir`. @@ -145,7 +145,7 @@ export class Compiler { } } - const pathsToWatch = this._getPathsToWatch(); + const pathsToWatch = await this._getPathsToWatch(); watcher.add(pathsToWatch); }; await onFileChangedAsync(); @@ -158,22 +158,21 @@ export class Compiler { }); } - // TODO (squadack) przywrócić działanie - SpyResolver - private _getPathsToWatch(): string[] { - // const contractNames = this._getContractNamesToCompile(); - // const spyResolver = new SpyResolver(this._resolver); - // for (const contractName of contractNames) { - // const contractSource = spyResolver.resolve(contractName); - // // NOTE: We ignore the return value here. We don't want to compute the source tree hash. - // // We just want to call a SpyResolver on each contracts and it's dependencies and - // // this is a convenient way to reuse the existing code that does that. - // // We can then get all the relevant paths from the `spyResolver` below. - // getSourceTreeHash(spyResolver, contractSource.path); - // } - // const pathsToWatch = _.uniq(spyResolver.resolvedContractSources.map(cs => cs.absolutePath)); - // return pathsToWatch; - return []; + private async _getPathsToWatch(): Promise { + const contractNames = await this._getContractNamesToCompileAsync(); + const spyResolver = new SpyResolver(this._resolver); + for (const contractName of contractNames) { + const contractSource = await spyResolver.require(contractName); + // NOTE: We ignore the return value here. We don't want to compute the source tree hash. + // We just want to call a SpyResolver on each contracts and it's dependencies and + // this is a convenient way to reuse the existing code that does that. + // We can then get all the relevant paths from the `spyResolver` below. + getSourceTreeHash(spyResolver, contractSource.url); + } + const pathsToWatch: string[] = _.uniq(spyResolver.resolvedContractSources.map(cs => cs.url)); + return pathsToWatch; } + private async _getContractNamesToCompileAsync(): Promise { let contractNamesToCompile; if (this._specifiedContracts === ALL_CONTRACTS_IDENTIFIER) { @@ -202,14 +201,8 @@ export class Compiler { for (const contractName of contractNames) { const contractSource = await this._resolver.require(contractName); - // const oldContractSource = this._oldResolver.resolve(contractName); - // const contractSource: ImportFile = { - // source: oldContractSource.source, - // url: oldContractSource.absolutePath, - // }; - // TODO rename kek xD - const kek = await getSourceTreeHash(this._resolver, contractSource.url); - const sourceTreeHashHex = kek.toString('hex'); + const sourceTreeHash = await getSourceTreeHash(this._resolver, contractSource.url); + const sourceTreeHashHex = sourceTreeHash.toString('hex'); const contractData = { contractName, currentArtifactIfExists: await getContractArtifactIfExistsAsync(this._artifactsDir, contractName), diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index fd1eb4da5e..da76dca371 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -264,14 +264,13 @@ async function recursivelyGatherDependencySources( if (_.isUndefined(sourcesToAppendTo[importPath])) { sourcesToAppendTo[importPath] = { id: fullSources[importPath].id }; - //TODO squadack rename sialala - const sialala = await resolver.require(importPath); - sourceCodesToAppendTo[importPath] = sialala.source; + const importFile = await resolver.require(importPath); + sourceCodesToAppendTo[importPath] = importFile.source; await recursivelyGatherDependencySources( resolver, importPath, - sialala.source, + importFile.source, fullSources, sourcesToAppendTo, sourceCodesToAppendTo, diff --git a/packages/sol-compiler/test/compiler_utils_test.ts b/packages/sol-compiler/test/compiler_utils_test.ts index 0cddd998d4..740755944a 100644 --- a/packages/sol-compiler/test/compiler_utils_test.ts +++ b/packages/sol-compiler/test/compiler_utils_test.ts @@ -54,7 +54,7 @@ describe('Compiler utils', () => { }); // const dependencies = parseDependencies({ source, path, absolutePath: path }); // TODO squadack weryfikacja - const dependencies = parseDependencies({ source, url: path }); + const dependencies = parseDependencies({ source, url: path, provider: '' }); const expectedDependencies = [ 'zeppelin-solidity/contracts/token/ERC20/ERC20.sol', 'packages/sol-compiler/lib/test/fixtures/contracts/TokenTransferProxy.sol', @@ -72,7 +72,7 @@ describe('Compiler utils', () => { }); // TODO squadack weyfikacja // expect(parseDependencies({ source, path, absolutePath: path })).to.be.deep.equal([ - expect(parseDependencies({ source, url: path })).to.be.deep.equal([ + expect(parseDependencies({ source, url: path, provider: '' })).to.be.deep.equal([ 'zeppelin-solidity/contracts/ownership/Ownable.sol', 'zeppelin-solidity/contracts/token/ERC20/ERC20.sol', ]); @@ -83,7 +83,7 @@ describe('Compiler utils', () => { const source = `// import "./TokenTransferProxy.sol";`; // TODO squadack weryfikacja // expect(parseDependencies({ path, source, absolutePath: path })).to.be.deep.equal([]); - expect(parseDependencies({ source, url: path })).to.be.deep.equal([]); + expect(parseDependencies({ source, url: path, provider: '' })).to.be.deep.equal([]); }); }); }); From 84933a2464975d37f4b7530c4695d35d98cc9960 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 10:32:24 -0500 Subject: [PATCH 08/15] added resolver-engine to package.json --- packages/sol-compiler/package.json | 3 +++ yarn.lock | 34 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 37d98b4381..4d7df54b3d 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -75,6 +75,9 @@ "@0x/typescript-typings": "^3.0.8", "@0x/utils": "^3.0.1", "@0x/web3-wrapper": "^3.2.4", + "@resolver-engine/core": "^0.2.1", + "@resolver-engine/imports": "^0.2.2", + "@resolver-engine/imports-fs": "^0.2.2", "@types/yargs": "^11.0.0", "chalk": "^2.3.0", "chokidar": "^2.0.4", diff --git a/yarn.lock b/yarn.lock index b796d0e78a..cb9b540e90 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1265,6 +1265,40 @@ version "0.1.2" resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.1.2.tgz#72f547b5c9b0401a56de303d9e508abf6d3fa56a" +"@resolver-engine/core@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.2.1.tgz#0d71803f6d3b8cb2e9ed481a1bf0ca5f5256d0c0" + integrity sha512-nsLQHmPJ77QuifqsIvqjaF5B9aHnDzJjp73Q1z6apY3e9nqYrx4Dtowhpsf7Jwftg/XzVDEMQC+OzUBNTS+S1A== + dependencies: + debug "^3.1.0" + request "^2.85.0" + +"@resolver-engine/fs@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.2.1.tgz#f98a308d77568cc02651d03636f46536b941b241" + integrity sha512-7kJInM1Qo2LJcKyDhuYzh9ZWd+mal/fynfL9BNjWOiTcOpX+jNfqb/UmGUqros5pceBITlWGqS4lU709yHFUbg== + dependencies: + "@resolver-engine/core" "^0.2.1" + debug "^3.1.0" + +"@resolver-engine/imports-fs@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.2.2.tgz#5a81ef3285dbf0411ab3b15205080a1ad7622d9e" + integrity sha512-gFCgMvCwyppjwq0UzIjde/WI+yDs3oatJhozG9xdjJdewwtd7LiF0T5i9lrHAUtqrQbqoFE4E+ZMRVHWpWHpKQ== + dependencies: + "@resolver-engine/fs" "^0.2.1" + "@resolver-engine/imports" "^0.2.2" + debug "^3.1.0" + +"@resolver-engine/imports@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.2.2.tgz#d3de55a1bb5f3beb7703fdde743298f321175843" + integrity sha512-u5/HUkvo8q34AA+hnxxqqXGfby5swnH0Myw91o3Sm2TETJlNKXibFGSKBavAH+wvWdBi4Z5gS2Odu0PowgVOUg== + dependencies: + "@resolver-engine/core" "^0.2.1" + debug "^3.1.0" + hosted-git-info "^2.6.0" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" From d4b24994efb908d4084ca3b6f1f2d460e8aeb638 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 11:07:53 -0500 Subject: [PATCH 09/15] linter fixes --- packages/sol-compiler/src/compiler.ts | 16 ++++++++-------- packages/sol-compiler/src/utils/compiler.ts | 17 ++++++++++------- .../sol-compiler/src/utils/name_resolver.ts | 8 +++++--- packages/sol-compiler/src/utils/spy_resolver.ts | 1 + 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index 87afe65ad4..7b0034df9e 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -22,8 +22,8 @@ import { createDirIfDoesNotExistAsync, getContractArtifactIfExistsAsync, getSolcAsync, - getSourcesWithDependencies, - getSourceTreeHash, + getSourcesWithDependenciesAsync, + getSourceTreeHashAsync, parseSolidityVersionRange, } from './utils/compiler'; import { constants } from './utils/constants'; @@ -145,7 +145,7 @@ export class Compiler { } } - const pathsToWatch = await this._getPathsToWatch(); + const pathsToWatch = await this._getPathsToWatchAsync(); watcher.add(pathsToWatch); }; await onFileChangedAsync(); @@ -158,7 +158,7 @@ export class Compiler { }); } - private async _getPathsToWatch(): Promise { + private async _getPathsToWatchAsync(): Promise { const contractNames = await this._getContractNamesToCompileAsync(); const spyResolver = new SpyResolver(this._resolver); for (const contractName of contractNames) { @@ -167,7 +167,7 @@ export class Compiler { // We just want to call a SpyResolver on each contracts and it's dependencies and // this is a convenient way to reuse the existing code that does that. // We can then get all the relevant paths from the `spyResolver` below. - getSourceTreeHash(spyResolver, contractSource.url); + await getSourceTreeHashAsync(spyResolver, contractSource.url); } const pathsToWatch: string[] = _.uniq(spyResolver.resolvedContractSources.map(cs => cs.url)); return pathsToWatch; @@ -176,7 +176,7 @@ export class Compiler { private async _getContractNamesToCompileAsync(): Promise { let contractNamesToCompile; if (this._specifiedContracts === ALL_CONTRACTS_IDENTIFIER) { - const allContracts = await globAsync(this._contractsDir + '/**/*' + constants.SOLIDITY_FILE_EXTENSION); + const allContracts = await globAsync(`${this._contractsDir}/**/*${constants.SOLIDITY_FILE_EXTENSION}`); contractNamesToCompile = _.map(allContracts, contractSource => path.basename(contractSource, constants.SOLIDITY_FILE_EXTENSION), ); @@ -201,7 +201,7 @@ export class Compiler { for (const contractName of contractNames) { const contractSource = await this._resolver.require(contractName); - const sourceTreeHash = await getSourceTreeHash(this._resolver, contractSource.url); + const sourceTreeHash = await getSourceTreeHashAsync(this._resolver, contractSource.url); const sourceTreeHashHex = sourceTreeHash.toString('hex'); const contractData = { contractName, @@ -308,7 +308,7 @@ export class Compiler { // contains listings for every contract compiled during the compiler invocation that compiled the contract // to be persisted, which could include many that are irrelevant to the contract at hand. So, gather up only // the relevant sources: - const { sourceCodes, sources } = await getSourcesWithDependencies( + const { sourceCodes, sources } = await getSourcesWithDependenciesAsync( this._resolver, contractPath, compilerOutput.sources, diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index da76dca371..92d878b2fa 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -89,7 +89,7 @@ export function getNormalizedErrMsg(errMsg: string): string { return normalizedErrMsg; } -//TODO squadack - czy tego po prostu nie wywalic? mamy swoją funkcję do wyciągania dependencies +// TODO consider replacing parseDependencies() with resolver-engine's findImports() /** * Parses the contract source code and extracts the dendencies * @param source Contract source code @@ -167,7 +167,10 @@ function printCompilationErrorsAndWarnings(solcErrors: solc.SolcError[]): void { * Gets the source tree hash for a file and its dependencies. * @param fileName Name of contract file. */ -export async function getSourceTreeHash(resolver: ResolverEngine, importPath: string): Promise { +export async function getSourceTreeHashAsync( + resolver: ResolverEngine, + importPath: string, +): Promise { const imFile: ImportFile = await resolver.require(importPath); const contractSource = { source: imFile.source, path: imFile.url, absolutePath: imFile.url }; const dependencies = parseDependencies(imFile); @@ -176,7 +179,7 @@ export async function getSourceTreeHash(resolver: ResolverEngine, im return sourceHash; } else { const dependencySourceTreeHashes = await Promise.all( - _.map(dependencies, async (dependency: string) => getSourceTreeHash(resolver, dependency)), + _.map(dependencies, async (dependency: string) => getSourceTreeHashAsync(resolver, dependency)), ); const sourceTreeHashesBuffer = Buffer.concat([sourceHash, ...dependencySourceTreeHashes]); const sourceTreeHash = ethUtil.sha3(sourceTreeHashesBuffer); @@ -192,7 +195,7 @@ export async function getSourceTreeHash(resolver: ResolverEngine, im * taken from the corresponding ID's in @param fullSources, and the content for @return sourceCodes is read from * disk (via the aforementioned `resolver.source`). */ -export async function getSourcesWithDependencies( +export async function getSourcesWithDependenciesAsync( resolver: ResolverEngine, contractPath: string, fullSources: { [sourceName: string]: { id: number } }, @@ -200,7 +203,7 @@ export async function getSourcesWithDependencies( const sources = { [contractPath]: { id: fullSources[contractPath].id } }; const pamparampam = await resolver.require(contractPath); const sourceCodes = { [contractPath]: pamparampam.source }; - await recursivelyGatherDependencySources( + await recursivelyGatherDependencySourcesAsync( resolver, contractPath, sourceCodes[contractPath], @@ -211,7 +214,7 @@ export async function getSourcesWithDependencies( return { sourceCodes, sources }; } -async function recursivelyGatherDependencySources( +async function recursivelyGatherDependencySourcesAsync( resolver: ResolverEngine, contractPath: string, contractSource: string, @@ -267,7 +270,7 @@ async function recursivelyGatherDependencySources( const importFile = await resolver.require(importPath); sourceCodesToAppendTo[importPath] = importFile.source; - await recursivelyGatherDependencySources( + await recursivelyGatherDependencySourcesAsync( resolver, importPath, importFile.source, diff --git a/packages/sol-compiler/src/utils/name_resolver.ts b/packages/sol-compiler/src/utils/name_resolver.ts index 8fa6129ffd..682f5b44e1 100644 --- a/packages/sol-compiler/src/utils/name_resolver.ts +++ b/packages/sol-compiler/src/utils/name_resolver.ts @@ -1,7 +1,5 @@ import { promisify } from '@0x/utils'; import { SubResolver } from '@resolver-engine/core'; -import * as fs from 'fs'; -import * as path from 'path'; import glob = require('glob'); @@ -9,9 +7,13 @@ const globAsync = promisify(glob); const SOLIDITY_FILE_EXTENSION = '.sol'; +/** + * This resolver finds and returns (given only contract name) path to contract file in given directory. + */ + export function NameResolver(contractDir: string): SubResolver { return async (resolvePath: string) => { - const results = await globAsync(contractDir + '/**/' + resolvePath + SOLIDITY_FILE_EXTENSION); + const results = await globAsync(`${contractDir}/**/${resolvePath}${SOLIDITY_FILE_EXTENSION}`); if (results.length === 1) { return results[0]; } diff --git a/packages/sol-compiler/src/utils/spy_resolver.ts b/packages/sol-compiler/src/utils/spy_resolver.ts index 5b44c76d5d..238cbfd40e 100644 --- a/packages/sol-compiler/src/utils/spy_resolver.ts +++ b/packages/sol-compiler/src/utils/spy_resolver.ts @@ -10,6 +10,7 @@ export class SpyResolver extends ResolverEngine { this._resolver = resolver; } + // tslint:disable-next-line:async-suffix public async require(uri: string, workingDir?: string): Promise { const resolvedFile = await this._resolver.require(uri, workingDir); this.resolvedContractSources.push(resolvedFile); From 46a521094c8a625a38b86a76ef3c0708f804a2f2 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 11:23:57 -0500 Subject: [PATCH 10/15] removed old comments and fixed hack --- packages/sol-compiler/src/compiler.ts | 5 ----- packages/sol-compiler/src/utils/compiler.ts | 20 ++++++------------- .../sol-compiler/test/compiler_utils_test.ts | 6 ------ 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/packages/sol-compiler/src/compiler.ts b/packages/sol-compiler/src/compiler.ts index 7b0034df9e..329663ee9c 100644 --- a/packages/sol-compiler/src/compiler.ts +++ b/packages/sol-compiler/src/compiler.ts @@ -226,11 +226,6 @@ export class Compiler { contractsToCompile: [], }; } - // add input to the right version batch - // versionToInputs[solcVersion].standardInput.sources[contractSource.path] = { - // content: contractSource.source, - // }; - // versionToInputs[solcVersion].contractsToCompile.push(contractSource.path); versionToInputs[solcVersion].contractsToCompile.push(contractSource.url); } diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index 92d878b2fa..5bc98e63c0 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -95,7 +95,6 @@ export function getNormalizedErrMsg(errMsg: string): string { * @param source Contract source code * @return List of dependendencies */ -// export function parseDependencies(contractSource: ContractSource): string[] { export function parseDependencies(contractSource: ImportFile): string[] { // TODO: Use a proper parser const source = contractSource.source; @@ -120,20 +119,13 @@ export function parseDependencies(contractSource: ImportFile): string[] { /** * Compiles the contracts and prints errors/warnings - * @param resolver Resolver * @param solcInstance Instance of a solc compiler * @param standardInput Solidity standard JSON input */ -export function compile( - // resolver: Resolver, - solcInstance: solc.SolcInstance, - standardInput: solc.StandardInput, -): solc.StandardOutput { +export function compile(solcInstance: solc.SolcInstance, standardInput: solc.StandardInput): solc.StandardOutput { const standardInputStr = JSON.stringify(standardInput); const standardOutputStr = solcInstance.compileStandardWrapper(standardInputStr, importPath => { - // HACK(squadack) i don't want to use callback - // all sources should be resolved beforehand - throw Error('used callback'); + throw Error('Used callback. All sources should be resolved beforehand.'); }); const compiled: solc.StandardOutput = JSON.parse(standardOutputStr); if (!_.isUndefined(compiled.errors)) { @@ -257,10 +249,10 @@ async function recursivelyGatherDependencySourcesAsync( * And we need to append the base path for relative imports. */ importPath = path.resolve(`/${contractFolder}`, importPath); - // HACK(squadack) - // chcemy uciąć wiodący slash tylko jeśli jest to faktycznie ścieżka bezwględna - // TODO obejść to jakoś - if (!importPath.startsWith('/home')) { + + // NOTE we want to remove leading slash ONLY if the path to contract + // folder is not an absolute path (e.g. path to npm package) + if (!contractFolder.startsWith('/')) { importPath = importPath.replace('/', ''); } } diff --git a/packages/sol-compiler/test/compiler_utils_test.ts b/packages/sol-compiler/test/compiler_utils_test.ts index 740755944a..73b87458fd 100644 --- a/packages/sol-compiler/test/compiler_utils_test.ts +++ b/packages/sol-compiler/test/compiler_utils_test.ts @@ -52,8 +52,6 @@ describe('Compiler utils', () => { const source = await fsWrapper.readFileAsync(path, { encoding: 'utf8', }); - // const dependencies = parseDependencies({ source, path, absolutePath: path }); - // TODO squadack weryfikacja const dependencies = parseDependencies({ source, url: path, provider: '' }); const expectedDependencies = [ 'zeppelin-solidity/contracts/token/ERC20/ERC20.sol', @@ -70,8 +68,6 @@ describe('Compiler utils', () => { const source = await fsWrapper.readFileAsync(path, { encoding: 'utf8', }); - // TODO squadack weyfikacja - // expect(parseDependencies({ source, path, absolutePath: path })).to.be.deep.equal([ expect(parseDependencies({ source, url: path, provider: '' })).to.be.deep.equal([ 'zeppelin-solidity/contracts/ownership/Ownable.sol', 'zeppelin-solidity/contracts/token/ERC20/ERC20.sol', @@ -81,8 +77,6 @@ describe('Compiler utils', () => { it.skip('correctly parses commented out dependencies', async () => { const path = ''; const source = `// import "./TokenTransferProxy.sol";`; - // TODO squadack weryfikacja - // expect(parseDependencies({ path, source, absolutePath: path })).to.be.deep.equal([]); expect(parseDependencies({ source, url: path, provider: '' })).to.be.deep.equal([]); }); }); From 8e830f748af03664f964961422a5528e2c9ec674 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 11:52:50 -0500 Subject: [PATCH 11/15] removed useless comment --- packages/sol-compiler/src/utils/compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index 5bc98e63c0..f218087e00 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -108,7 +108,7 @@ export function parseDependencies(contractSource: ImportFile): string[] { if (!_.isNull(dependencyMatch)) { let dependencyPath = dependencyMatch[1]; if (dependencyPath.startsWith('.')) { - dependencyPath = path.join(path.dirname(contractSource.url), dependencyPath); // TODO squadack implicite zamieniłem path na absolutePath(url) + dependencyPath = path.join(path.dirname(contractSource.url), dependencyPath); } dependencies.push(dependencyPath); } From ecd8d2f65ce1c3aed227314eedae36a226b37a36 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 12:27:00 -0500 Subject: [PATCH 12/15] added new before Error --- packages/sol-compiler/src/utils/compiler.ts | 2 +- yarn.lock | 22 +++------------------ 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index f218087e00..283c1744f5 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -125,7 +125,7 @@ export function parseDependencies(contractSource: ImportFile): string[] { export function compile(solcInstance: solc.SolcInstance, standardInput: solc.StandardInput): solc.StandardOutput { const standardInputStr = JSON.stringify(standardInput); const standardOutputStr = solcInstance.compileStandardWrapper(standardInputStr, importPath => { - throw Error('Used callback. All sources should be resolved beforehand.'); + throw new Error('Used callback. All sources should be resolved beforehand.'); }); const compiled: solc.StandardOutput = JSON.parse(standardOutputStr); if (!_.isUndefined(compiled.errors)) { diff --git a/yarn.lock b/yarn.lock index cb9b540e90..1280d970aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7995,21 +7995,10 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" - integrity sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg= - dependencies: - natives "^1.1.0" - -graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@4.1.15, graceful-fs@^3.0.0, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@~1.2.0: version "4.1.15" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - -graceful-fs@~1.2.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" - integrity sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q= + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== "graceful-readlink@>= 1.0.0": version "1.0.1" @@ -11470,11 +11459,6 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -natives@^1.1.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.6.tgz#a603b4a498ab77173612b9ea1acdec4d980f00bb" - integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" From f0a1268c677c24e77ed16eb5c789a9e782895ccb Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 12:33:50 -0500 Subject: [PATCH 13/15] small fixes --- packages/sol-compiler/src/utils/compiler.ts | 7 +++---- packages/sol-compiler/src/utils/name_resolver.ts | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/sol-compiler/src/utils/compiler.ts b/packages/sol-compiler/src/utils/compiler.ts index 283c1744f5..782fada83f 100644 --- a/packages/sol-compiler/src/utils/compiler.ts +++ b/packages/sol-compiler/src/utils/compiler.ts @@ -163,10 +163,9 @@ export async function getSourceTreeHashAsync( resolver: ResolverEngine, importPath: string, ): Promise { - const imFile: ImportFile = await resolver.require(importPath); - const contractSource = { source: imFile.source, path: imFile.url, absolutePath: imFile.url }; - const dependencies = parseDependencies(imFile); - const sourceHash = ethUtil.sha3(contractSource.source); + const importFile: ImportFile = await resolver.require(importPath); + const dependencies = parseDependencies(importFile); + const sourceHash = ethUtil.sha3(importFile.source); if (dependencies.length === 0) { return sourceHash; } else { diff --git a/packages/sol-compiler/src/utils/name_resolver.ts b/packages/sol-compiler/src/utils/name_resolver.ts index 682f5b44e1..7aae7e0037 100644 --- a/packages/sol-compiler/src/utils/name_resolver.ts +++ b/packages/sol-compiler/src/utils/name_resolver.ts @@ -10,7 +10,6 @@ const SOLIDITY_FILE_EXTENSION = '.sol'; /** * This resolver finds and returns (given only contract name) path to contract file in given directory. */ - export function NameResolver(contractDir: string): SubResolver { return async (resolvePath: string) => { const results = await globAsync(`${contractDir}/**/${resolvePath}${SOLIDITY_FILE_EXTENSION}`); From 3364373116ddc597931bb02d8b50556f847c72f8 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 12:36:21 -0500 Subject: [PATCH 14/15] bumped resolver-engine to 0.3.0 --- packages/sol-compiler/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 4d7df54b3d..812eecd82a 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -75,9 +75,9 @@ "@0x/typescript-typings": "^3.0.8", "@0x/utils": "^3.0.1", "@0x/web3-wrapper": "^3.2.4", - "@resolver-engine/core": "^0.2.1", - "@resolver-engine/imports": "^0.2.2", - "@resolver-engine/imports-fs": "^0.2.2", + "@resolver-engine/core": "^0.3.0", + "@resolver-engine/imports": "^0.3.0", + "@resolver-engine/imports-fs": "^0.3.0", "@types/yargs": "^11.0.0", "chalk": "^2.3.0", "chokidar": "^2.0.4", From 6ed32797114b797e0eb86762b9f16d86a81715b5 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamek Date: Thu, 31 Jan 2019 14:49:02 -0500 Subject: [PATCH 15/15] changelog --- packages/sol-compiler/CHANGELOG.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/sol-compiler/CHANGELOG.json b/packages/sol-compiler/CHANGELOG.json index 672939a4a6..15dea001d4 100644 --- a/packages/sol-compiler/CHANGELOG.json +++ b/packages/sol-compiler/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "3.1.0", + "changes": [ + { + "note": "replaced sol-resolver with resolver-engine" + } + ] + }, { "version": "3.0.0", "changes": [