diff options
author | Leonid Logvinov <logvinov.leon@gmail.com> | 2019-01-15 21:45:02 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-15 21:45:02 +0800 |
commit | 18084588ea9fa724d6e32c9a49c79d49f189ba7c (patch) | |
tree | 7944152430a9687e7e63db4011bacaf2fa3aebe3 /packages/sol-tracing-utils/src/source_maps.ts | |
parent | 16a2cf7be68605def2824de4f5c22f0154c2e6ad (diff) | |
parent | 64d99dc07cc82c7cc2917871596b46985f1d709f (diff) | |
download | dexon-0x-contracts-18084588ea9fa724d6e32c9a49c79d49f189ba7c.tar dexon-0x-contracts-18084588ea9fa724d6e32c9a49c79d49f189ba7c.tar.gz dexon-0x-contracts-18084588ea9fa724d6e32c9a49c79d49f189ba7c.tar.bz2 dexon-0x-contracts-18084588ea9fa724d6e32c9a49c79d49f189ba7c.tar.lz dexon-0x-contracts-18084588ea9fa724d6e32c9a49c79d49f189ba7c.tar.xz dexon-0x-contracts-18084588ea9fa724d6e32c9a49c79d49f189ba7c.tar.zst dexon-0x-contracts-18084588ea9fa724d6e32c9a49c79d49f189ba7c.zip |
Merge pull request #1498 from 0xProject/fix/sol-cov
Sol tracing fixes
Diffstat (limited to 'packages/sol-tracing-utils/src/source_maps.ts')
-rw-r--r-- | packages/sol-tracing-utils/src/source_maps.ts | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/packages/sol-tracing-utils/src/source_maps.ts b/packages/sol-tracing-utils/src/source_maps.ts index af0fb4035..8c17652d9 100644 --- a/packages/sol-tracing-utils/src/source_maps.ts +++ b/packages/sol-tracing-utils/src/source_maps.ts @@ -1,7 +1,7 @@ import * as _ from 'lodash'; import { getPcToInstructionIndexMapping } from './instructions'; -import { LocationByOffset, SourceRange } from './types'; +import { OffsetToLocation, SourceCodes, SourceRange, Sources } from './types'; const RADIX = 10; @@ -15,38 +15,41 @@ export interface SourceLocation { * Receives a string with newlines and returns a map of byte offset to LineColumn * @param str A string to process */ -export function getLocationByOffset(str: string): LocationByOffset { - const locationByOffset: LocationByOffset = { 0: { line: 1, column: 0 } }; +export function getOffsetToLocation(str: string): OffsetToLocation { + const offsetToLocation: OffsetToLocation = { 0: { line: 1, column: 0 } }; let currentOffset = 0; for (const char of str.split('')) { - const location = locationByOffset[currentOffset]; + const location = offsetToLocation[currentOffset]; const isNewline = char === '\n'; - locationByOffset[currentOffset + 1] = { + offsetToLocation[currentOffset + 1] = { line: location.line + (isNewline ? 1 : 0), column: isNewline ? 0 : location.column + 1, }; currentOffset++; } - return locationByOffset; + return offsetToLocation; } /** * Parses a sourcemap string. * The solidity sourcemap format is documented here: https://github.com/ethereum/solidity/blob/develop/docs/miscellaneous.rst#source-mappings - * @param sourceCodes sources contents + * @param indexToSourceCode index to source code * @param srcMap source map string * @param bytecodeHex contract bytecode - * @param sources sources file names + * @param indexToSource index to source file path */ export function parseSourceMap( - sourceCodes: string[], + sourceCodes: SourceCodes, srcMap: string, bytecodeHex: string, - sources: string[], + sources: Sources, ): { [programCounter: number]: SourceRange } { const bytecode = Uint8Array.from(Buffer.from(bytecodeHex, 'hex')); const pcToInstructionIndex: { [programCounter: number]: number } = getPcToInstructionIndexMapping(bytecode); - const locationByOffsetByFileIndex = _.map(sourceCodes, s => (_.isUndefined(s) ? {} : getLocationByOffset(s))); + const fileIndexToOffsetToLocation: { [fileIndex: number]: OffsetToLocation } = {}; + _.map(sourceCodes, (sourceCode: string, fileIndex: number) => { + fileIndexToOffsetToLocation[fileIndex] = _.isUndefined(sourceCode) ? {} : getOffsetToLocation(sourceCode); + }); const entries = srcMap.split(';'); let lastParsedEntry: SourceLocation = {} as any; const instructionIndexToSourceRange: { [instructionIndex: number]: SourceRange } = {}; @@ -66,14 +69,18 @@ export function parseSourceMap( length, fileIndex, }; - if (parsedEntry.fileIndex !== -1 && !_.isUndefined(locationByOffsetByFileIndex[parsedEntry.fileIndex])) { + if (parsedEntry.fileIndex !== -1 && !_.isUndefined(fileIndexToOffsetToLocation[parsedEntry.fileIndex])) { + const offsetToLocation = fileIndexToOffsetToLocation[parsedEntry.fileIndex]; const sourceRange = { location: { - start: locationByOffsetByFileIndex[parsedEntry.fileIndex][parsedEntry.offset], - end: locationByOffsetByFileIndex[parsedEntry.fileIndex][parsedEntry.offset + parsedEntry.length], + start: offsetToLocation[parsedEntry.offset], + end: offsetToLocation[parsedEntry.offset + parsedEntry.length], }, fileName: sources[parsedEntry.fileIndex], }; + if (sourceRange.location.start === undefined || sourceRange.location.end === undefined) { + throw new Error(`Error while processing sourcemap: location out of range in ${sourceRange.fileName}`); + } instructionIndexToSourceRange[i] = sourceRange; } else { // Some assembly code generated by Solidity can't be mapped back to a line of source code. |