Inline preevaluated string and primitive only constants in compilation time, don't inline const references in non-annotation context, fix for KT-11025: Don't inline const val in compare instuctions
#KT-11025 Fixed
This commit is contained in:
@@ -19,6 +19,7 @@ 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;
|
||||
@@ -71,6 +72,7 @@ import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
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;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
@@ -1235,11 +1237,20 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public StackValue visitConstantExpression(@NotNull KtConstantExpression expression, StackValue receiver) {
|
||||
ConstantValue<?> compileTimeValue = getCompileTimeConstant(expression, bindingContext);
|
||||
ConstantValue<?> compileTimeValue = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext);
|
||||
assert compileTimeValue != null;
|
||||
return StackValue.constant(compileTimeValue.getValue(), expressionType(expression));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getPrimitiveOrStringCompileTimeConstant(@NotNull KtExpression expression, @NotNull BindingContext bindingContext) {
|
||||
ConstantValue<?> constant = getCompileTimeConstant(expression, bindingContext, false);
|
||||
if (constant == null || ConstantExpressionEvaluatorKt.isStandaloneOnlyConstant(constant)) {
|
||||
return null;
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getCompileTimeConstant(@NotNull KtExpression expression, @NotNull BindingContext bindingContext) {
|
||||
return getCompileTimeConstant(expression, bindingContext, false);
|
||||
@@ -1248,15 +1259,45 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@Nullable
|
||||
public static ConstantValue<?> getCompileTimeConstant(
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean checkPure
|
||||
@NotNull final BindingContext bindingContext,
|
||||
boolean takeUpConstValsAsConst
|
||||
) {
|
||||
CompileTimeConstant<?> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, bindingContext);
|
||||
if (compileTimeValue == null) {
|
||||
if (compileTimeValue == null || compileTimeValue.getUsesNonConstValAsConstant()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (compileTimeValue.getUsesNonConstValAsConstant() || (checkPure && !compileTimeValue.getParameters().isPure())) return null;
|
||||
if (!takeUpConstValsAsConst && compileTimeValue.getUsesVariableAsConstant()) {
|
||||
final Ref<Boolean> containsNonInlinedVals = new Ref<Boolean>(false);
|
||||
KtVisitor constantChecker = new KtVisitor() {
|
||||
@Override
|
||||
public Object visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression, Object data) {
|
||||
ResolvedCall resolvedCall = CallUtilKt.getResolvedCall(expression, bindingContext);
|
||||
if (resolvedCall != null) {
|
||||
CallableDescriptor callableDescriptor = resolvedCall.getResultingDescriptor();
|
||||
if (callableDescriptor instanceof PropertyDescriptor &&
|
||||
!JvmCodegenUtil.isInlinedJavaConstProperty((VariableDescriptor) callableDescriptor)) {
|
||||
containsNonInlinedVals.set(true);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitKtElement(@NotNull KtElement element, Object data) {
|
||||
if (!containsNonInlinedVals.get()) {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
expression.accept(constantChecker);
|
||||
|
||||
if (containsNonInlinedVals.get()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
KotlinType expectedType = bindingContext.getType(expression);
|
||||
return compileTimeValue.toConstantValue(expectedType);
|
||||
@@ -2902,7 +2943,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
expression.getRight(), reference);
|
||||
}
|
||||
else {
|
||||
ConstantValue<?> compileTimeConstant = getCompileTimeConstant(expression, bindingContext, true);
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext);
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
@@ -3025,7 +3066,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
private boolean isIntZero(KtExpression expr, Type exprType) {
|
||||
ConstantValue<?> exprValue = getCompileTimeConstant(expr, bindingContext);
|
||||
ConstantValue<?> exprValue = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext);
|
||||
return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue());
|
||||
}
|
||||
|
||||
@@ -3179,7 +3220,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public StackValue visitPrefixExpression(@NotNull KtPrefixExpression expression, @NotNull StackValue receiver) {
|
||||
ConstantValue<?> compileTimeConstant = getCompileTimeConstant(expression, bindingContext, true);
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext);
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.RootContext;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
@@ -217,4 +218,9 @@ public class JvmCodegenUtil {
|
||||
public static String getMappingFileName(@NotNull String moduleName) {
|
||||
return "META-INF/" + moduleName + "." + ModuleMapping.MAPPING_FILE_EXT;
|
||||
}
|
||||
|
||||
public static boolean isInlinedJavaConstProperty(VariableDescriptor descriptor) {
|
||||
if (!(descriptor instanceof JavaPropertyDescriptor)) return false;
|
||||
return descriptor.isConst();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ public class PropertyCodegen {
|
||||
|
||||
KtExpression defaultValue = p.getDefaultValue();
|
||||
if (defaultValue != null) {
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext);
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext, true);
|
||||
assert state.getClassBuilderMode() != ClassBuilderMode.FULL || constant != null
|
||||
: "Default value for annotation parameter should be compile time value: " + defaultValue.getText();
|
||||
if (constant != null) {
|
||||
|
||||
@@ -1131,9 +1131,11 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
private boolean inlineJavaConstantIfNeeded(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
if (!isStaticPut) return false;
|
||||
if (!(descriptor instanceof JavaPropertyDescriptor)) return false;
|
||||
if (!AsmUtil.isPrimitive(this.type) && !this.type.equals(Type.getObjectType("java/lang/String"))) return false;
|
||||
if (!JvmCodegenUtil.isInlinedJavaConstProperty(descriptor)) return false;
|
||||
|
||||
assert AsmUtil.isPrimitive(this.type) || AsmTypes.JAVA_STRING_TYPE.equals(this.type) :
|
||||
"Java const property should have primitive or string type: " + descriptor;
|
||||
assert isStaticPut : "Java const property should be static" + descriptor;
|
||||
|
||||
JavaPropertyDescriptor javaPropertyDescriptor = (JavaPropertyDescriptor) descriptor;
|
||||
ConstantValue<?> constantValue = javaPropertyDescriptor.getCompileTimeInitializer();
|
||||
|
||||
Reference in New Issue
Block a user