2019-09-20 01:23:49 +08:00
|
|
|
import { SourceLocation, Position } from './ast'
|
|
|
|
|
|
|
|
export function getInnerRange(
|
|
|
|
loc: SourceLocation,
|
|
|
|
offset: number,
|
|
|
|
length?: number
|
|
|
|
): SourceLocation {
|
2019-09-20 11:05:51 +08:00
|
|
|
__DEV__ && assert(offset <= loc.source.length)
|
2019-09-20 01:23:49 +08:00
|
|
|
const source = loc.source.substr(offset, length)
|
|
|
|
const newLoc: SourceLocation = {
|
|
|
|
source,
|
2019-09-20 11:05:51 +08:00
|
|
|
start: advancePositionWithClone(loc.start, loc.source, offset),
|
2019-09-20 01:23:49 +08:00
|
|
|
end: loc.end
|
|
|
|
}
|
|
|
|
|
|
|
|
if (length != null) {
|
2019-09-20 11:05:51 +08:00
|
|
|
__DEV__ && assert(offset + length <= loc.source.length)
|
|
|
|
newLoc.end = advancePositionWithClone(
|
|
|
|
loc.start,
|
|
|
|
loc.source,
|
|
|
|
offset + length
|
|
|
|
)
|
2019-09-20 01:23:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return newLoc
|
|
|
|
}
|
|
|
|
|
2019-09-20 11:05:51 +08:00
|
|
|
export function advancePositionWithClone(
|
2019-09-20 01:23:49 +08:00
|
|
|
pos: Position,
|
|
|
|
source: string,
|
|
|
|
numberOfCharacters: number
|
|
|
|
): Position {
|
2019-09-20 01:59:24 +08:00
|
|
|
return advancePositionWithMutation({ ...pos }, source, numberOfCharacters)
|
|
|
|
}
|
2019-09-20 01:23:49 +08:00
|
|
|
|
2019-09-20 01:59:24 +08:00
|
|
|
// advance by mutation without cloning (for performance reasons), since this
|
|
|
|
// gets called a lot in the parser
|
|
|
|
export function advancePositionWithMutation(
|
|
|
|
pos: Position,
|
|
|
|
source: string,
|
|
|
|
numberOfCharacters: number
|
|
|
|
): Position {
|
2019-09-20 09:18:18 +08:00
|
|
|
let linesCount = 0
|
|
|
|
let lastNewLinePos = -1
|
|
|
|
for (let i = 0; i < numberOfCharacters; i++) {
|
|
|
|
if (source.charCodeAt(i) === 10 /* newline char code */) {
|
|
|
|
linesCount++
|
|
|
|
lastNewLinePos = i
|
|
|
|
}
|
|
|
|
}
|
2019-09-20 01:23:49 +08:00
|
|
|
|
2019-09-20 01:59:24 +08:00
|
|
|
pos.offset += numberOfCharacters
|
2019-09-20 09:18:18 +08:00
|
|
|
pos.line += linesCount
|
2019-09-20 01:59:24 +08:00
|
|
|
pos.column =
|
2019-09-20 09:18:18 +08:00
|
|
|
lastNewLinePos === -1
|
2019-09-20 01:23:49 +08:00
|
|
|
? pos.column + numberOfCharacters
|
2019-09-20 09:18:18 +08:00
|
|
|
: Math.max(1, numberOfCharacters - lastNewLinePos - 1)
|
2019-09-20 01:23:49 +08:00
|
|
|
|
2019-09-20 01:59:24 +08:00
|
|
|
return pos
|
2019-09-20 01:23:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export function assert(condition: boolean, msg?: string) {
|
2019-09-25 04:35:01 +08:00
|
|
|
/* istanbul ignore if */
|
2019-09-20 01:23:49 +08:00
|
|
|
if (!condition) {
|
2019-09-23 04:50:57 +08:00
|
|
|
throw new Error(msg || `unexpected compiler condition`)
|
2019-09-20 01:23:49 +08:00
|
|
|
}
|
|
|
|
}
|