JS: optimize JSON parser
This commit is contained in:
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.parser.sourcemaps
|
||||
|
||||
import java.io.Reader
|
||||
import java.io.StringReader
|
||||
import java.io.StringWriter
|
||||
import java.io.Writer
|
||||
import java.io.*
|
||||
|
||||
sealed class JsonNode {
|
||||
abstract fun write(writer: Writer)
|
||||
@@ -120,8 +117,7 @@ data class JsonNumber(val value: Double) : JsonNode() {
|
||||
override fun write(writer: Writer) {
|
||||
if (value.toLong().toDouble() == value) {
|
||||
writer.append(value.toLong().toString())
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writer.append(value.toString())
|
||||
}
|
||||
}
|
||||
@@ -130,14 +126,15 @@ data class JsonNumber(val value: Double) : JsonNode() {
|
||||
}
|
||||
|
||||
class JsonSyntaxException(val offset: Int, val line: Int, val column: Int, val text: String) :
|
||||
RuntimeException("JSON syntax error at ${line + 1}, ${column + 1}: $text")
|
||||
RuntimeException("JSON syntax error at ${line + 1}, ${column + 1}: $text")
|
||||
|
||||
fun parseJson(reader: Reader): JsonNode = JsonParser(reader).parse()
|
||||
fun parseJson(file: File): JsonNode = parseJson(file.readText(Charsets.UTF_8))
|
||||
|
||||
fun parseJson(text: String): JsonNode = parseJson(StringReader(text))
|
||||
fun parseJson(text: String): JsonNode = JsonParser(text).parse()
|
||||
|
||||
private class JsonParser(val reader: Reader) {
|
||||
private var charCode = reader.read()
|
||||
private class JsonParser(val content: String) {
|
||||
private var index = 0
|
||||
private var charCode = content.getOrNull(index++)?.toInt() ?: -1
|
||||
private var offset = 0
|
||||
private var line = 0
|
||||
private var col = 0
|
||||
@@ -165,13 +162,27 @@ private class JsonParser(val reader: Reader) {
|
||||
'['.toInt() -> parseArray()
|
||||
'{'.toInt() -> parseObject()
|
||||
'"'.toInt() -> JsonString(parseString())
|
||||
'n'.toInt() -> { expectString("null"); JsonNull }
|
||||
'f'.toInt() -> { expectString("false"); JsonBoolean.FALSE }
|
||||
't'.toInt() -> { expectString("true"); JsonBoolean.TRUE }
|
||||
in '0'.toInt()..'9'.toInt() -> JsonNumber(parseNumber())
|
||||
'-'.toInt() -> { advance(); JsonNumber(-parseNumber())
|
||||
'n'.toInt() -> {
|
||||
expectString("null")
|
||||
JsonNull
|
||||
}
|
||||
'f'.toInt() -> {
|
||||
expectString("false")
|
||||
JsonBoolean.FALSE
|
||||
}
|
||||
't'.toInt() -> {
|
||||
expectString("true")
|
||||
JsonBoolean.TRUE
|
||||
}
|
||||
'-'.toInt() -> {
|
||||
advance()
|
||||
JsonNumber(-parseNumber())
|
||||
}
|
||||
else -> if (charCode in '0'.toInt()..'9'.toInt()) {
|
||||
JsonNumber(parseNumber())
|
||||
} else {
|
||||
error("Unexpected char")
|
||||
}
|
||||
else -> error("Unexpected char")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,8 +194,7 @@ private class JsonParser(val reader: Reader) {
|
||||
if (charCode == ']'.toInt()) {
|
||||
advance()
|
||||
break
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (result.elements.isNotEmpty()) {
|
||||
expectCharAndAdvance(',')
|
||||
}
|
||||
@@ -202,8 +212,7 @@ private class JsonParser(val reader: Reader) {
|
||||
if (charCode == '}'.toInt()) {
|
||||
advance()
|
||||
break
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (result.properties.isNotEmpty()) {
|
||||
expectCharAndAdvance(',')
|
||||
}
|
||||
@@ -356,7 +365,7 @@ private class JsonParser(val reader: Reader) {
|
||||
wasCR = false
|
||||
}
|
||||
}
|
||||
charCode = reader.read()
|
||||
charCode = content.getOrNull(index++)?.toInt() ?: -1
|
||||
offset++
|
||||
}
|
||||
|
||||
|
||||
@@ -16,20 +16,29 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.parser.sourcemaps
|
||||
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.Reader
|
||||
import java.io.StringReader
|
||||
|
||||
object SourceMapParser {
|
||||
@Throws(IOException::class)
|
||||
fun parse(reader: Reader): SourceMapParseResult {
|
||||
fun parse(file: File): SourceMapParseResult {
|
||||
return parse(file.readText(Charsets.UTF_8))
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun parse(content: String): SourceMapParseResult {
|
||||
val jsonObject = try {
|
||||
parseJson(reader)
|
||||
parseJson(content)
|
||||
}
|
||||
catch (e: JsonSyntaxException) {
|
||||
return SourceMapError(e.message ?: "parse error")
|
||||
}
|
||||
return parse(jsonObject)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun parse(jsonObject: JsonNode): SourceMapParseResult {
|
||||
if (jsonObject !is JsonObject) return SourceMapError("Top-level object expected")
|
||||
|
||||
val version = jsonObject.properties["version"] ?: return SourceMapError("Version not defined")
|
||||
|
||||
Reference in New Issue
Block a user