JS: fix parsing of object literals in js() function.

Also, fix generation of source maps of content of js() function.

See KT-19794
This commit is contained in:
Alexey Andreev
2017-09-29 13:09:42 +03:00
parent c15847a957
commit 27e319a279
15 changed files with 183 additions and 31 deletions
@@ -462,7 +462,7 @@ public class JsAstMapper {
}
}
private JsExpression mapExpression(Node exprNode) throws JsParserException {
public JsExpression mapExpression(Node exprNode) throws JsParserException {
JsNode unknown = map(exprNode);
if (unknown instanceof JsExpression) {
@@ -727,7 +727,7 @@ public class Parser {
return pn;
}
private Node expr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
public Node expr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
Node pn = assignExpr(ts, inForInit);
while (ts.matchToken(TokenStream.COMMA)) {
CodePosition position = ts.tokenPosition;
@@ -30,6 +30,42 @@ fun parse(code: String, reporter: ErrorReporter, scope: JsScope, fileName: Strin
}
}
fun parseExpressionOrStatement(
code: String,
reporter: ErrorReporter, scope: JsScope,
startPosition: CodePosition, fileName: String
): List<JsStatement>? {
val accumulatingReporter = AccumulatingReporter()
val exprNode = try {
parse(code, startPosition, 0, accumulatingReporter, true) {
val result = expr(it, false)
if (it.token != TokenStream.EOF) {
accumulatingReporter.hasErrors = true
}
result
}
}
catch (e: JavaScriptException) {
null
}
return if (!accumulatingReporter.hasErrors) {
for (warning in accumulatingReporter.warnings) {
reporter.warning(warning.message, warning.startPosition, warning.endPosition)
}
val expr = exprNode?.toJsAst(scope, fileName) {
mapExpression(it)
}
expr?.let { listOf(JsExpressionStatement(it)) }
}
else {
val node = parse(code, startPosition, 0, reporter, true, Parser::parse)
node?.toJsAst(scope, fileName) {
mapStatements(it)
}
}
}
fun parseFunction(code: String, fileName: String, position: CodePosition, offset: Int, reporter: ErrorReporter, scope: JsScope): JsFunction? {
val rootNode = parse(code, position, offset, reporter, insideFunction = false) {
addListener(FunctionParsingObserver())
@@ -80,4 +116,20 @@ private fun StringReader(string: String, offset: Int): Reader {
val reader = StringReader(string)
reader.skip(offset.toLong())
return reader
}
}
private class AccumulatingReporter : ErrorReporter {
var hasErrors = false
val warnings = mutableListOf<Warning>()
override fun warning(message: String, startPosition: CodePosition, endPosition: CodePosition) {
warnings += Warning(message, startPosition, endPosition)
}
override fun error(message: String, startPosition: CodePosition, endPosition: CodePosition) {
hasErrors = true
}
class Warning(val message: String, val startPosition: CodePosition, val endPosition: CodePosition)
}