Optimize const vals by inlining them at use sites
#KT-11734 Fixed #KT-13570 Fixed
This commit is contained in:
@@ -50,10 +50,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
|
||||
import org.jetbrains.kotlin.config.*;
|
||||
import org.jetbrains.kotlin.coroutines.CoroutineUtilKt;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
@@ -1438,14 +1435,17 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public StackValue visitConstantExpression(@NotNull KtConstantExpression expression, StackValue receiver) {
|
||||
ConstantValue<?> compileTimeValue = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext);
|
||||
ConstantValue<?> compileTimeValue = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
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);
|
||||
public static ConstantValue<?> getPrimitiveOrStringCompileTimeConstant(
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals) {
|
||||
ConstantValue<?> constant = getCompileTimeConstant(expression, bindingContext, false, shouldInlineConstVals);
|
||||
if (constant == null || ConstantExpressionEvaluatorKt.isStandaloneOnlyConstant(constant)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1453,22 +1453,26 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getCompileTimeConstant(@NotNull KtExpression expression, @NotNull BindingContext bindingContext) {
|
||||
return getCompileTimeConstant(expression, bindingContext, false);
|
||||
public static ConstantValue<?> getCompileTimeConstant(
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals) {
|
||||
return getCompileTimeConstant(expression, bindingContext, false, shouldInlineConstVals);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getCompileTimeConstant(
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull final BindingContext bindingContext,
|
||||
boolean takeUpConstValsAsConst
|
||||
boolean takeUpConstValsAsConst,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
CompileTimeConstant<?> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, bindingContext);
|
||||
if (compileTimeValue == null || compileTimeValue.getUsesNonConstValAsConstant()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!takeUpConstValsAsConst && compileTimeValue.getUsesVariableAsConstant()) {
|
||||
if (!shouldInlineConstVals && !takeUpConstValsAsConst && compileTimeValue.getUsesVariableAsConstant()) {
|
||||
final Ref<Boolean> containsNonInlinedVals = new Ref<Boolean>(false);
|
||||
KtVisitor constantChecker = new KtVisitor() {
|
||||
@Override
|
||||
@@ -2607,14 +2611,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
boolean skipPropertyAccessors;
|
||||
|
||||
PropertyDescriptor originalPropertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
||||
LanguageVersionSettings languageVersionSettings = state.getConfiguration().get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS);
|
||||
if (languageVersionSettings == null) {
|
||||
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT;
|
||||
}
|
||||
|
||||
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
|
||||
int flags = AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty);
|
||||
boolean isInlinedConst = propertyDescriptor.isConst() && languageVersionSettings.supportsFeature(LanguageFeature.InlineConstVals);
|
||||
boolean isInlinedConst = propertyDescriptor.isConst() && state.getShouldInlineConstVals();
|
||||
skipPropertyAccessors = isInlinedConst || (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
@@ -2635,7 +2635,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context, languageVersionSettings)) {
|
||||
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context, state.getShouldInlineConstVals())) {
|
||||
propertyDescriptor = context.getAccessorForSuperCallIfNeeded(propertyDescriptor, superCallTarget);
|
||||
|
||||
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
|
||||
@@ -2649,7 +2649,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (propertyDescriptor.isVar()) {
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
if (setter != null &&
|
||||
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context, languageVersionSettings) &&
|
||||
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context, state.getShouldInlineConstVals()) &&
|
||||
!isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper);
|
||||
}
|
||||
@@ -3523,7 +3523,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
expression.getRight(), reference);
|
||||
}
|
||||
else {
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext);
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
@@ -3666,7 +3666,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
private boolean isIntZero(KtExpression expr, Type exprType) {
|
||||
ConstantValue<?> exprValue = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext);
|
||||
ConstantValue<?> exprValue = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals());
|
||||
return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue());
|
||||
}
|
||||
|
||||
@@ -3796,7 +3796,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
public void invokeAppend(KtExpression expr) {
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext);
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals());
|
||||
|
||||
if (compileTimeConstant == null && expr instanceof KtBinaryExpression) {
|
||||
KtBinaryExpression binaryExpression = (KtBinaryExpression) expr;
|
||||
@@ -3839,7 +3839,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public StackValue visitPrefixExpression(@NotNull KtPrefixExpression expression, @NotNull StackValue receiver) {
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext);
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
|
||||
@@ -649,12 +649,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private Type genPropertyOnStack(InstructionAdapter iv, MethodContext context, @NotNull PropertyDescriptor propertyDescriptor, int index) {
|
||||
iv.load(index, classAsmType);
|
||||
LanguageVersionSettings settings = state.getConfiguration().get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS);
|
||||
if (settings == null) {
|
||||
settings = LanguageVersionSettingsImpl.DEFAULT;
|
||||
}
|
||||
if (couldUseDirectAccessToProperty(propertyDescriptor, /* forGetter = */ true,
|
||||
/* isDelegated = */ false, context, settings)) {
|
||||
/* isDelegated = */ false, context, state.getShouldInlineConstVals())) {
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getType());
|
||||
String fieldName = ((FieldOwnerContext) context.getParentContext()).getFieldName(propertyDescriptor, false);
|
||||
iv.getfield(classAsmType.getInternalName(), fieldName, type.getDescriptor());
|
||||
|
||||
@@ -185,9 +185,9 @@ public class JvmCodegenUtil {
|
||||
boolean forGetter,
|
||||
boolean isDelegated,
|
||||
@NotNull MethodContext contextBeforeInline,
|
||||
@NotNull LanguageVersionSettings languageVersionSettings
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.InlineConstVals) && property.isConst()) return true;
|
||||
if (shouldInlineConstVals && property.isConst()) return true;
|
||||
|
||||
if (KotlinTypeMapper.isAccessor(property)) return false;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
@@ -461,7 +462,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
KtExpression initializer = property.getInitializer();
|
||||
|
||||
ConstantValue<?> initializerValue =
|
||||
initializer != null ? ExpressionCodegen.getCompileTimeConstant(initializer, bindingContext) : null;
|
||||
initializer != null ? ExpressionCodegen.getCompileTimeConstant(initializer, bindingContext, state.getShouldInlineConstVals()) : null;
|
||||
// we must write constant values for fields in light classes,
|
||||
// because Java's completion for annotation arguments uses this information
|
||||
if (initializerValue == null) return state.getClassBuilderMode().generateBodies;
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter;
|
||||
@@ -228,7 +229,8 @@ public class PropertyCodegen {
|
||||
|
||||
KtExpression defaultValue = p.getDefaultValue();
|
||||
if (defaultValue != null) {
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext, true);
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(
|
||||
defaultValue, bindingContext, true, state.getShouldInlineConstVals());
|
||||
assert !state.getClassBuilderMode().generateBodies || constant != null
|
||||
: "Default value for annotation parameter should be compile time value: " + defaultValue.getText();
|
||||
if (constant != null) {
|
||||
|
||||
@@ -30,10 +30,11 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.ValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -1199,7 +1200,7 @@ public abstract class StackValue {
|
||||
if (getter == null) {
|
||||
assert fieldName != null : "Property should have either a getter or a field name: " + descriptor;
|
||||
assert backingFieldOwner != null : "Property should have either a getter or a backingFieldOwner: " + descriptor;
|
||||
if (inlineJavaConstantIfNeeded(type, v)) return;
|
||||
if (inlineConstantIfNeeded(type, v)) return;
|
||||
|
||||
v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD,
|
||||
backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor());
|
||||
@@ -1227,15 +1228,24 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean inlineJavaConstantIfNeeded(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
if (!JvmCodegenUtil.isInlinedJavaConstProperty(descriptor)) return false;
|
||||
private boolean inlineConstantIfNeeded(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
if (JvmCodegenUtil.isInlinedJavaConstProperty(descriptor)) {
|
||||
return inlineConstant(type, v);
|
||||
}
|
||||
|
||||
if (descriptor.isConst() && codegen.getState().getShouldInlineConstVals()) {
|
||||
return inlineConstant(type, v);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean inlineConstant(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
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;
|
||||
"Const property should have primitive or string type: " + descriptor;
|
||||
assert isStaticPut : "Const property should be static" + descriptor;
|
||||
|
||||
JavaPropertyDescriptor javaPropertyDescriptor = (JavaPropertyDescriptor) descriptor;
|
||||
ConstantValue<?> constantValue = javaPropertyDescriptor.getCompileTimeInitializer();
|
||||
ConstantValue<?> constantValue = descriptor.getCompileTimeInitializer();
|
||||
if (constantValue == null) return false;
|
||||
|
||||
Object value = constantValue.getValue();
|
||||
|
||||
+5
-1
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.coroutines.CoroutineUtilKt;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
@@ -83,6 +84,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
private final JvmRuntimeTypes runtimeTypes;
|
||||
private final JvmFileClassesProvider fileClassesProvider;
|
||||
private final TypeMappingConfiguration<Type> typeMappingConfiguration;
|
||||
private final boolean shouldInlineConstVals;
|
||||
|
||||
public CodegenAnnotatingVisitor(@NotNull GenerationState state) {
|
||||
this.bindingTrace = state.getBindingTrace();
|
||||
@@ -91,6 +93,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
this.runtimeTypes = state.getJvmRuntimeTypes();
|
||||
this.fileClassesProvider = state.getFileClassesProvider();
|
||||
this.typeMappingConfiguration = state.getTypeMapper().getTypeMappingConfiguration();
|
||||
this.shouldInlineConstVals = state.getShouldInlineConstVals();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -645,7 +648,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
WhenByEnumsMapping mapping = new WhenByEnumsMapping(classDescriptor, currentClassName, fieldNumber);
|
||||
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext)) {
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext, shouldInlineConstVals)) {
|
||||
if (constant instanceof NullValue) continue;
|
||||
|
||||
assert constant instanceof EnumValue : "expression in when should be EnumValue";
|
||||
@@ -662,6 +665,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
SwitchCodegenUtil.checkAllItemsAreConstantsSatisfying(
|
||||
expression,
|
||||
bindingContext,
|
||||
shouldInlineConstVals,
|
||||
new Function1<ConstantValue<?>, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(@NotNull ConstantValue<?> constant) {
|
||||
|
||||
@@ -30,10 +30,7 @@ import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCache
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
@@ -169,6 +166,11 @@ class GenerationState @JvmOverloads constructor(
|
||||
|
||||
val generateParametersMetadata: Boolean = configuration.getBoolean(JVMConfigurationKeys.PARAMETERS_METADATA)
|
||||
|
||||
val shouldInlineConstVals = run {
|
||||
val settings = configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS) ?: LanguageVersionSettingsImpl.DEFAULT
|
||||
settings.supportsFeature(LanguageFeature.InlineConstVals)
|
||||
}
|
||||
|
||||
init {
|
||||
this.interceptedBuilderFactory = builderFactory
|
||||
.wrapWith(
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.when;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.kotlin.codegen.FrameMap;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.psi.KtWhenEntry;
|
||||
import org.jetbrains.kotlin.psi.KtWhenExpression;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -98,7 +99,7 @@ abstract public class SwitchCodegen {
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
Label entryLabel = new Label();
|
||||
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext)) {
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext, codegen.getState().getShouldInlineConstVals())) {
|
||||
if (constant instanceof NullValue) continue;
|
||||
processConstant(constant, entryLabel);
|
||||
}
|
||||
@@ -156,7 +157,7 @@ abstract public class SwitchCodegen {
|
||||
private int findNullEntryIndex(@NotNull KtWhenExpression expression) {
|
||||
int entryIndex = 0;
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext)) {
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext, codegen.getState().getShouldInlineConstVals())) {
|
||||
if (constant instanceof NullValue) {
|
||||
return entryIndex;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public class SwitchCodegenUtil {
|
||||
public static boolean checkAllItemsAreConstantsSatisfying(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals,
|
||||
Function1<ConstantValue<?>, Boolean> predicate
|
||||
) {
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
@@ -49,7 +50,7 @@ public class SwitchCodegenUtil {
|
||||
|
||||
if (patternExpression == null) return false;
|
||||
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext);
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext, shouldInlineConstVals);
|
||||
if (constant == null || !predicate.invoke(constant)) {
|
||||
return false;
|
||||
}
|
||||
@@ -62,12 +63,13 @@ public class SwitchCodegenUtil {
|
||||
@NotNull
|
||||
public static Iterable<ConstantValue<?>> getAllConstants(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull BindingContext bindingContext
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
List<ConstantValue<?>> result = new ArrayList<ConstantValue<?>>();
|
||||
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
addConstantsFromEntry(result, entry, bindingContext);
|
||||
addConstantsFromEntry(result, entry, bindingContext, shouldInlineConstVals);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -76,7 +78,8 @@ public class SwitchCodegenUtil {
|
||||
private static void addConstantsFromEntry(
|
||||
@NotNull List<ConstantValue<?>> result,
|
||||
@NotNull KtWhenEntry entry,
|
||||
@NotNull BindingContext bindingContext
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
for (KtWhenCondition condition : entry.getConditions()) {
|
||||
if (!(condition instanceof KtWhenConditionWithExpression)) continue;
|
||||
@@ -84,17 +87,18 @@ public class SwitchCodegenUtil {
|
||||
KtExpression patternExpression = ((KtWhenConditionWithExpression) condition).getExpression();
|
||||
|
||||
assert patternExpression != null : "expression in when should not be null";
|
||||
result.add(ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext));
|
||||
result.add(ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext, shouldInlineConstVals));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Iterable<ConstantValue<?>> getConstantsFromEntry(
|
||||
@NotNull KtWhenEntry entry,
|
||||
@NotNull BindingContext bindingContext
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
List<ConstantValue<?>> result = new ArrayList<ConstantValue<?>>();
|
||||
addConstantsFromEntry(result, entry, bindingContext);
|
||||
addConstantsFromEntry(result, entry, bindingContext, shouldInlineConstVals);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -106,7 +110,8 @@ public class SwitchCodegenUtil {
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
BindingContext bindingContext = codegen.getBindingContext();
|
||||
if (!isThereConstantEntriesButNulls(expression, bindingContext)) {
|
||||
boolean shouldInlineConstVals = codegen.getState().getShouldInlineConstVals();
|
||||
if (!isThereConstantEntriesButNulls(expression, bindingContext, shouldInlineConstVals)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -118,11 +123,11 @@ public class SwitchCodegenUtil {
|
||||
return new EnumSwitchCodegen(expression, isStatement, isExhaustive, codegen, mapping);
|
||||
}
|
||||
|
||||
if (isIntegralConstantsSwitch(expression, subjectType, bindingContext)) {
|
||||
if (isIntegralConstantsSwitch(expression, subjectType, bindingContext, shouldInlineConstVals)) {
|
||||
return new IntegralConstantsSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
if (isStringConstantsSwitch(expression, subjectType, bindingContext)) {
|
||||
if (isStringConstantsSwitch(expression, subjectType, bindingContext, shouldInlineConstVals)) {
|
||||
return new StringSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
@@ -131,9 +136,10 @@ public class SwitchCodegenUtil {
|
||||
|
||||
private static boolean isThereConstantEntriesButNulls(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull BindingContext bindingContext
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
for (ConstantValue<?> constant : getAllConstants(expression, bindingContext)) {
|
||||
for (ConstantValue<?> constant : getAllConstants(expression, bindingContext, shouldInlineConstVals)) {
|
||||
if (constant != null && !(constant instanceof NullValue)) return true;
|
||||
}
|
||||
|
||||
@@ -143,7 +149,8 @@ public class SwitchCodegenUtil {
|
||||
private static boolean isIntegralConstantsSwitch(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull Type subjectType,
|
||||
@NotNull BindingContext bindingContext
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
int typeSort = subjectType.getSort();
|
||||
|
||||
@@ -151,7 +158,7 @@ public class SwitchCodegenUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, new Function1<ConstantValue<?>, Boolean>() {
|
||||
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, shouldInlineConstVals, new Function1<ConstantValue<?>, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(
|
||||
@NotNull ConstantValue<?> constant
|
||||
@@ -164,14 +171,15 @@ public class SwitchCodegenUtil {
|
||||
private static boolean isStringConstantsSwitch(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull Type subjectType,
|
||||
@NotNull BindingContext bindingContext
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
|
||||
if (!subjectType.getClassName().equals(String.class.getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, new Function1<ConstantValue<?>, Boolean>() {
|
||||
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, shouldInlineConstVals, new Function1<ConstantValue<?>, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(
|
||||
@NotNull ConstantValue<?> constant
|
||||
|
||||
Reference in New Issue
Block a user