change findlowerbound behavior

pull/7/head
yann300 9 years ago
parent 030ac5e8d7
commit 2c39b5f7df
  1. 41
      src/helpers/util.js
  2. 17
      src/util/sourceMappingDecoder.js
  3. 119
      test/util.js

@ -44,32 +44,31 @@ module.exports = {
/* /*
Binary Search: Binary Search:
Assumes that @arg array is sorted increasingly Assumes that @arg array is sorted increasingly
return smallest i such that changes[i] <= target does not hold, return largest i such that array[i] <= target; return -1 if array[0] > target || array is empty
or changes.length if all elements are < target.
It returns the index where target could be inserted to maintain the order of the array
*/ */
findLowerBound: function (target, array) { findLowerBound: function (target, array) {
return findLowerBoundInternal(target, array, 0, array.length) var start = 0
}, var length = array.length
while (length > 0) {
findLowerBoundValue: function (target, array) {
var index = this.findLowerBound(target, array)
return array[index]
}
}
function findLowerBoundInternal (target, array, lowerbound, length) {
while (length > 1) {
var half = length >> 1 var half = length >> 1
var middle = lowerbound + half var middle = start + half
if (array[middle] < target) { if (array[middle] <= target) {
length = length - (middle - lowerbound) length = length - 1 - half
lowerbound = middle start = middle + 1
} else if (array[middle] === target) {
return middle
} else { } else {
length = half length = half
} }
} }
return lowerbound return start - 1
},
/*
Binary Search:
Assumes that @arg array is sorted increasingly
return largest array[i] such that array[i] <= target; return null if array[0] > target || array is empty
*/
findLowerBoundValue: function (target, array) {
var index = this.findLowerBound(target, array)
return index >= 0 ? array[index] : null
}
} }

