Fix constant expression inlining logic
Constant expressions are inlined if they do not depend on non-inlineable vals. Java constants are always inlined. Kotlin constants are inlined in LV 1.1+.
This commit is contained in:
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -74,7 +73,6 @@ import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluatorKt;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
|
||||
@@ -295,7 +295,7 @@ public class JvmCodegenUtil {
|
||||
}
|
||||
|
||||
public static boolean isInlinedJavaConstProperty(VariableDescriptor descriptor) {
|
||||
return JvmConstantsKt.isInlinedJavaConstProperty(descriptor);
|
||||
return descriptor instanceof JavaPropertyDescriptor && descriptor.isConst();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -42,7 +42,7 @@ fun getCompileTimeConstant(
|
||||
if (!shouldInlineConstVals && !takeUpConstValsAsConst && compileTimeValue.usesVariableAsConstant) {
|
||||
val constantChecker = ConstantsChecker(bindingContext)
|
||||
expression.accept(constantChecker)
|
||||
if (constantChecker.containsNonInlinedVals) return null
|
||||
if (constantChecker.containsKotlinConstVals) return null
|
||||
}
|
||||
|
||||
val expectedType = bindingContext.getType(expression) ?: return null
|
||||
@@ -52,25 +52,21 @@ fun getCompileTimeConstant(
|
||||
|
||||
|
||||
private class ConstantsChecker(private val bindingContext: BindingContext) : KtVisitorVoid() {
|
||||
var containsNonInlinedVals = false
|
||||
var containsKotlinConstVals = false
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||
val resolvedCall = expression.getResolvedCall(bindingContext)
|
||||
if (resolvedCall != null) {
|
||||
val callableDescriptor = resolvedCall.resultingDescriptor
|
||||
if (callableDescriptor is PropertyDescriptor && isInlinedJavaConstProperty(callableDescriptor as VariableDescriptor)) {
|
||||
containsNonInlinedVals = true
|
||||
if (callableDescriptor is PropertyDescriptor && callableDescriptor !is JavaPropertyDescriptor && callableDescriptor.isConst) {
|
||||
containsKotlinConstVals = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitKtElement(element: KtElement) {
|
||||
if (!containsNonInlinedVals) {
|
||||
if (!containsKotlinConstVals) {
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun isInlinedJavaConstProperty(descriptor: VariableDescriptor): Boolean =
|
||||
(descriptor as? JavaPropertyDescriptor)?.isConst ?: false
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// FILE: test.kt
|
||||
fun test1(a: A) = a.X
|
||||
fun test2(a: A) = 1 + a.X
|
||||
fun test3(a: A) = 1 < a.X
|
||||
|
||||
// FILE: A.java
|
||||
public class A {
|
||||
public final int X = 42;
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 42
|
||||
// 0 43
|
||||
// 3 GETFIELD A.X
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// LANGUAGE_VERSION: 1.0
|
||||
// FILE: test.kt
|
||||
fun test1(a: A) = a.X
|
||||
fun test2(a: A) = 1 + a.X
|
||||
fun test3(a: A) = 1 < a.X
|
||||
|
||||
// FILE: A.java
|
||||
public class A {
|
||||
public final int X = 42;
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 42
|
||||
// 0 43
|
||||
// 3 GETFIELD A.X
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// LANGUAGE_VERSION: 1.1
|
||||
// FILE: test.kt
|
||||
fun test1(a: A) = a.X
|
||||
fun test2(a: A) = 1 + a.X
|
||||
fun test3(a: A) = 1 < a.X
|
||||
|
||||
// FILE: A.java
|
||||
public class A {
|
||||
public final int X = 42;
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 42
|
||||
// 0 43
|
||||
// 3 GETFIELD A.X
|
||||
@@ -1010,6 +1010,24 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noInlineNonStaticJavaField.kt")
|
||||
public void testNoInlineNonStaticJavaField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/constants/noInlineNonStaticJavaField.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noInlineNonStaticJavaField_lv10.kt")
|
||||
public void testNoInlineNonStaticJavaField_lv10() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/constants/noInlineNonStaticJavaField_lv10.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noInlineNonStaticJavaField_lv11.kt")
|
||||
public void testNoInlineNonStaticJavaField_lv11() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/constants/noInlineNonStaticJavaField_lv11.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullableByteAndShort.kt")
|
||||
public void testNullableByteAndShort() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/constants/nullableByteAndShort.kt");
|
||||
|
||||
Reference in New Issue
Block a user