(TODO) Do not generate line numbers for invoke in callable reference classes
Keep line numbers for inlinable callable references.
#KT-29483 Fixed
(TODO) These tests are failing:
org.jetbrains.kotlin.codegen.debugInformation.SteppingTestGenerated
testNamedCallableReference
testInlineNamedCallableReference
For some reason, removing line numbers from the function reference's
invoke leads to JVM skipping the actual method which the reference
points to, during stepping.
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java
index 567a0a4..055a992 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java
@@ -136,7 +136,7 @@
public final Map<KtElement, StackValue> tempVariables = new HashMap<>();
private int myLastLineNumber = -1;
- private boolean shouldMarkLineNumbers = true;
+ public boolean shouldMarkLineNumbers = true;
private int finallyDepth = 0;
public ExpressionCodegen(
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java
index 7578a99..153a767 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java
@@ -181,25 +181,28 @@
}
};
- StackValue result;
- Type returnType = codegen.getReturnType();
- if (referencedFunction instanceof ConstructorDescriptor) {
- if (returnType.getSort() == Type.ARRAY) {
- //noinspection ConstantConditions
- result = codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType(), fakeResolvedCall);
+ codegen.runWithShouldMarkLineNumbers(codegen.shouldMarkLineNumbers && isInliningStrategy, () -> {
+ StackValue result;
+ Type returnType = codegen.getReturnType();
+ if (referencedFunction instanceof ConstructorDescriptor) {
+ if (returnType.getSort() == Type.ARRAY) {
+ //noinspection ConstantConditions
+ result = codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType(), fakeResolvedCall);
+ }
+ else {
+ result = codegen.generateConstructorCall(fakeResolvedCall, returnType);
+ }
}
else {
- result = codegen.generateConstructorCall(fakeResolvedCall, returnType);
+ Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
+ result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
}
- }
- else {
- Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
- result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
- }
- InstructionAdapter v = codegen.v;
- result.put(returnType, v);
- v.areturn(returnType);
+ InstructionAdapter v = codegen.v;
+ result.put(returnType, v);
+ v.areturn(returnType);
+ return null;
+ });
}
private void computeAndSaveArguments(
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt
index 25ac04a..ef58f86 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt
@@ -384,7 +384,9 @@
else -> codegen.intermediateValueForProperty(target as PropertyDescriptor, false, null, StackValue.none())
}
- codegen.markStartLineNumber(expression)
+ if (isInliningStrategy) {
+ codegen.markStartLineNumber(expression)
+ }
if (isGetter) {
value.put(OBJECT_TYPE, targetKotlinType, v)
@@ -403,4 +405,3 @@
}
}
}
-
diff --git a/compiler/testData/codegen/bytecodeText/lineNumbers/callableReference.kt b/compiler/testData/codegen/bytecodeText/lineNumbers/callableReference.kt
new file mode 100644
index 0000000..5fd98a4
--- /dev/null
+++ b/compiler/testData/codegen/bytecodeText/lineNumbers/callableReference.kt
@@ -0,0 +1,16 @@
+// IGNORE_BACKEND: JVM_IR
+
+fun function() {
+}
+
+val property: Long
+ get() = System.currentTimeMillis()
+
+fun main() {
+ ::function
+ ::property
+}
+
+// There's one line number in `function`, one in `getProperty` and three in `main`.
+// It's important that there are no additional line numbers in synthetic methods in anonymous classes for callable references
+// 5 LINENUMBER
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java
index 7f845ec..85d257e 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java
@@ -3230,6 +3230,11 @@
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/lineNumbers"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
+ @TestMetadata("callableReference.kt")
+ public void testCallableReference() throws Exception {
+ runTest("compiler/testData/codegen/bytecodeText/lineNumbers/callableReference.kt");
+ }
+
@TestMetadata("ifConsts.kt")
public void testIfConsts() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/ifConsts.kt");
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java
index 2e6646f..4e9715c 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java
@@ -3275,6 +3275,11 @@
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/lineNumbers"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
+ @TestMetadata("callableReference.kt")
+ public void testCallableReference() throws Exception {
+ runTest("compiler/testData/codegen/bytecodeText/lineNumbers/callableReference.kt");
+ }
+
@TestMetadata("ifConsts.kt")
public void testIfConsts() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/ifConsts.kt");