diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/JsLineNumberTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/JsLineNumberTestGenerated.java index 8c4832fe2a4..6721ac43a9b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/JsLineNumberTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/JsLineNumberTestGenerated.java @@ -66,6 +66,12 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest { doTest(fileName); } + @TestMetadata("for.kt") + public void testFor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/for.kt"); + doTest(fileName); + } + @TestMetadata("increment.kt") public void testIncrement() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/increment.kt"); @@ -96,12 +102,24 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest { doTest(fileName); } + @TestMetadata("lambdaWithClosure.kt") + public void testLambdaWithClosure() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/lambdaWithClosure.kt"); + doTest(fileName); + } + @TestMetadata("literals.kt") public void testLiterals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/literals.kt"); doTest(fileName); } + @TestMetadata("longLiteral.kt") + public void testLongLiteral() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/longLiteral.kt"); + doTest(fileName); + } + @TestMetadata("memberFunWithDefaultParam.kt") public void testMemberFunWithDefaultParam() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/memberFunWithDefaultParam.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LoopTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LoopTranslator.kt index 72d6a1dada0..dd82e473728 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LoopTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LoopTranslator.kt @@ -145,16 +145,17 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont val rangeEnd = context.defineTemporary(rightExpression) val body = translateBody(null) - val conditionExpression = lessThanEq(parameterName.makeRef(), rangeEnd) - val incrementExpression = JsPostfixOperation(JsUnaryOperator.INC, parameterName.makeRef()) + val conditionExpression = lessThanEq(parameterName.makeRef(), rangeEnd).source(expression) + val incrementExpression = JsPostfixOperation(JsUnaryOperator.INC, parameterName.makeRef()).source(expression) + val initVars = newVar(parameterName, rangeStart).apply { source = expression } - return JsFor(newVar(parameterName, rangeStart), conditionExpression, incrementExpression, body) + return JsFor(initVars, conditionExpression, incrementExpression, body) } fun translateForOverRange(): JsStatement { val rangeExpression = context.defineTemporary(Translation.translateAsExpression(loopRange, context)) - fun getProperty(funName: String): JsExpression = JsNameRef(funName, rangeExpression) + fun getProperty(funName: String): JsExpression = JsNameRef(funName, rangeExpression).source(loopRange) val start = context.defineTemporary(getProperty("first")) val end = context.defineTemporary(getProperty("last")) @@ -162,10 +163,11 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont val body = translateBody(null) - val conditionExpression = lessThanEq(parameterName.makeRef(), end) - val incrementExpression = addAssign(parameterName.makeRef(), increment) + val conditionExpression = lessThanEq(parameterName.makeRef(), end).source(expression) + val incrementExpression = addAssign(parameterName.makeRef(), increment).source(expression) + val initVars = newVar(parameterName, start).apply { source = expression } - return JsFor(newVar(parameterName, start), conditionExpression, incrementExpression, body) + return JsFor(initVars, conditionExpression, incrementExpression, body) } fun translateForOverArray(): JsStatement { @@ -174,11 +176,11 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont val end = context.defineTemporary(length) val index = context.declareTemporary(JsIntLiteral(0)) - val arrayAccess = JsArrayAccess(rangeExpression, index.reference()) + val arrayAccess = JsArrayAccess(rangeExpression, index.reference()).source(expression) val body = translateBody(arrayAccess) - val initExpression = assignment(index.reference(), JsIntLiteral(0)) - val conditionExpression = inequality(index.reference(), end) - val incrementExpression = JsPrefixOperation(JsUnaryOperator.INC, index.reference()) + val initExpression = assignment(index.reference(), JsIntLiteral(0)).source(expression) + val conditionExpression = inequality(index.reference(), end).source(expression) + val incrementExpression = JsPrefixOperation(JsUnaryOperator.INC, index.reference()).source(expression) return JsFor(initExpression, conditionExpression, incrementExpression, body) } @@ -216,7 +218,7 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont } else { bodyStatements += hasNextBlock.statements - bodyStatements += JsIf(notOptimized(hasNextInvocation), JsBreak()) + bodyStatements += JsIf(notOptimized(hasNextInvocation), JsBreak().apply { source = expression }).apply { source = expression } JsBooleanLiteral(true) } bodyStatements += nextBlock.statements @@ -224,7 +226,7 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont return JsWhile(exitCondition, bodyStatements.singleOrNull() ?: JsBlock(bodyStatements)) } - return when { + val result = when { isForOverRangeLiteral() -> translateForOverLiteralRange() @@ -237,4 +239,6 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont else -> translateForOverIterator() } + + return result.apply { source = expression } } diff --git a/js/js.translator/testData/lineNumbers/for.kt b/js/js.translator/testData/lineNumbers/for.kt new file mode 100644 index 00000000000..6dd25bb230e --- /dev/null +++ b/js/js.translator/testData/lineNumbers/for.kt @@ -0,0 +1,20 @@ +fun box() { + for (x in arrayOf(1, 2, 3)) { + println(x) + } + + for (x in 1..10) { + println(x) + } + + for (x in listOf(1, 2, 3)) { + println(x) + } + + val xs = listOf(1, 2, 3) + for (x in xs.indices) { + println(x) + } +} + +// LINES: 2 10 15 2 2 2 3 6 6 7 10 10 10 11 14 15 15 15 15 15 15 16 \ No newline at end of file