JS: fix incremental generation of source maps

This commit is contained in:
Alexey Andreev
2017-02-28 20:41:27 +03:00
parent 0058d2fdf6
commit f4a9b99e4d
6 changed files with 56 additions and 70 deletions
@@ -31,7 +31,7 @@ class JsAstDeserializer(private val program: JsProgram) {
private val stringTable = mutableListOf<String>()
private val nameTable = mutableListOf<Name>()
private val nameCache = mutableListOf<JsName?>()
private val locationStack: Deque<JsLocation> = ArrayDeque()
private val fileStack: Deque<String> = ArrayDeque()
fun deserialize(input: InputStream): JsProgramFragment {
return deserialize(Chunk.parseFrom(CodedInputStream.newInstance(input).apply { setRecursionLimit(4096) }))
@@ -491,28 +491,27 @@ class JsAstDeserializer(private val program: JsProgram) {
}
private fun <T : JsNode> withLocation(fileId: Int?, location: Location?, action: () -> T): T {
val lastLocation = locationStack.peek()
val deserializedLocation = if (fileId != null || location != null) {
val file = fileId?.let { deserializeString(it) } ?: lastLocation?.file!!
val (startLine, startChar) = if (location != null) {
Pair(location.startLine, location.startChar)
}
else {
Pair(lastLocation.startLine, lastLocation.startChar)
}
JsLocation(file, startLine, startChar)
val deserializedFile = fileId?.let { deserializeString(it) }
val file = deserializedFile ?: fileStack.peek()
val deserializedLocation = if (file != null && location != null) {
JsLocation(file, location.startLine, location.startChar)
}
else {
null
}
if (deserializedLocation != null) {
locationStack.push(deserializedLocation)
val shouldUpdateFile = location != null && deserializedFile != null && deserializedFile != fileStack.peek()
if (shouldUpdateFile) {
fileStack.push(deserializedFile)
}
val node = action()
if (deserializedLocation != null) {
node.source = deserializedLocation
locationStack.pop()
if (node !is JsLiteral.JsBooleanLiteral && node !is JsLiteral.JsThisRef && node !is JsNullLiteral) {
node.source = deserializedLocation
}
}
if (shouldUpdateFile) {
fileStack.pop()
}
return node
@@ -31,7 +31,7 @@ class JsAstSerializer {
private val stringTableBuilder = StringTable.newBuilder()
private val nameMap = mutableMapOf<JsName, Int>()
private val stringMap = mutableMapOf<String, Int>()
private val locationStack: Deque<JsLocation> = ArrayDeque()
private val fileStack: Deque<String> = ArrayDeque()
fun serialize(fragment: JsProgramFragment, output: OutputStream) {
serialize(fragment).writeTo(output)
@@ -561,27 +561,25 @@ class JsAstSerializer {
}
private inline fun withLocation(node: JsNode, fileConsumer: (Int) -> Unit, locationConsumer: (Location) -> Unit, inner: () -> Unit) {
val lastLocation = locationStack.peek()
val location = extractLocation(node)
val locationStackModified = if (lastLocation != location && location != null) {
locationStack.push(location)
if (lastLocation == null || lastLocation.file != location.file) {
var fileChanged = false
if (location != null) {
val lastFile = fileStack.peek()
fileChanged = lastFile != location.file
if (fileChanged) {
fileConsumer(serialize(location.file))
fileStack.push(location.file)
}
val locationBuilder = Location.newBuilder()
locationBuilder.startLine = location.startLine
locationBuilder.startChar = location.startChar
locationConsumer(locationBuilder.build())
true
}
else {
false
}
inner()
if (locationStackModified) {
locationStack.pop()
if (fileChanged) {
fileStack.pop()
}
}