Multiple fixes of JS source maps
- elvis expression with complex RHS - destructuring declarations - decomposition of `var` statement (for example, in case of inline destructuring functions) - `is` LHS &&/|| inline fun RHS - argument assignment to temporary var on inline call site - assignment of `next()` result to temporary var in `for` expression - rethrow statement in exception handler
This commit is contained in:
@@ -81,7 +81,7 @@ internal class ExpressionDecomposer private constructor(
|
||||
|
||||
for (jsVar in vars) {
|
||||
if (jsVar in containsExtractable && prevVars.isNotEmpty()) {
|
||||
addStatement(JsVars(prevVars, x.isMultiline))
|
||||
addStatement(JsVars(prevVars, x.isMultiline).apply { source = prevVars.first().source })
|
||||
prevVars = SmartList<JsVars.JsVar>()
|
||||
}
|
||||
|
||||
@@ -89,8 +89,11 @@ internal class ExpressionDecomposer private constructor(
|
||||
prevVars.add(jsVar)
|
||||
}
|
||||
|
||||
vars.clear()
|
||||
vars.addAll(prevVars)
|
||||
if (vars.size != prevVars.size) {
|
||||
vars.clear()
|
||||
vars.addAll(prevVars)
|
||||
x.source = prevVars.first().source
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -168,7 +171,7 @@ internal class ExpressionDecomposer private constructor(
|
||||
additionalStatements.toStatement()
|
||||
}
|
||||
|
||||
addStatement(JsIf(test, arg2Eval))
|
||||
addStatement(JsIf(test, arg2Eval).also { it.source = source })
|
||||
ctx.replaceMe(tmp.nameRef)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ private constructor(
|
||||
val parameters = getParameters()
|
||||
|
||||
removeDefaultInitializers(arguments, parameters, body)
|
||||
aliasArgumentsIfNeeded(namingContext, arguments, parameters)
|
||||
aliasArgumentsIfNeeded(namingContext, arguments, parameters, call.source)
|
||||
renameLocalNames(namingContext, invokedFunction)
|
||||
processReturns()
|
||||
|
||||
@@ -89,7 +89,7 @@ private constructor(
|
||||
val namingContext = inliningContext.newNamingContext()
|
||||
val arguments = call.arguments
|
||||
val parameters = outer.parameters
|
||||
aliasArgumentsIfNeeded(namingContext, arguments, parameters)
|
||||
aliasArgumentsIfNeeded(namingContext, arguments, parameters, call.source)
|
||||
namingContext.applyRenameTo(inner)
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ private constructor(
|
||||
if (thisReplacement == null || thisReplacement is JsThisRef) return
|
||||
|
||||
val thisName = JsScope.declareTemporaryName(getThisAlias())
|
||||
namingContext.newVar(thisName, thisReplacement)
|
||||
namingContext.newVar(thisName, thisReplacement, source = call.source)
|
||||
thisReplacement = thisName.makeRef()
|
||||
|
||||
replaceThisReference(block, thisReplacement)
|
||||
@@ -121,7 +121,7 @@ private constructor(
|
||||
|
||||
val resultName = JsScope.declareTemporaryName(getResultLabel())
|
||||
this.resultName = resultName
|
||||
namingContext.newVar(resultName, null)
|
||||
namingContext.newVar(resultName, source = call.source)
|
||||
return resultName.makeRef()
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +45,10 @@ class NamingContext(private val statementContext: JsContext<JsStatement>) {
|
||||
renamings.put(name, replacement)
|
||||
}
|
||||
|
||||
fun newVar(name: JsName, value: JsExpression? = null) {
|
||||
fun newVar(name: JsName, value: JsExpression? = null, source: Any?) {
|
||||
val vars = JsAstUtils.newVar(name, value)
|
||||
vars.synthetic = true
|
||||
vars.source = source
|
||||
declarations.add(vars)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.jetbrains.kotlin.js.inline.util.rewriters.LabelNameRefreshingVisitor
|
||||
fun aliasArgumentsIfNeeded(
|
||||
context: NamingContext,
|
||||
arguments: List<JsExpression>,
|
||||
parameters: List<JsParameter>
|
||||
parameters: List<JsParameter>,
|
||||
source: Any?
|
||||
) {
|
||||
require(arguments.size <= parameters.size) { "arguments.size (${arguments.size}) should be less or equal to parameters.size (${parameters.size})" }
|
||||
|
||||
@@ -34,9 +35,10 @@ fun aliasArgumentsIfNeeded(
|
||||
|
||||
val replacement = JsScope.declareTemporaryName(paramName.ident).apply {
|
||||
staticRef = arg
|
||||
context.newVar(this, arg.deepCopy())
|
||||
context.newVar(this, arg.deepCopy(), source = source)
|
||||
}.makeRef()
|
||||
|
||||
replacement.source = arg.source
|
||||
context.replaceName(paramName, replacement)
|
||||
}
|
||||
|
||||
@@ -45,7 +47,7 @@ fun aliasArgumentsIfNeeded(
|
||||
val paramName = defaultParam.name
|
||||
val freshName = JsScope.declareTemporaryName(paramName.ident)
|
||||
freshName.copyMetadataFrom(paramName)
|
||||
context.newVar(freshName)
|
||||
context.newVar(freshName, source = source)
|
||||
|
||||
context.replaceName(paramName, freshName.makeRef())
|
||||
}
|
||||
|
||||
@@ -120,12 +120,30 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuring.kt")
|
||||
public void testDestructuring() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/destructuring.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuringInline.kt")
|
||||
public void testDestructuringInline() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/destructuringInline.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doWhileWithComplexCondition.kt")
|
||||
public void testDoWhileWithComplexCondition() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/doWhileWithComplexCondition.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("elvis.kt")
|
||||
public void testElvis() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/elvis.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("enumCompanionObject.kt")
|
||||
public void testEnumCompanionObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/enumCompanionObject.kt");
|
||||
@@ -156,6 +174,12 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineArguments.kt")
|
||||
public void testInlineArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/inlineArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineLocalVarsRef.kt")
|
||||
public void testInlineLocalVarsRef() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/inlineLocalVarsRef.kt");
|
||||
@@ -186,6 +210,12 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("isOperator.kt")
|
||||
public void testIsOperator() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/isOperator.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaWithClosure.kt")
|
||||
public void testLambdaWithClosure() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/lambdaWithClosure.kt");
|
||||
|
||||
+3
-1
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.expression
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
|
||||
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.types.isDynamic
|
||||
|
||||
class CatchTranslator(
|
||||
val catches: List<KtCatchClause>,
|
||||
val psi: PsiElement,
|
||||
context: TranslationContext
|
||||
) : AbstractTranslator(context) {
|
||||
|
||||
@@ -86,7 +88,7 @@ class CatchTranslator(
|
||||
catches: Iterator<KtCatchClause>
|
||||
): JsStatement {
|
||||
if (!catches.hasNext()) {
|
||||
return JsThrow(initialCatchParameterRef)
|
||||
return JsThrow(initialCatchParameterRef).apply { source = psi }
|
||||
}
|
||||
|
||||
var nextContext = context
|
||||
|
||||
+6
-2
@@ -92,8 +92,12 @@ public class DestructuringDeclarationTranslator extends AbstractTranslator {
|
||||
entryInitializer = JsAstUtils.wrapValue(alias, entryInitializer);
|
||||
}
|
||||
|
||||
jsVars.add(new JsVars.JsVar(name, entryInitializer));
|
||||
JsVars.JsVar jsVar = new JsVars.JsVar(name, entryInitializer);
|
||||
jsVar.setSource(entry);
|
||||
jsVars.add(jsVar);
|
||||
}
|
||||
return new JsVars(jsVars, true);
|
||||
JsVars result = new JsVars(jsVars, true);
|
||||
result.setSource(multiDeclaration);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -391,7 +391,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@NotNull
|
||||
public JsNode visitIsExpression(@NotNull KtIsExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return Translation.patternTranslator(context).translateIsExpression(expression);
|
||||
return Translation.patternTranslator(context).translateIsExpression(expression).source(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -115,12 +115,13 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
|
||||
|
||||
val currentVarInit =
|
||||
if (destructuringParameter == null) {
|
||||
newVar(parameterName, itemValue)
|
||||
newVar(parameterName, itemValue).apply { source = expression.loopRange }
|
||||
}
|
||||
else {
|
||||
val innerBlockContext = context.innerBlock(block)
|
||||
if (itemValue != null) {
|
||||
innerBlockContext.addStatementToCurrentBlock(JsAstUtils.newVar(parameterName, itemValue))
|
||||
val parameterStatement = JsAstUtils.newVar(parameterName, itemValue).apply { source = expression.loopRange }
|
||||
innerBlockContext.addStatementToCurrentBlock(parameterStatement)
|
||||
}
|
||||
DestructuringDeclarationTranslator.translate(
|
||||
destructuringParameter, JsAstUtils.pureFqn(parameterName, null), innerBlockContext)
|
||||
|
||||
@@ -32,7 +32,7 @@ class TryTranslator(
|
||||
fun translate(): JsTry {
|
||||
val tryBlock = translateAsBlock(expression.tryBlock)
|
||||
|
||||
val catchTranslator = CatchTranslator(expression.catchClauses, context())
|
||||
val catchTranslator = CatchTranslator(expression.catchClauses, expression, context())
|
||||
val catchBlock = catchTranslator.translate()
|
||||
|
||||
val finallyExpression = expression.finallyBlock?.finalExpression
|
||||
|
||||
+1
@@ -154,6 +154,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
|
||||
JsExpression testExpression = TranslationUtils.isNullCheck(leftExpression);
|
||||
ifStatement = JsAstUtils.newJsIf(testExpression, rightBlock);
|
||||
}
|
||||
ifStatement.setSource(expression);
|
||||
context().addStatementToCurrentBlock(ifStatement);
|
||||
return result;
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,4 +19,4 @@ fun bar() {
|
||||
}
|
||||
}
|
||||
|
||||
// LINES: 11 3 3 5 5 6 6 8 8 9 9 * 20 15 15 18 18
|
||||
// LINES: 11 3 3 5 5 6 6 8 8 9 9 2 2 * 20 15 15 18 18
|
||||
+1
-1
@@ -17,4 +17,4 @@ fun bar(a: String, b: Char, x: Int) {
|
||||
a.foo(b)
|
||||
}
|
||||
|
||||
// LINES: 6 4 4 5 5 11 9 9 10 10 18 14 14 14 14 14 15 17 9 9 14 10 17 10 14 14 * 1 * 1
|
||||
// LINES: 6 4 4 5 5 11 9 9 10 10 18 14 14 14 14 14 15 17 17 9 9 14 10 17 10 14 14 * 1 * 1
|
||||
@@ -0,0 +1,30 @@
|
||||
var log = ""
|
||||
|
||||
fun foo() {
|
||||
for (
|
||||
(
|
||||
q,
|
||||
w
|
||||
)
|
||||
in listOf(Pair("1", "2"))
|
||||
) {
|
||||
log += q
|
||||
log += w
|
||||
}
|
||||
|
||||
bar {
|
||||
(
|
||||
q,
|
||||
w
|
||||
) ->
|
||||
log += q
|
||||
log += w
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(f: (Pair<String, String>) -> Unit) {
|
||||
f(Pair("w", "e"))
|
||||
}
|
||||
|
||||
|
||||
// LINES: 22 16 16 17 18 20 20 21 21 23 9 9 9 9 4 9 9 9 5 5 6 7 11 11 12 12 15 15 27 26 26 * 1 * 1
|
||||
@@ -0,0 +1,35 @@
|
||||
var log = ""
|
||||
|
||||
fun foo() {
|
||||
for (
|
||||
(
|
||||
q,
|
||||
w
|
||||
)
|
||||
in listOf(P("1", "2"))
|
||||
) {
|
||||
log += q
|
||||
log += w
|
||||
}
|
||||
|
||||
bar {
|
||||
(
|
||||
q,
|
||||
w
|
||||
) ->
|
||||
log += q
|
||||
log += w
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(f: (P) -> Unit) {
|
||||
f(P("w", "e"))
|
||||
}
|
||||
|
||||
class P(val a: String, val b: String)
|
||||
|
||||
inline operator fun P.component1() = a
|
||||
|
||||
inline operator fun P.component2() = b
|
||||
|
||||
// LINES: 22 17 17 31 18 18 33 20 20 21 21 23 9 9 9 9 4 9 9 9 6 6 31 7 7 33 11 11 12 12 15 15 27 26 26 29 29 29 * 31 31 31 33 33 33 * 1 * 1
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
var log = ""
|
||||
|
||||
fun box(x: String?) {
|
||||
log +=
|
||||
x
|
||||
?:
|
||||
try { foo() } finally { log += "finally" }
|
||||
}
|
||||
|
||||
fun foo() = "bar"
|
||||
|
||||
// LINES: 8 7 7 4 4 4 5 5 7 7 7 7 * 5 4 5 10 10 10 * 1 * 1
|
||||
+1
-1
@@ -17,4 +17,4 @@ fun box() {
|
||||
}
|
||||
}
|
||||
|
||||
// LINES: 18 2 2 10 15 2 2 2 2 2 3 3 6 6 6 6 7 7 10 10 10 10 10 11 11 14 14 15 15 15 15 15 15 15 15 15 15 15 15 16 16
|
||||
// LINES: 18 2 2 10 15 2 2 2 2 2 2 3 3 6 6 6 6 7 7 10 10 10 10 10 10 11 11 14 14 15 15 15 15 15 15 15 15 15 15 15 15 16 16
|
||||
@@ -0,0 +1,14 @@
|
||||
var log = ""
|
||||
|
||||
fun box() {
|
||||
foo(bar())
|
||||
}
|
||||
|
||||
inline fun foo(x: Int) {
|
||||
log += x
|
||||
log += x
|
||||
}
|
||||
|
||||
fun bar() = 23
|
||||
|
||||
// LINES: 5 4 4 8 8 9 9 10 8 8 9 9 12 12 12 * 1 * 1
|
||||
+1
-1
@@ -21,4 +21,4 @@ fun bar(x: Int) {
|
||||
println("%")
|
||||
}
|
||||
|
||||
// LINES: 17 2 2 3 3 4 7 7 9 9 10 10 11 14 14 16 16 22 20 * 2 2 3 3 4 3 7 7 9 9 10 10 11 10 14 14 16 16 * 20 21 21
|
||||
// LINES: 17 2 2 3 3 4 7 7 9 9 10 10 11 14 14 16 16 22 20 20 20 20 2 2 3 3 4 3 7 7 9 9 10 10 11 10 14 14 16 16 * 20 21 21
|
||||
@@ -0,0 +1,14 @@
|
||||
var log = ""
|
||||
|
||||
fun box(a: Any) {
|
||||
if (a is String && foo()) {
|
||||
log += "OK"
|
||||
}
|
||||
}
|
||||
|
||||
inline fun foo(): Boolean {
|
||||
log += "foo"
|
||||
return true
|
||||
}
|
||||
|
||||
// LINES: 7 4 4 4 10 10 4 11 4 5 5 12 10 10 11 11 * 1 * 1
|
||||
Reference in New Issue
Block a user