commit
5f5c4c7ce3
@ -0,0 +1,119 @@ |
|||||||
|
'use strict' |
||||||
|
var util = require('../helpers/util') |
||||||
|
|
||||||
|
/** |
||||||
|
* Decompress the source mapping given by solc-bin.js |
||||||
|
*/ |
||||||
|
function SourceMappingDecoder () { |
||||||
|
// s:l:f:j
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Decode the source mapping for the given @arg index |
||||||
|
* |
||||||
|
* @param {Integer} index - source mapping index to decode |
||||||
|
* @param {String} mapping - compressed source mapping given by solc-bin |
||||||
|
* @return {Object} returns the decompressed source mapping for the given index {start, length, file, jump} |
||||||
|
*/ |
||||||
|
SourceMappingDecoder.prototype.atIndex = function (index, mapping) { |
||||||
|
var ret = {} |
||||||
|
var map = mapping.split(';') |
||||||
|
if (index >= map.length) { |
||||||
|
index = map.length - 1 |
||||||
|
} |
||||||
|
for (var k = index; k >= 0; k--) { |
||||||
|
var current = map[k] |
||||||
|
if (!current.length) { |
||||||
|
continue |
||||||
|
} |
||||||
|
current = current.split(':') |
||||||
|
if (ret.start === undefined && current[0] && current[0].length) { |
||||||
|
ret.start = parseInt(current[0]) |
||||||
|
} |
||||||
|
if (ret.length === undefined && current[1] && current[1].length) { |
||||||
|
ret.length = parseInt(current[1]) |
||||||
|
} |
||||||
|
if (ret.file === undefined && current[2] && current[2].length) { |
||||||
|
ret.file = parseInt(current[2]) |
||||||
|
} |
||||||
|
if (ret.jump === undefined && current[3] && current[3].length) { |
||||||
|
ret.jump = current[3] |
||||||
|
} |
||||||
|
if (ret.start !== undefined && ret.length !== undefined && ret.file !== undefined && ret.jump !== undefined) { |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
return ret |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Decode the source mapping for the given compressed mapping |
||||||
|
* |
||||||
|
* @param {String} mapping - compressed source mapping given by solc-bin |
||||||
|
* @return {Array} returns the decompressed source mapping. Array of {start, length, file, jump} |
||||||
|
*/ |
||||||
|
SourceMappingDecoder.prototype.decompressAll = function (mapping) { |
||||||
|
var map = mapping.split(';') |
||||||
|
var ret = [] |
||||||
|
for (var k in map) { |
||||||
|
var compressed = map[k].split(':') |
||||||
|
var sourceMap = { |
||||||
|
start: compressed[0] ? parseInt(compressed[0]) : ret[ret.length - 1].start, |
||||||
|
length: compressed[1] ? parseInt(compressed[1]) : ret[ret.length - 1].length, |
||||||
|
file: compressed[2] ? parseInt(compressed[2]) : ret[ret.length - 1].file, |
||||||
|
jump: compressed[3] ? compressed[3] : ret[ret.length - 1].jump |
||||||
|
} |
||||||
|
ret.push(sourceMap) |
||||||
|
} |
||||||
|
return ret |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieve line/column position of each source char |
||||||
|
* |
||||||
|
* @param {String} source - contract source code |
||||||
|
* @return {Arrray} returns an array containing offset of line breaks |
||||||
|
*/ |
||||||
|
SourceMappingDecoder.prototype.getLinebreakPositions = function (source) { |
||||||
|
var ret = [] |
||||||
|
for (var pos = source.indexOf('\n'); pos >= 0; pos = source.indexOf('\n', pos + 1)) { |
||||||
|
ret.push(pos) |
||||||
|
} |
||||||
|
return ret |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieve the line/colum position for the given source mapping |
||||||
|
* |
||||||
|
* @param {Object} sourceLocation - object containing attributes {source} and {length} |
||||||
|
* @param {Array} lineBreakPositions - array returned by the function 'getLinebreakPositions' |
||||||
|
* @return {Object} returns an object {start: {line, column}, end: {line, column}} (line/column count start at 0) |
||||||
|
*/ |
||||||
|
SourceMappingDecoder.prototype.convertOffsetToLineColumn = function (sourceLocation, lineBreakPositions) { |
||||||
|
if (sourceLocation.start >= 0 && sourceLocation.length >= 0) { |
||||||
|
return { |
||||||
|
start: convertFromCharPosition(sourceLocation.start, lineBreakPositions), |
||||||
|
end: convertFromCharPosition(sourceLocation.start + sourceLocation.length, lineBreakPositions) |
||||||
|
} |
||||||
|
} else { |
||||||
|
return { |
||||||
|
start: null, |
||||||
|
end: null |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function convertFromCharPosition (pos, lineBreakPositions) { |
||||||
|
var line = util.findLowerBound(pos, lineBreakPositions) |
||||||
|
if (lineBreakPositions[line] !== pos) { |
||||||
|
line = line + 1 |
||||||
|
} |
||||||
|
var beginColumn = line === 0 ? 0 : (lineBreakPositions[line - 1] + 1) |
||||||
|
var column = pos - beginColumn |
||||||
|
return { |
||||||
|
line: line, |
||||||
|
column: column |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = SourceMappingDecoder |
@ -0,0 +1,22 @@ |
|||||||
|
var sourceRuntimeMapping = {} |
||||||
|
sourceRuntimeMapping.mapping = '0:205:4:-;;;;;;;;;;;;;;;;;;;;;;55:74;;;;;;;;;;;;;;;;;;;;;;;;;;142:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55:74;103:2;99:1;;:6;;;;;120:2;116:1;;:6;;;;;55:74;;;:::o;142:61::-;166:6;174;142:61;;;:::o' |
||||||
|
sourceRuntimeMapping.source = `contract test {
|
||||||
|
int x;
|
||||||
|
|
||||||
|
int y;
|
||||||
|
|
||||||
|
function set(int _x, int _y)
|
||||||
|
{ |
||||||
|
x = _x;
|
||||||
|
y = _y; |
||||||
|
}
|
||||||
|
|
||||||
|
function get() returns (uint x, uint y)
|
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
}` |
||||||
|
|
||||||
|
if (typeof (module) !== 'undefined' && typeof (module.exports) !== 'undefined') { |
||||||
|
module.exports = sourceRuntimeMapping |
||||||
|
} |
@ -0,0 +1,118 @@ |
|||||||
|
'use strict' |
||||||
|
var sourceMapping = require('./resources/sourceMapping') |
||||||
|
var index = require('../src/index') |
||||||
|
var tape = require('tape') |
||||||
|
var util = require('../src/helpers/util') |
||||||
|
|
||||||
|
tape('Util', function (t) { |
||||||
|
t.test('lowerbound', function (st) { |
||||||
|
st.plan(7) |
||||||
|
var array = [2, 5, 8, 9, 45, 56, 78] |
||||||
|
var lowerBound = util.findLowerBound(10, array) |
||||||
|
st.equal(lowerBound, 3) |
||||||
|
|
||||||
|
lowerBound = util.findLowerBound(3, array) |
||||||
|
st.equal(lowerBound, 0) |
||||||
|
|
||||||
|
lowerBound = util.findLowerBound(100, array) |
||||||
|
st.equal(lowerBound, 6) |
||||||
|
|
||||||
|
lowerBound = util.findLowerBound(1, array) |
||||||
|
st.equal(lowerBound, -1) |
||||||
|
|
||||||
|
lowerBound = util.findLowerBound(45, array) |
||||||
|
st.equal(lowerBound, 4) |
||||||
|
|
||||||
|
array = [2, 5, 8, 9, 9, 45, 56, 78] |
||||||
|
lowerBound = util.findLowerBound(9, array) |
||||||
|
st.equal(lowerBound, 4) |
||||||
|
|
||||||
|
lowerBound = util.findLowerBound(9, []) |
||||||
|
st.equal(lowerBound, -1) |
||||||
|
}) |
||||||
|
|
||||||
|
var testSourceMapping = {} |
||||||
|
t.test('sourceMappingDecoder', function (st) { |
||||||
|
st.plan(28) |
||||||
|
var sourceMappingDecoder = new index.util.SourceMappingDecoder() |
||||||
|
console.log('test decompressAll') |
||||||
|
var result = sourceMappingDecoder.decompressAll(sourceMapping.mapping) |
||||||
|
st.equal(result[0].start, 0) |
||||||
|
st.equal(result[0].length, 205) |
||||||
|
st.equal(result[0].file, 4) |
||||||
|
st.equal(result[0].jump, '-') |
||||||
|
|
||||||
|
st.equal(result[21].start, 0) |
||||||
|
st.equal(result[21].length, 205) |
||||||
|
st.equal(result[21].file, 4) |
||||||
|
st.equal(result[21].jump, '-') |
||||||
|
testSourceMapping[21] = result[21] |
||||||
|
|
||||||
|
st.equal(result[22].start, 55) |
||||||
|
st.equal(result[22].length, 74) |
||||||
|
st.equal(result[22].file, 4) |
||||||
|
st.equal(result[22].jump, '-') |
||||||
|
|
||||||
|
var last = result.length - 1 |
||||||
|
st.equal(result[last].start, 142) |
||||||
|
st.equal(result[last].length, 61) |
||||||
|
st.equal(result[last].file, 4) |
||||||
|
st.equal(result[last].jump, 'o') |
||||||
|
testSourceMapping['last'] = result[last] |
||||||
|
|
||||||
|
console.log('test decompress') |
||||||
|
result = sourceMappingDecoder.atIndex(22, sourceMapping.mapping) |
||||||
|
console.log(result) |
||||||
|
st.equal(result.start, 55) |
||||||
|
st.equal(result.length, 74) |
||||||
|
st.equal(result.file, 4) |
||||||
|
st.equal(result.jump, '-') |
||||||
|
testSourceMapping[22] = result |
||||||
|
|
||||||
|
result = sourceMappingDecoder.atIndex(82, sourceMapping.mapping) |
||||||
|
console.log(result) |
||||||
|
st.equal(result.start, 103) |
||||||
|
st.equal(result.length, 2) |
||||||
|
st.equal(result.file, 4) |
||||||
|
st.equal(result.jump, '-') |
||||||
|
testSourceMapping[82] = result |
||||||
|
|
||||||
|
result = sourceMappingDecoder.atIndex(85, sourceMapping.mapping) |
||||||
|
console.log(result) |
||||||
|
st.equal(result.start, 99) |
||||||
|
st.equal(result.length, 6) |
||||||
|
st.equal(result.file, 4) |
||||||
|
st.equal(result.jump, '-') |
||||||
|
testSourceMapping[85] = result |
||||||
|
}) |
||||||
|
|
||||||
|
t.test('sourceMappingLineColumnConverter', function (st) { |
||||||
|
st.plan(14) |
||||||
|
var sourceMappingDecoder = new index.util.SourceMappingDecoder() |
||||||
|
var linesbreak = sourceMappingDecoder.getLinebreakPositions(sourceMapping.source) |
||||||
|
st.equal(linesbreak[0], 16) |
||||||
|
st.equal(linesbreak[5], 84) |
||||||
|
var result = sourceMappingDecoder.convertOffsetToLineColumn(testSourceMapping[21], linesbreak) |
||||||
|
st.equal(result.start.line, 0) |
||||||
|
st.equal(result.start.column, 0) |
||||||
|
st.equal(result.end.line, 15) |
||||||
|
st.equal(result.end.column, 1) |
||||||
|
result = sourceMappingDecoder.convertOffsetToLineColumn(testSourceMapping[82], linesbreak) |
||||||
|
st.equal(result.start.line, 7) |
||||||
|
st.equal(result.start.column, 12) |
||||||
|
st.equal(result.end.line, 7) |
||||||
|
st.equal(result.end.column, 14) |
||||||
|
|
||||||
|
var res = { // point to \n
|
||||||
|
start: 103, |
||||||
|
length: 4, |
||||||
|
file: 4, |
||||||
|
jump: '-' |
||||||
|
} |
||||||
|
result = sourceMappingDecoder.convertOffsetToLineColumn(res, linesbreak) |
||||||
|
st.equal(result.start.line, 7) |
||||||
|
st.equal(result.start.column, 12) |
||||||
|
st.equal(result.end.line, 7) |
||||||
|
st.equal(result.end.column, 16) |
||||||
|
}) |
||||||
|
}) |
Loading…
Reference in new issue