@ -18,6 +18,9 @@ function SourceMappingDecoder () {
SourceMappingDecoder.prototype.atIndex = function (index, mapping) { SourceMappingDecoder.prototype.atIndex = function (index, mapping) {
var ret = {} var ret = {}
var map = mapping.split(';') var map = mapping.split(';')
if (index >= map.length) {
index = map.length - 1
}
for (var k = index; k >= 0; k--) { for (var k = index; k >= 0; k--) {
var current = map[k] var current = map[k]
if (!current.length) { if (!current.length) {
@ -84,7 +87,7 @@ SourceMappingDecoder.prototype.getLinebreakPositions = function (source) {
* *
* @param {Object} sourceLocation - object containing attributes {source} and {length} * @param {Object} sourceLocation - object containing attributes {source} and {length}
* @param {Array} lineBreakPositions - array returned by the function 'getLinebreakPositions' * @param {Array} lineBreakPositions - array returned by the function 'getLinebreakPositions'
* @@return {Object} returns an object {start: {line, column}, end: {line, column}} (line count start at 0) * @return {Object} returns an object {start: {line, column}, end: {line, column}} (line/column count start at 0)
*/ */
SourceMappingDecoder.prototype.convertOffsetToLineColumn = function (sourceLocation, lineBreakPositions) { SourceMappingDecoder.prototype.convertOffsetToLineColumn = function (sourceLocation, lineBreakPositions) {
if (sourceLocation.start >= 0 && sourceLocation.length >= 0) { if (sourceLocation.start >= 0 && sourceLocation.length >= 0) {
@ -94,21 +97,19 @@ SourceMappingDecoder.prototype.convertOffsetToLineColumn = function (sourceLocat
} }
} else { } else {
return { return {
start: -1, start: null,
end: -1 end: null
} }
} }
} }
function convertFromCharPosition (pos, lineBreakPositions) { function convertFromCharPosition (pos, lineBreakPositions) {
var line = util.findLowerBound(pos, lineBreakPositions) var line = util.findLowerBound(pos, lineBreakPositions)
if (lineBreakPositions[line] !== pos) {
if (lineBreakPositions[line] < pos) {
line = line + 1 line = line + 1
} }
var beginColumn = line === 0 ? 0 : (lineBreakPositions[line - 1] + 1)
var column = lineBreakPositions[line - 1] ? (pos - lineBreakPositions[line - 1] - 1) : pos var column = pos - beginColumn
return { return {
line: line, line: line,
column: column column: column

@ -2,78 +2,117 @@
var sourceMapping = require('./resources/sourceMapping') var sourceMapping = require('./resources/sourceMapping')
var index = require('../src/index') var index = require('../src/index')
var tape = require('tape') var tape = require('tape')
var util = require('../src/helpers/util')
tape('Util', function (t) { 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 = {} var testSourceMapping = {}
t.test('sourceMappingDecoder', function (st) { t.test('sourceMappingDecoder', function (st) {
st.plan(28) st.plan(28)
var sourceMappingDecoder = new index.util.SourceMappingDecoder() var sourceMappingDecoder = new index.util.SourceMappingDecoder()
console.log('test decompressAll') console.log('test decompressAll')
var result = sourceMappingDecoder.decompressAll(sourceMapping.mapping) var result = sourceMappingDecoder.decompressAll(sourceMapping.mapping)
st.ok(result[0].start === 0) st.equal(result[0].start, 0)
st.ok(result[0].length === 205) st.equal(result[0].length, 205)
st.ok(result[0].file === 4) st.equal(result[0].file, 4)
st.ok(result[0].jump === '-') st.equal(result[0].jump, '-')
st.ok(result[21].start === 0) st.equal(result[21].start, 0)
st.ok(result[21].length === 205) st.equal(result[21].length, 205)
st.ok(result[21].file === 4) st.equal(result[21].file, 4)
st.ok(result[21].jump === '-') st.equal(result[21].jump, '-')
testSourceMapping[21] = result[21] testSourceMapping[21] = result[21]
st.ok(result[22].start === 55) st.equal(result[22].start, 55)
st.ok(result[22].length === 74) st.equal(result[22].length, 74)
st.ok(result[22].file === 4) st.equal(result[22].file, 4)
st.ok(result[22].jump === '-') st.equal(result[22].jump, '-')
var last = result.length - 1 var last = result.length - 1
st.ok(result[last].start === 142) st.equal(result[last].start, 142)
st.ok(result[last].length === 61) st.equal(result[last].length, 61)
st.ok(result[last].file === 4) st.equal(result[last].file, 4)
st.ok(result[last].jump === 'o') st.equal(result[last].jump, 'o')
testSourceMapping['last'] = result[last] testSourceMapping['last'] = result[last]
console.log('test decompress') console.log('test decompress')
result = sourceMappingDecoder.atIndex(22, sourceMapping.mapping) result = sourceMappingDecoder.atIndex(22, sourceMapping.mapping)
console.log(result) console.log(result)
st.ok(result.start === 55) st.equal(result.start, 55)
st.ok(result.length === 74) st.equal(result.length, 74)
st.ok(result.file === 4) st.equal(result.file, 4)
st.ok(result.jump === '-') st.equal(result.jump, '-')
testSourceMapping[22] = result testSourceMapping[22] = result
result = sourceMappingDecoder.atIndex(82, sourceMapping.mapping) result = sourceMappingDecoder.atIndex(82, sourceMapping.mapping)
console.log(result) console.log(result)
st.ok(result.start === 103) st.equal(result.start, 103)
st.ok(result.length === 2) st.equal(result.length, 2)
st.ok(result.file === 4) st.equal(result.file, 4)
st.ok(result.jump === '-') st.equal(result.jump, '-')
testSourceMapping[82] = result testSourceMapping[82] = result
result = sourceMappingDecoder.atIndex(85, sourceMapping.mapping) result = sourceMappingDecoder.atIndex(85, sourceMapping.mapping)
console.log(result) console.log(result)
st.ok(result.start === 99) st.equal(result.start, 99)
st.ok(result.length === 6) st.equal(result.length, 6)
st.ok(result.file === 4) st.equal(result.file, 4)
st.ok(result.jump === '-') st.equal(result.jump, '-')
testSourceMapping[85] = result testSourceMapping[85] = result
}) })
t.test('sourceMappingLineColumnConverter', function (st) { t.test('sourceMappingLineColumnConverter', function (st) {
st.plan(10) st.plan(14)
var sourceMappingDecoder = new index.util.SourceMappingDecoder() var sourceMappingDecoder = new index.util.SourceMappingDecoder()
var linesbreak = sourceMappingDecoder.getLinebreakPositions(sourceMapping.source) var linesbreak = sourceMappingDecoder.getLinebreakPositions(sourceMapping.source)
st.ok(linesbreak[0] === 16) st.equal(linesbreak[0], 16)
st.ok(linesbreak[5] === 84) st.equal(linesbreak[5], 84)
var result = sourceMappingDecoder.convertOffsetToLineColumn(testSourceMapping[21], linesbreak) var result = sourceMappingDecoder.convertOffsetToLineColumn(testSourceMapping[21], linesbreak)
st.ok(result.start.line === 0) st.equal(result.start.line, 0)
st.ok(result.start.column === 0) st.equal(result.start.column, 0)
st.ok(result.end.line === 15) st.equal(result.end.line, 15)
st.ok(result.end.column === 1) st.equal(result.end.column, 1)
result = sourceMappingDecoder.convertOffsetToLineColumn(testSourceMapping[82], linesbreak) result = sourceMappingDecoder.convertOffsetToLineColumn(testSourceMapping[82], linesbreak)
st.ok(result.start.line === 7) st.equal(result.start.line, 7)
st.ok(result.start.column === 12) st.equal(result.start.column, 12)
st.ok(result.end.line === 7) st.equal(result.end.line, 7)
st.ok(result.end.column === 14) 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…
Cancel
Save