aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorperissology <perissology@protonmail.com>2018-06-15 02:17:04 +0800
committerperissology <perissology@protonmail.com>2018-06-15 02:17:04 +0800
commit7a41a5249fcb8457cb8beb823ce9a1362cdbfa98 (patch)
treeb7f03fab37dde2f652984c9aef486bde23f560d6
parent0e354e5ea1f9951088331a310999bf87c8f8f4b3 (diff)
downloaddexon-sol-tools-7a41a5249fcb8457cb8beb823ce9a1362cdbfa98.tar
dexon-sol-tools-7a41a5249fcb8457cb8beb823ce9a1362cdbfa98.tar.gz
dexon-sol-tools-7a41a5249fcb8457cb8beb823ce9a1362cdbfa98.tar.bz2
dexon-sol-tools-7a41a5249fcb8457cb8beb823ce9a1362cdbfa98.tar.lz
dexon-sol-tools-7a41a5249fcb8457cb8beb823ce9a1362cdbfa98.tar.xz
dexon-sol-tools-7a41a5249fcb8457cb8beb823ce9a1362cdbfa98.tar.zst
dexon-sol-tools-7a41a5249fcb8457cb8beb823ce9a1362cdbfa98.zip
Collect coverage for provided sources
When solidity generates source maps during contract compilation, the contracts are referred to by an id, which corresponds to an array index. We may not want to cover all sources that were included in a compilation, but because we use array indexes (vs. the id that is provided by solidity compiler) to map the contract to the sourceMap, the provided sourceCodes array must include the code at the correct index. This can result in empty slots in the sourceCodes array. This commit allows the coverage to only be collected for the contracts with provided sourceCode.
-rw-r--r--packages/sol-cov/src/collect_coverage_entries.ts2
-rw-r--r--packages/sol-cov/src/coverage_subprovider.ts6
-rw-r--r--packages/sol-cov/src/source_maps.ts5
3 files changed, 11 insertions, 2 deletions
diff --git a/packages/sol-cov/src/collect_coverage_entries.ts b/packages/sol-cov/src/collect_coverage_entries.ts
index b145f044e..3fc85008c 100644
--- a/packages/sol-cov/src/collect_coverage_entries.ts
+++ b/packages/sol-cov/src/collect_coverage_entries.ts
@@ -10,7 +10,7 @@ const coverageEntriesBySourceHash: { [sourceHash: string]: CoverageEntriesDescri
export const collectCoverageEntries = (contractSource: string) => {
const sourceHash = ethUtil.sha3(contractSource).toString('hex');
- if (_.isUndefined(coverageEntriesBySourceHash[sourceHash])) {
+ if (_.isUndefined(coverageEntriesBySourceHash[sourceHash]) && !_.isUndefined(contractSource)) {
const ast = parser.parse(contractSource, { range: true });
const locationByOffset = getLocationByOffset(contractSource);
const visitor = new ASTVisitor(locationByOffset);
diff --git a/packages/sol-cov/src/coverage_subprovider.ts b/packages/sol-cov/src/coverage_subprovider.ts
index 0fa7f873e..2f0bcbb93 100644
--- a/packages/sol-cov/src/coverage_subprovider.ts
+++ b/packages/sol-cov/src/coverage_subprovider.ts
@@ -66,6 +66,12 @@ export const coverageHandler: SingleFileSubtraceHandler = (
): Coverage => {
const absoluteFileName = contractData.sources[fileIndex];
const coverageEntriesDescription = collectCoverageEntries(contractData.sourceCodes[fileIndex]);
+
+ // if the source wasn't provided for the fileIndex, we can't cover the file
+ if (_.isUndefined(coverageEntriesDescription)) {
+ return {};
+ }
+
let sourceRanges = _.map(subtrace, structLog => pcToSourceRange[structLog.pc]);
sourceRanges = _.compact(sourceRanges); // Some PC's don't map to a source range and we just ignore them.
// By default lodash does a shallow object comparasion. We JSON.stringify them and compare as strings.
diff --git a/packages/sol-cov/src/source_maps.ts b/packages/sol-cov/src/source_maps.ts
index f9503e16c..c95c7d2b0 100644
--- a/packages/sol-cov/src/source_maps.ts
+++ b/packages/sol-cov/src/source_maps.ts
@@ -12,6 +12,9 @@ export interface SourceLocation {
}
export function getLocationByOffset(str: string): LocationByOffset {
+ if (_.isUndefined(str)) {
+ return {};
+ }
const locationByOffset: LocationByOffset = { 0: { line: 1, column: 0 } };
let currentOffset = 0;
for (const char of str.split('')) {
@@ -56,7 +59,7 @@ export function parseSourceMap(
length,
fileIndex,
};
- if (parsedEntry.fileIndex !== -1) {
+ if (parsedEntry.fileIndex !== -1 && !_.isUndefined(locationByOffsetByFileIndex[parsedEntry.fileIndex])) {
const sourceRange = {
location: {
start: locationByOffsetByFileIndex[parsedEntry.fileIndex][parsedEntry.offset],