Split CompileTimeConstant into two entities

1. ConstantValue
	* just holds some value and its type
	* implementations for concrete constants
2. CompileTimeConstant
	* is only produced by ConstantExpressionEvaluator
	* has additional flags (canBeUsedInAnnotation etc)
	* has two implementations TypedCompileTimeConstant containing a constant value
		and IntegerValueConstant which does not have exact type
	* can be converted to ConstantValue

Adjustt usages to use ConstantValue if flags are not needed
Add tests for some uncovered cases
This commit is contained in:
Pavel V. Talanov
2015-07-07 14:56:19 +03:00
parent 155f00578d
commit c313887641
134 changed files with 791 additions and 907 deletions
@@ -187,9 +187,9 @@ public abstract class AnnotationCodegen {
return !type.isMarkedNullable() && classifier instanceof TypeParameterDescriptor && TypeUtils.hasNullableSuperType(type);
}
public void generateAnnotationDefaultValue(@NotNull CompileTimeConstant value, @NotNull JetType expectedType) {
public void generateAnnotationDefaultValue(@NotNull ConstantValue<?> value, @NotNull JetType expectedType) {
AnnotationVisitor visitor = visitAnnotation(null, false); // Parameters are unimportant
genCompileTimeValue(null, value, expectedType, visitor);
genCompileTimeValue(null, value, visitor);
visitor.visitEnd();
}
@@ -212,17 +212,16 @@ public abstract class AnnotationCodegen {
}
private void genAnnotationArguments(AnnotationDescriptor annotationDescriptor, AnnotationVisitor annotationVisitor) {
for (Map.Entry<ValueParameterDescriptor, CompileTimeConstant<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
ValueParameterDescriptor descriptor = entry.getKey();
String name = descriptor.getName().asString();
genCompileTimeValue(name, entry.getValue(), descriptor.getType(), annotationVisitor);
genCompileTimeValue(name, entry.getValue(), annotationVisitor);
}
}
private void genCompileTimeValue(
@Nullable final String name,
@NotNull CompileTimeConstant<?> value,
@NotNull final JetType expectedType,
@NotNull ConstantValue<?> value,
@NotNull final AnnotationVisitor annotationVisitor
) {
AnnotationArgumentVisitor argumentVisitor = new AnnotationArgumentVisitor<Void, Void>() {
@@ -281,8 +280,8 @@ public abstract class AnnotationCodegen {
@Override
public Void visitArrayValue(ArrayValue value, Void data) {
AnnotationVisitor visitor = annotationVisitor.visitArray(name);
for (CompileTimeConstant<?> argument : value.getValue()) {
genCompileTimeValue(null, argument, value.getType(), visitor);
for (ConstantValue<?> argument : value.getValue()) {
genCompileTimeValue(null, argument, visitor);
}
visitor.visitEnd();
return null;
@@ -303,14 +302,7 @@ public abstract class AnnotationCodegen {
return null;
}
@Override
public Void visitNumberTypeValue(IntegerValueTypeConstant value, Void data) {
Object numberType = value.getValue(expectedType);
annotationVisitor.visit(name, numberType);
return null;
}
private Void visitSimpleValue(CompileTimeConstant value) {
private Void visitSimpleValue(ConstantValue<?> value) {
annotationVisitor.visit(name, value.getValue());
return null;
}
@@ -325,7 +317,7 @@ public abstract class AnnotationCodegen {
return visitUnsupportedValue(value);
}
private Void visitUnsupportedValue(CompileTimeConstant value) {
private Void visitUnsupportedValue(ConstantValue<?> value) {
throw new IllegalStateException("Don't know how to compile annotation value " + value);
}
};
@@ -349,7 +341,7 @@ public abstract class AnnotationCodegen {
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
AnnotationDescriptor kotlinAnnotation = descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation);
if (kotlinAnnotation != null) {
for (Map.Entry<ValueParameterDescriptor, CompileTimeConstant<?>> argument: kotlinAnnotation.getAllValueArguments().entrySet()) {
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> argument: kotlinAnnotation.getAllValueArguments().entrySet()) {
if ("retention".equals(argument.getKey().getName().asString()) && argument.getValue() instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) argument.getValue()).getValue();
JetType classObjectType = getClassObjectType(enumEntry);
@@ -366,9 +358,9 @@ public abstract class AnnotationCodegen {
}
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
if (retentionAnnotation != null) {
Collection<CompileTimeConstant<?>> valueArguments = retentionAnnotation.getAllValueArguments().values();
Collection<ConstantValue<?>> valueArguments = retentionAnnotation.getAllValueArguments().values();
if (!valueArguments.isEmpty()) {
CompileTimeConstant<?> compileTimeConstant = valueArguments.iterator().next();
ConstantValue<?> compileTimeConstant = valueArguments.iterator().next();
if (compileTimeConstant instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
JetType classObjectType = getClassObjectType(enumEntry);
@@ -49,12 +49,12 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.ScriptCodeDescriptor;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesPackage;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
@@ -68,9 +68,8 @@ import org.jetbrains.kotlin.resolve.calls.model.*;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.constants.evaluate.EvaluatePackage;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
@@ -1292,20 +1291,19 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitConstantExpression(@NotNull JetConstantExpression expression, StackValue receiver) {
CompileTimeConstant<?> compileTimeValue = getCompileTimeConstant(expression, bindingContext);
ConstantValue<?> compileTimeValue = getCompileTimeConstant(expression, bindingContext);
assert compileTimeValue != null;
return StackValue.constant(compileTimeValue.getValue(), expressionType(expression));
}
@Nullable
public static CompileTimeConstant getCompileTimeConstant(@NotNull JetExpression expression, @NotNull BindingContext bindingContext) {
public static ConstantValue<?> getCompileTimeConstant(@NotNull JetExpression expression, @NotNull BindingContext bindingContext) {
CompileTimeConstant<?> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, bindingContext);
if (compileTimeValue instanceof IntegerValueTypeConstant) {
JetType expectedType = bindingContext.getType(expression);
assert expectedType != null : "Expression is not type checked: " + expression.getText();
return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) compileTimeValue, expectedType);
if (compileTimeValue == null) {
return null;
}
return compileTimeValue;
JetType expectedType = bindingContext.getType(expression);
return compileTimeValue.toConstantValue(expectedType);
}
@Override
@@ -3012,7 +3010,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private boolean isIntZero(JetExpression expr, Type exprType) {
CompileTimeConstant<?> exprValue = getCompileTimeConstant(expr, bindingContext);
ConstantValue<?> exprValue = getCompileTimeConstant(expr, bindingContext);
return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue());
}
@@ -45,7 +45,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.KClassValue;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
@@ -538,7 +538,7 @@ public class FunctionCodegen {
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.throws"));
if (annotation == null) return ArrayUtil.EMPTY_STRING_ARRAY;
Collection<CompileTimeConstant<?>> values = annotation.getAllValueArguments().values();
Collection<ConstantValue<?>> values = annotation.getAllValueArguments().values();
if (values.isEmpty()) return ArrayUtil.EMPTY_STRING_ARRAY;
Object value = values.iterator().next();
@@ -547,9 +547,9 @@ public class FunctionCodegen {
List<String> strings = ContainerUtil.mapNotNull(
arrayValue.getValue(),
new Function<CompileTimeConstant<?>, String>() {
new Function<ConstantValue<?>, String>() {
@Override
public String fun(CompileTimeConstant<?> constant) {
public String fun(ConstantValue<?> constant) {
if (constant instanceof KClassValue) {
KClassValue classValue = (KClassValue) constant;
ClassDescriptor classDescriptor = DescriptorUtils.getClassDescriptorForType(classValue.getValue());
@@ -39,8 +39,7 @@ import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
@@ -379,26 +378,28 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
JetExpression initializer = property.getInitializer();
CompileTimeConstant<?> initializerValue;
if (property.isVar() && initializer != null) {
BindingTrace tempTrace = TemporaryBindingTrace.create(state.getBindingTrace(), "property initializer");
initializerValue = ConstantExpressionEvaluator.evaluate(initializer, tempTrace, propertyDescriptor.getType());
}
else {
initializerValue = propertyDescriptor.getCompileTimeInitializer();
}
ConstantValue<?> initializerValue = computeInitializerValue(property, propertyDescriptor, initializer);
// 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() != ClassBuilderMode.LIGHT_CLASSES;
//TODO: OPTIMIZATION: don't initialize static final fields
Object value = initializerValue instanceof IntegerValueTypeConstant
? ((IntegerValueTypeConstant) initializerValue).getValue(propertyDescriptor.getType())
: initializerValue.getValue();
JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor);
Type type = typeMapper.mapType(jetType);
return !skipDefaultValue(propertyDescriptor, value, type);
return !skipDefaultValue(propertyDescriptor, initializerValue.getValue(), type);
}
@Nullable
private ConstantValue<?> computeInitializerValue(
@NotNull JetProperty property,
@NotNull PropertyDescriptor propertyDescriptor,
@Nullable JetExpression initializer
) {
if (property.isVar() && initializer != null) {
BindingTrace tempTrace = TemporaryBindingTrace.create(state.getBindingTrace(), "property initializer");
return ConstantExpressionEvaluator.evaluateToConstantValue(initializer, tempTrace, propertyDescriptor.getType());
}
return propertyDescriptor.getCompileTimeInitializer();
}
@NotNull
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
import org.jetbrains.kotlin.types.ErrorUtils;
@@ -180,7 +180,7 @@ public class PropertyCodegen {
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
JetExpression defaultValue = p.getDefaultValue();
if (defaultValue != null) {
CompileTimeConstant<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext);
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext);
assert constant != null : "Default value for annotation parameter should be compile time value: " + defaultValue.getText();
AnnotationCodegen annotationCodegen = AnnotationCodegen.forAnnotationDefaultValue(mv, typeMapper);
annotationCodegen.generateAnnotationDefaultValue(constant, descriptor.getType());
@@ -311,7 +311,7 @@ public class PropertyCodegen {
Object value = null;
if (shouldWriteFieldInitializer(propertyDescriptor)) {
CompileTimeConstant<?> initializer = propertyDescriptor.getCompileTimeInitializer();
ConstantValue<?> initializer = propertyDescriptor.getCompileTimeInitializer();
if (initializer != null) {
value = initializer.getValue();
}
@@ -45,7 +45,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.EnumValue;
import org.jetbrains.kotlin.resolve.constants.NullValue;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
@@ -537,7 +537,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
WhenByEnumsMapping mapping = new WhenByEnumsMapping(classDescriptor, currentClassName, fieldNumber);
for (CompileTimeConstant constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext)) {
for (ConstantValue<?> constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext)) {
if (constant instanceof NullValue) continue;
assert constant instanceof EnumValue : "expression in when should be EnumValue";
@@ -554,9 +554,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
SwitchCodegenUtil.checkAllItemsAreConstantsSatisfying(
expression,
bindingContext,
new Function1<CompileTimeConstant, Boolean>() {
new Function1<ConstantValue<?>, Boolean>() {
@Override
public Boolean invoke(@NotNull CompileTimeConstant constant) {
public Boolean invoke(@NotNull ConstantValue<?> constant) {
return constant instanceof EnumValue || constant instanceof NullValue;
}
}
@@ -54,7 +54,7 @@ import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.StringValue;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
@@ -721,10 +721,10 @@ public class JetTypeMapper {
AnnotationDescriptor platformNameAnnotation = descriptor.getAnnotations().findAnnotation(new FqName("kotlin.platform.platformName"));
if (platformNameAnnotation == null) return null;
Map<ValueParameterDescriptor, CompileTimeConstant<?>> arguments = platformNameAnnotation.getAllValueArguments();
Map<ValueParameterDescriptor, ConstantValue<?>> arguments = platformNameAnnotation.getAllValueArguments();
if (arguments.isEmpty()) return null;
CompileTimeConstant<?> name = arguments.values().iterator().next();
ConstantValue<?> name = arguments.values().iterator().next();
if (!(name instanceof StringValue)) return null;
return ((StringValue) name).getValue();
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.when;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.psi.JetWhenExpression;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.EnumValue;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
@@ -58,7 +58,7 @@ public class EnumSwitchCodegen extends SwitchCodegen {
}
@Override
protected void processConstant(@NotNull CompileTimeConstant constant, @NotNull Label entryLabel) {
protected void processConstant(@NotNull ConstantValue<?> constant, @NotNull Label entryLabel) {
assert constant instanceof EnumValue : "guaranteed by usage contract";
putTransitionOnce(mapping.getIndexByEntry((EnumValue) constant), entryLabel);
}
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.when;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.psi.JetWhenExpression;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.org.objectweb.asm.Label;
public class IntegralConstantsSwitchCodegen extends SwitchCodegen {
@@ -32,7 +32,7 @@ public class IntegralConstantsSwitchCodegen extends SwitchCodegen {
}
@Override
protected void processConstant(@NotNull CompileTimeConstant constant, @NotNull Label entryLabel) {
protected void processConstant(@NotNull ConstantValue<?> constant, @NotNull Label entryLabel) {
assert constant.getValue() != null : "constant value should not be null";
int value = (constant.getValue() instanceof Number)
? ((Number) constant.getValue()).intValue()
@@ -21,7 +21,7 @@ import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.psi.JetWhenExpression;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.StringValue;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
@@ -47,7 +47,7 @@ public class StringSwitchCodegen extends SwitchCodegen {
@Override
protected void processConstant(
@NotNull CompileTimeConstant constant, @NotNull Label entryLabel
@NotNull ConstantValue<?> constant, @NotNull Label entryLabel
) {
assert constant instanceof StringValue : "guaranteed by usage contract";
int hashCode = constant.hashCode();
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.FrameMap;
import org.jetbrains.kotlin.psi.JetWhenEntry;
import org.jetbrains.kotlin.psi.JetWhenExpression;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.NullValue;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeUtils;
@@ -96,7 +96,7 @@ abstract public class SwitchCodegen {
for (JetWhenEntry entry : expression.getEntries()) {
Label entryLabel = new Label();
for (CompileTimeConstant constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext)) {
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext)) {
if (constant instanceof NullValue) continue;
processConstant(constant, entryLabel);
}
@@ -110,7 +110,7 @@ abstract public class SwitchCodegen {
}
abstract protected void processConstant(
@NotNull CompileTimeConstant constant,
@NotNull ConstantValue<?> constant,
@NotNull Label entryLabel
);
@@ -154,7 +154,7 @@ abstract public class SwitchCodegen {
private int findNullEntryIndex(@NotNull JetWhenExpression expression) {
int entryIndex = 0;
for (JetWhenEntry entry : expression.getEntries()) {
for (CompileTimeConstant constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext)) {
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext)) {
if (constant instanceof NullValue) {
return entryIndex;
}
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant;
import org.jetbrains.kotlin.resolve.constants.NullValue;
import org.jetbrains.kotlin.resolve.constants.StringValue;
@@ -36,7 +36,7 @@ public class SwitchCodegenUtil {
public static boolean checkAllItemsAreConstantsSatisfying(
@NotNull JetWhenExpression expression,
@NotNull BindingContext bindingContext,
Function1<CompileTimeConstant, Boolean> predicate
Function1<ConstantValue<?>, Boolean> predicate
) {
for (JetWhenEntry entry : expression.getEntries()) {
for (JetWhenCondition condition : entry.getConditions()) {
@@ -49,7 +49,7 @@ public class SwitchCodegenUtil {
if (patternExpression == null) return false;
CompileTimeConstant constant = ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext);
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext);
if (constant == null || !predicate.invoke(constant)) {
return false;
}
@@ -60,11 +60,11 @@ public class SwitchCodegenUtil {
}
@NotNull
public static Iterable<CompileTimeConstant> getAllConstants(
public static Iterable<ConstantValue<?>> getAllConstants(
@NotNull JetWhenExpression expression,
@NotNull BindingContext bindingContext
) {
List<CompileTimeConstant> result = new ArrayList<CompileTimeConstant>();
List<ConstantValue<?>> result = new ArrayList<ConstantValue<?>>();
for (JetWhenEntry entry : expression.getEntries()) {
addConstantsFromEntry(result, entry, bindingContext);
@@ -74,7 +74,7 @@ public class SwitchCodegenUtil {
}
private static void addConstantsFromEntry(
@NotNull List<CompileTimeConstant> result,
@NotNull List<ConstantValue<?>> result,
@NotNull JetWhenEntry entry,
@NotNull BindingContext bindingContext
) {
@@ -89,11 +89,11 @@ public class SwitchCodegenUtil {
}
@NotNull
public static Iterable<CompileTimeConstant> getConstantsFromEntry(
public static Iterable<ConstantValue<?>> getConstantsFromEntry(
@NotNull JetWhenEntry entry,
@NotNull BindingContext bindingContext
) {
List<CompileTimeConstant> result = new ArrayList<CompileTimeConstant>();
List<ConstantValue<?>> result = new ArrayList<ConstantValue<?>>();
addConstantsFromEntry(result, entry, bindingContext);
return result;
}
@@ -132,7 +132,7 @@ public class SwitchCodegenUtil {
@NotNull JetWhenExpression expression,
@NotNull BindingContext bindingContext
) {
for (CompileTimeConstant constant : getAllConstants(expression, bindingContext)) {
for (ConstantValue<?> constant : getAllConstants(expression, bindingContext)) {
if (constant != null && !(constant instanceof NullValue)) return true;
}
@@ -150,10 +150,10 @@ public class SwitchCodegenUtil {
return false;
}
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, new Function1<CompileTimeConstant, Boolean>() {
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, new Function1<ConstantValue<?>, Boolean>() {
@Override
public Boolean invoke(
@NotNull CompileTimeConstant constant
@NotNull ConstantValue<?> constant
) {
return constant instanceof IntegerValueConstant;
}
@@ -170,10 +170,10 @@ public class SwitchCodegenUtil {
return false;
}
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, new Function1<CompileTimeConstant, Boolean>() {
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, new Function1<ConstantValue<?>, Boolean>() {
@Override
public Boolean invoke(
@NotNull CompileTimeConstant constant
@NotNull ConstantValue<?> constant
) {
return constant instanceof StringValue || constant instanceof NullValue;
}
@@ -1,56 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.java.structure.impl;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.load.java.structure.JavaField;
import org.jetbrains.kotlin.load.java.structure.JavaPropertyInitializerEvaluator;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantFactory;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
public class JavaPropertyInitializerEvaluatorImpl implements JavaPropertyInitializerEvaluator {
@Nullable
@Override
public CompileTimeConstant<?> getInitializerConstant(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor) {
PsiExpression initializer = ((JavaFieldImpl) field).getInitializer();
Object evaluatedExpression = JavaConstantExpressionEvaluator.computeConstantExpression(initializer, false);
if (evaluatedExpression != null) {
CompileTimeConstantFactory factory = new CompileTimeConstantFactory(
new CompileTimeConstant.Parameters.Impl(
ConstantExpressionEvaluator.isPropertyCompileTimeConstant(descriptor),
false,
true
), DescriptorUtilPackage.getBuiltIns(descriptor));
return factory.createCompileTimeConstant(evaluatedExpression, descriptor.getType());
}
return null;
}
@Override
public boolean isNotNullCompileTimeConstant(@NotNull JavaField field) {
// PsiUtil.isCompileTimeConstant returns false for null-initialized fields,
// see com.intellij.psi.util.IsConstantExpressionVisitor.visitLiteralExpression()
return PsiUtil.isCompileTimeConstant(((JavaFieldImpl) field).getPsi());
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.java.structure.impl
import com.intellij.psi.impl.JavaConstantExpressionEvaluator
import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.load.java.structure.JavaPropertyInitializerEvaluator
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
public class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator {
override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? {
val initializer = (field as JavaFieldImpl).getInitializer()
val evaluated = JavaConstantExpressionEvaluator.computeConstantExpression(initializer, false) ?: return null
val factory = ConstantValueFactory(descriptor.builtIns)
when (evaluated) {
//Note: evaluated expression may be of class that does not match field type in some cases
// tested for Int, left other checks just in case
is Byte, is Short, is Int, is Long -> {
return factory.createIntegerConstantValue((evaluated as Number).toLong(), descriptor.getType())
}
else -> {
return factory.createConstantValue(evaluated)
}
}
}
override fun isNotNullCompileTimeConstant(field: JavaField): Boolean {
// PsiUtil.isCompileTimeConstant returns false for null-initialized fields,
// see com.intellij.psi.util.IsConstantExpressionVisitor.visitLiteralExpression()
return PsiUtil.isCompileTimeConstant((field as JavaFieldImpl).getPsi())
}
}
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
@@ -210,16 +211,16 @@ public class AnnotationResolver {
}
@NotNull
public static Map<ValueParameterDescriptor, CompileTimeConstant<?>> resolveAnnotationArguments(
public static Map<ValueParameterDescriptor, ConstantValue<?>> resolveAnnotationArguments(
@NotNull ResolvedCall<?> resolvedCall,
@NotNull BindingTrace trace
) {
Map<ValueParameterDescriptor, CompileTimeConstant<?>> arguments = new HashMap<ValueParameterDescriptor, CompileTimeConstant<?>>();
Map<ValueParameterDescriptor, ConstantValue<?>> arguments = new HashMap<ValueParameterDescriptor, ConstantValue<?>>();
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument : resolvedCall.getValueArguments().entrySet()) {
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
ResolvedValueArgument resolvedArgument = descriptorToArgument.getValue();
CompileTimeConstant<?> value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument);
ConstantValue<?> value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument);
if (value != null) {
arguments.put(parameterDescriptor, value);
}
@@ -228,32 +229,30 @@ public class AnnotationResolver {
}
@Nullable
public static CompileTimeConstant<?> getAnnotationArgumentValue(
public static ConstantValue<?> getAnnotationArgumentValue(
BindingTrace trace,
ValueParameterDescriptor parameterDescriptor,
ResolvedValueArgument resolvedArgument
) {
JetType varargElementType = parameterDescriptor.getVarargElementType();
boolean argumentsAsVararg = varargElementType != null && !hasSpread(resolvedArgument);
List<CompileTimeConstant<?>> constants = resolveValueArguments(
resolvedArgument, argumentsAsVararg ? varargElementType : parameterDescriptor.getType(), trace);
final JetType constantType = argumentsAsVararg ? varargElementType : parameterDescriptor.getType();
List<CompileTimeConstant<?>> compileTimeConstants = resolveValueArguments(resolvedArgument, constantType, trace);
List<ConstantValue<?>> constants = KotlinPackage.map(compileTimeConstants, new Function1<CompileTimeConstant<?>, ConstantValue<?>>() {
@Override
public ConstantValue<?> invoke(CompileTimeConstant<?> constant) {
return constant.toConstantValue(constantType);
}
});
if (argumentsAsVararg) {
if (parameterDescriptor.declaresDefaultValue() && compileTimeConstants.isEmpty()) return null;
boolean usesVariableAsConstant = KotlinPackage.any(constants, new Function1<CompileTimeConstant<?>, Boolean>() {
@Override
public Boolean invoke(CompileTimeConstant<?> constant) {
return constant.usesVariableAsConstant();
}
});
if (parameterDescriptor.declaresDefaultValue() && constants.isEmpty()) return null;
return new ArrayValue(constants, parameterDescriptor.getType(), usesVariableAsConstant);
return new ArrayValue(constants, parameterDescriptor.getType());
}
else {
// we should actually get only one element, but just in case of getting many, we take the last one
return !constants.isEmpty() ? KotlinPackage.last(constants) : null;
return KotlinPackage.lastOrNull(constants);
}
}
@@ -280,7 +279,7 @@ public class AnnotationResolver {
}
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.getConstant(argumentExpression, trace.getBindingContext());
if (constant != null && constant.canBeUsedInAnnotations()) {
if (constant != null && constant.getCanBeUsedInAnnotations()) {
return;
}
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
import org.jetbrains.kotlin.resolve.scopes.*;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
@@ -735,8 +734,7 @@ public class BodyResolver {
JetScope propertyDeclarationInnerScope = JetScopeUtils.getPropertyDeclarationInnerScopeForInitializer(
propertyDescriptor, scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace);
JetType expectedTypeForInitializer = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
CompileTimeConstant<?> compileTimeInitializer = propertyDescriptor.getCompileTimeInitializer();
if (compileTimeInitializer == null) {
if (propertyDescriptor.getCompileTimeInitializer() == null) {
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer,
outerDataFlowInfo, trace);
}
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.psi.JetTypeReference;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.BooleanValue;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeProjection;
@@ -113,7 +115,7 @@ public class CompileTimeConstantUtils {
annotatedDescriptor.getAnnotations().findAnnotation(new FqName("kotlin.jvm.internal.Intrinsic"));
if (intrinsicAnnotation == null) return null;
Collection<CompileTimeConstant<?>> values = intrinsicAnnotation.getAllValueArguments().values();
Collection<ConstantValue<?>> values = intrinsicAnnotation.getAllValueArguments().values();
if (values.isEmpty()) return null;
Object value = values.iterator().next().getValue();
@@ -132,9 +134,13 @@ public class CompileTimeConstantUtils {
if (expression == null) return false;
CompileTimeConstant<?> compileTimeConstant =
ConstantExpressionEvaluator.evaluate(expression, trace, KotlinBuiltIns.getInstance().getBooleanType());
if (!(compileTimeConstant instanceof BooleanValue) || compileTimeConstant.usesVariableAsConstant()) return false;
if (!(compileTimeConstant instanceof TypedCompileTimeConstant) || compileTimeConstant.getUsesVariableAsConstant()) return false;
Boolean value = ((BooleanValue) compileTimeConstant).getValue();
ConstantValue constantValue = ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue();
if (!(constantValue instanceof BooleanValue)) return false;
Boolean value = ((BooleanValue) constantValue).getValue();
return expectedValue == null || expectedValue.equals(value);
}
@@ -37,10 +37,8 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.constants.evaluate.EvaluatePackage;
import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
@@ -868,17 +866,13 @@ public class DescriptorResolver {
if (!variable.hasInitializer()) return;
variableDescriptor.setCompileTimeInitializer(
storageManager.createRecursionTolerantNullableLazyValue(new Function0<CompileTimeConstant<?>>() {
storageManager.createRecursionTolerantNullableLazyValue(new Function0<ConstantValue<?>>() {
@Nullable
@Override
public CompileTimeConstant<?> invoke() {
public ConstantValue<?> invoke() {
JetExpression initializer = variable.getInitializer();
JetType initializerType = expressionTypingServices.safeGetType(scope, initializer, variableType, dataFlowInfo, trace);
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.evaluate(initializer, trace, initializerType);
if (constant instanceof IntegerValueTypeConstant) {
return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) constant, initializerType);
}
return constant;
return ConstantExpressionEvaluator.evaluateToConstantValue(initializer, trace, initializerType);
}
}, null)
);
@@ -26,13 +26,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.diagnostics.*;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.StringValue;
import java.util.*;
@@ -302,9 +302,9 @@ public class ModifiersChecker {
}
String value = null;
Collection<CompileTimeConstant<?>> values = annotation.getAllValueArguments().values();
Collection<ConstantValue<?>> values = annotation.getAllValueArguments().values();
if (!values.isEmpty()) {
CompileTimeConstant<?> name = values.iterator().next();
ConstantValue<?> name = values.iterator().next();
if (name instanceof StringValue) {
value = ((StringValue) name).getValue();
}
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
import org.jetbrains.kotlin.types.ErrorUtils;
@@ -369,7 +368,7 @@ public class CallExpressionResolver {
}
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, context.trace, context.expectedType);
if (value instanceof IntegerValueConstant && ((IntegerValueConstant) value).isPure()) {
if (value != null && value.getIsPure()) {
return ExpressionTypingUtils.createCompileTimeConstantTypeInfo(value, expression, context);
}
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.resolve.calls.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.resolve.descriptorUtil.classObjectType
import org.jetbrains.kotlin.resolve.descriptorUtil.getClassObjectReferenceTarget
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassObjectType
@@ -59,7 +58,7 @@ public class FakeCallableDescriptorForObject(
override fun getOriginal(): CallableDescriptor = this
override fun getCompileTimeInitializer(): CompileTimeConstant<out Any?>? = null
override fun getCompileTimeInitializer() = null
override fun getSource(): SourceElement = classDescriptor.getSource()
}
@@ -51,7 +51,7 @@ public class CompileTimeConstantChecker {
// return true if there is an error
public boolean checkConstantExpressionType(
@Nullable CompileTimeConstant compileTimeConstant,
@Nullable ConstantValue<?> compileTimeConstant,
@NotNull JetConstantExpression expression,
@NotNull JetType expectedType
) {
@@ -76,7 +76,7 @@ public class CompileTimeConstantChecker {
}
private boolean checkIntegerValue(
@Nullable CompileTimeConstant value,
@Nullable ConstantValue<?> value,
@NotNull JetType expectedType,
@NotNull JetConstantExpression expression
) {
@@ -98,7 +98,7 @@ public class CompileTimeConstantChecker {
}
private boolean checkFloatValue(
@Nullable CompileTimeConstant value,
@Nullable ConstantValue<?> value,
@NotNull JetType expectedType,
@NotNull JetConstantExpression expression
) {
@@ -125,7 +125,7 @@ public class CompileTimeConstantChecker {
return false;
}
private boolean checkCharValue(CompileTimeConstant<?> constant, JetType expectedType, JetConstantExpression expression) {
private boolean checkCharValue(ConstantValue<?> constant, JetType expectedType, JetConstantExpression expression) {
if (!noExpectedTypeOrError(expectedType)
&& !JetTypeChecker.DEFAULT.isSubtypeOf(builtIns.getCharType(), expectedType)) {
return reportError(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, "character", expectedType));
@@ -41,31 +41,26 @@ import java.math.BigInteger
import kotlin.platform.platformStatic
public class ConstantExpressionEvaluator private constructor(val trace: BindingTrace) : JetVisitor<CompileTimeConstant<*>, JetType>() {
private val builtIns = KotlinBuiltIns.getInstance()
private val factory = ConstantValueFactory(KotlinBuiltIns.getInstance())
companion object {
platformStatic public fun evaluate(expression: JetExpression, trace: BindingTrace, expectedType: JetType? = TypeUtils.NO_EXPECTED_TYPE): CompileTimeConstant<*>? {
val evaluator = ConstantExpressionEvaluator(trace)
val constant = evaluator.evaluate(expression, expectedType)
return if (constant !is ErrorValue) constant else null
val constant = evaluator.evaluate(expression, expectedType) ?: return null
return if (!constant.isError) constant else null
}
platformStatic public fun isPropertyCompileTimeConstant(descriptor: VariableDescriptor): Boolean {
if (descriptor.isVar()) {
return false
}
if (DescriptorUtils.isObject(descriptor.getContainingDeclaration()) ||
DescriptorUtils.isStaticDeclaration(descriptor)) {
val returnType = descriptor.getType()
return KotlinBuiltIns.isPrimitiveType(returnType) || KotlinBuiltIns.isString(returnType)
}
return false
platformStatic public fun evaluateToConstantValue(
expression: JetExpression,
trace: BindingTrace,
expectedType: JetType
): ConstantValue<*>? {
return evaluate(expression, trace, expectedType)?.toConstantValue(expectedType)
}
platformStatic public fun getConstant(expression: JetExpression, bindingContext: BindingContext): CompileTimeConstant<*>? {
val constant = getPossiblyErrorConstant(expression, bindingContext)
return if (constant !is ErrorValue) constant else null
val constant = getPossiblyErrorConstant(expression, bindingContext) ?: return null
return if (!constant.isError) constant else null
}
platformStatic private fun getPossiblyErrorConstant(expression: JetExpression, bindingContext: BindingContext): CompileTimeConstant<*>? {
@@ -87,30 +82,38 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
return null
}
private val stringExpressionEvaluator = object : JetVisitor<StringValue, Nothing>() {
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(true, false, false), builtIns)
private val stringExpressionEvaluator = object : JetVisitor<TypedCompileTimeConstant<String>, Nothing>() {
private fun createStringConstant(compileTimeConstant: CompileTimeConstant<*>): TypedCompileTimeConstant<String>? {
val constantValue = compileTimeConstant.toConstantValue(TypeUtils.NO_EXPECTED_TYPE)
return when (constantValue) {
is ErrorValue, is EnumValue -> return null
is NullValue -> factory.createStringValue("null")
else -> factory.createStringValue(constantValue.value.toString())
}.wrap(compileTimeConstant.parameters)
}
fun evaluate(entry: JetStringTemplateEntry): StringValue? {
fun evaluate(entry: JetStringTemplateEntry): TypedCompileTimeConstant<String>? {
return entry.accept(this, null)
}
override fun visitStringTemplateEntryWithExpression(entry: JetStringTemplateEntryWithExpression, data: Nothing?): StringValue? {
val expression = entry.getExpression()
if (expression == null) return null
override fun visitStringTemplateEntryWithExpression(entry: JetStringTemplateEntryWithExpression, data: Nothing?): TypedCompileTimeConstant<String>? {
val expression = entry.getExpression() ?: return null
return createStringConstant(this@ConstantExpressionEvaluator.evaluate(expression, KotlinBuiltIns.getInstance().getStringType()))
return this@ConstantExpressionEvaluator.evaluate(expression, KotlinBuiltIns.getInstance().getStringType())?.let {
createStringConstant(it)
}
}
override fun visitLiteralStringTemplateEntry(entry: JetLiteralStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getText())
override fun visitLiteralStringTemplateEntry(entry: JetLiteralStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getText()).wrap()
override fun visitEscapeStringTemplateEntry(entry: JetEscapeStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getUnescapedValue())
override fun visitEscapeStringTemplateEntry(entry: JetEscapeStringTemplateEntry, data: Nothing?) = factory.createStringValue(entry.getUnescapedValue()).wrap()
}
override fun visitConstantExpression(expression: JetConstantExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val text = expression.getText() ?: return null
val nodeElementType = expression.getNode().getElementType()
if (nodeElementType == JetNodeTypes.NULL) return NullValue(builtIns)
if (nodeElementType == JetNodeTypes.NULL) return factory.createNullValue().wrap()
val result: Any? = when (nodeElementType) {
JetNodeTypes.INTEGER_CONSTANT -> parseLong(text)
@@ -121,7 +124,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
} ?: return null
fun isLongWithSuffix() = nodeElementType == JetNodeTypes.INTEGER_CONSTANT && hasLongSuffix(text)
return createConstant(result, expectedType, CompileTimeConstant.Parameters.Impl(true, !isLongWithSuffix(), false))
return createConstant(result, expectedType, CompileTimeConstant.Parameters(true, !isLongWithSuffix(), false))
}
override fun visitParenthesizedExpression(expression: JetParenthesizedExpression, expectedType: JetType?): CompileTimeConstant<*>? {
@@ -152,17 +155,17 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
break
}
else {
if (!constant.canBeUsedInAnnotations()) canBeUsedInAnnotation = false
if (constant.usesVariableAsConstant()) usesVariableAsConstant = true
sb.append(constant.value)
if (!constant.canBeUsedInAnnotations) canBeUsedInAnnotation = false
if (constant.usesVariableAsConstant) usesVariableAsConstant = true
sb.append(constant.constantValue.value)
}
}
return if (!interupted)
createConstant(
sb.toString(),
expectedType,
CompileTimeConstant.Parameters.Impl(
isPure = true,
CompileTimeConstant.Parameters(
isPure = false,
canBeUsedInAnnotation = canBeUsedInAnnotation,
usesVariableAsConstant = usesVariableAsConstant
)
@@ -174,8 +177,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
evaluate(expression.getLeft(), expectedType)
override fun visitBinaryExpression(expression: JetBinaryExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val leftExpression = expression.getLeft()
if (leftExpression == null) return null
val leftExpression = expression.getLeft() ?: return null
val operationToken = expression.getOperationToken()
if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationToken)) {
@@ -183,14 +185,12 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
val leftConstant = evaluate(leftExpression, booleanType)
if (leftConstant == null) return null
val rightExpression = expression.getRight()
if (rightExpression == null) return null
val rightExpression = expression.getRight() ?: return null
val rightConstant = evaluate(rightExpression, booleanType)
if (rightConstant == null) return null
val rightConstant = evaluate(rightExpression, booleanType) ?: return null
val leftValue = leftConstant.value
val rightValue = rightConstant.value
val leftValue = leftConstant.getValue(booleanType)
val rightValue = rightConstant.getValue(booleanType)
if (leftValue !is Boolean || rightValue !is Boolean) return null
val result = when (operationToken) {
@@ -198,8 +198,14 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
JetTokens.OROR -> leftValue || rightValue
else -> throw IllegalArgumentException("Unknown boolean operation token ${operationToken}")
}
val usesVariableAsConstant = leftConstant.usesVariableAsConstant() || rightConstant.usesVariableAsConstant()
return createConstant(result, expectedType, CompileTimeConstant.Parameters.Impl(true, true, usesVariableAsConstant))
return createConstant(
result, expectedType,
CompileTimeConstant.Parameters(
canBeUsedInAnnotation = true,
isPure = false,
usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant
)
)
}
else {
return evaluateCall(expression.getOperationReference(), leftExpression, expectedType)
@@ -226,7 +232,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
return createConstant(
result,
expectedType,
CompileTimeConstant.Parameters.Impl(
CompileTimeConstant.Parameters(
canBeUsedInAnnotation,
!isNumberConversionMethod && isArgumentPure,
usesVariableAsConstant)
@@ -240,8 +246,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
if (isDivisionByZero(resultingDescriptorName.asString(), argumentForParameter.value)) {
val parentExpression: JetExpression = PsiTreeUtil.getParentOfType(receiverExpression, javaClass())!!
trace.report(Errors.DIVISION_BY_ZERO.on(parentExpression))
//TODO_R:
return ErrorValue.create("Division by zero")
return factory.createErrorValue("Division by zero").wrap()
}
val result = evaluateBinaryAndCheck(argumentForReceiver, argumentForParameter, resultingDescriptorName.asString(), callExpression)
@@ -250,11 +255,10 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
val areArgumentsPure = isPureConstant(argumentForReceiver.expression) && isPureConstant(argumentForParameter.expression)
val canBeUsedInAnnotation = canBeUsedInAnnotation(argumentForReceiver.expression) && canBeUsedInAnnotation(argumentForParameter.expression)
val usesVariableAsConstant = usesVariableAsConstant(argumentForReceiver.expression) || usesVariableAsConstant(argumentForParameter.expression)
val parameters = CompileTimeConstant.Parameters.Impl(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant)
val factory = CompileTimeConstantFactory(parameters, builtIns)
val parameters = CompileTimeConstant.Parameters(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant)
return when (resultingDescriptorName) {
OperatorConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression, factory)
OperatorConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression, factory)
OperatorConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression, factory)?.wrap(parameters)
OperatorConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression, factory)?.wrap(parameters)
else -> {
createConstant(result, expectedType, parameters)
}
@@ -264,17 +268,11 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
return null
}
private fun usesVariableAsConstant(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.usesVariableAsConstant() ?: false
private fun usesVariableAsConstant(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.usesVariableAsConstant ?: false
private fun canBeUsedInAnnotation(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.canBeUsedInAnnotations() ?: false
private fun canBeUsedInAnnotation(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.canBeUsedInAnnotations ?: false
private fun isPureConstant(expression: JetExpression): Boolean {
val compileTimeConstant = getConstant(expression, trace.getBindingContext())
if (compileTimeConstant is IntegerValueConstant) {
return compileTimeConstant.isPure()
}
return false
}
private fun isPureConstant(expression: JetExpression) = getConstant(expression, trace.getBindingContext())?.isPure ?: false
private fun evaluateUnaryAndCheck(receiver: OperationArgument, name: String, callExpression: JetExpression): Any? {
val functions = unaryOperations[UnaryOperationKey(receiver.ctcType, name)]
@@ -342,25 +340,19 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
override fun visitSimpleNameExpression(expression: JetSimpleNameExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val enumDescriptor = trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, expression);
if (enumDescriptor != null && DescriptorUtils.isEnumEntry(enumDescriptor)) {
return EnumValue(enumDescriptor as ClassDescriptor)
return factory.createEnumValue(enumDescriptor as ClassDescriptor).wrap()
}
val resolvedCall = expression.getResolvedCall(trace.getBindingContext())
if (resolvedCall != null) {
val callableDescriptor = resolvedCall.getResultingDescriptor()
if (callableDescriptor is VariableDescriptor) {
val compileTimeConstant = callableDescriptor.getCompileTimeInitializer()
if (compileTimeConstant == null) return null
val variableInitializer = callableDescriptor.getCompileTimeInitializer() ?: return null
val value: Any? =
if (compileTimeConstant is IntegerValueTypeConstant)
compileTimeConstant.getValue(expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
else
compileTimeConstant.value
return createConstant(
value,
variableInitializer.value,
expectedType,
CompileTimeConstant.Parameters.Impl(
CompileTimeConstant.Parameters(
canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor),
isPure = false,
usesVariableAsConstant = true
@@ -371,6 +363,18 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
return null
}
private fun isPropertyCompileTimeConstant(descriptor: VariableDescriptor): Boolean {
if (descriptor.isVar()) {
return false
}
if (DescriptorUtils.isObject(descriptor.getContainingDeclaration()) ||
DescriptorUtils.isStaticDeclaration(descriptor)) {
val returnType = descriptor.getType()
return KotlinBuiltIns.isPrimitiveType(returnType) || KotlinBuiltIns.isString(returnType)
}
return false
}
override fun visitQualifiedExpression(expression: JetQualifiedExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val selectorExpression = expression.getSelectorExpression()
// 1.toInt(); 1.plus(1);
@@ -409,7 +413,10 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
val arguments = call.getValueArguments().values().flatMap { resolveArguments(it.getArguments(), varargType) }
return ArrayValue(arguments, resultingDescriptor.getReturnType()!!, arguments.any() { it.usesVariableAsConstant() })
return ArrayValue(arguments.map { it.toConstantValue(varargType) }, resultingDescriptor.getReturnType()!!).
wrap(
usesVariableAsConstant = arguments.any { it.usesVariableAsConstant }
)
}
// Ann()
@@ -420,7 +427,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
classDescriptor.getDefaultType(),
AnnotationResolver.resolveAnnotationArguments(call, trace)
)
return AnnotationValue(descriptor)
return AnnotationValue(descriptor).wrap()
}
}
@@ -430,7 +437,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
override fun visitClassLiteralExpression(expression: JetClassLiteralExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val jetType = trace.getType(expression)!!
if (jetType.isError()) return null
return KClassValue(jetType)
return KClassValue(jetType).wrap()
}
private fun resolveArguments(valueArguments: List<ValueArgument>, expectedType: JetType): List<CompileTimeConstant<*>> {
@@ -476,32 +483,54 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
}
private fun createOperationArgument(expression: JetExpression, expressionType: JetType, compileTimeType: CompileTimeType<*>): OperationArgument? {
val evaluatedConstant = evaluate(expression, trace, expressionType)
if (evaluatedConstant == null) return null
if (evaluatedConstant is IntegerValueTypeConstant) {
val evaluationResultWithNewType = evaluatedConstant.getValue(expressionType)
return OperationArgument(evaluationResultWithNewType, compileTimeType, expression)
}
val evaluationResult = evaluatedConstant.value
if (evaluationResult == null) return null
val compileTimeConstant = evaluate(expression, trace, expressionType) ?: return null
val evaluationResult = compileTimeConstant.getValue(expressionType) ?: return null
return OperationArgument(evaluationResult, compileTimeType, expression)
}
fun createConstant(
private fun createConstant(
value: Any?,
expectedType: JetType?,
parameters: CompileTimeConstant.Parameters
): CompileTimeConstant<*>? {
return CompileTimeConstantFactory(parameters, builtIns).createCompileTimeConstant(value, if (parameters.isPure) expectedType ?: TypeUtils.NO_EXPECTED_TYPE else null)
return if (parameters.isPure) {
return createCompileTimeConstant(value, parameters, expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
}
else {
factory.createConstantValue(value)?.wrap(parameters)
}
}
private fun createCompileTimeConstant(
value: Any?,
parameters: CompileTimeConstant.Parameters,
expectedType: JetType
): CompileTimeConstant<*>? {
return when (value) {
is Byte, is Short, is Int, is Long -> createIntegerCompileTimeConstant((value as Number).toLong(), parameters, expectedType)
else -> factory.createConstantValue(value)?.wrap(parameters)
}
}
private fun createIntegerCompileTimeConstant(
value: Long,
parameters: CompileTimeConstant.Parameters,
expectedType: JetType
): CompileTimeConstant<*>? {
if (TypeUtils.noExpectedType(expectedType) || expectedType.isError()) {
return IntegerValueTypeConstant(value, parameters)
}
val integerValue = factory.createIntegerConstantValue(value, expectedType)
if (integerValue != null) {
return integerValue.wrap(parameters)
}
return when (value) {
value.toInt().toLong() -> factory.createIntValue(value.toInt())
else -> factory.createLongValue(value)
}.wrap(parameters)
}
}
public fun IntegerValueTypeConstant.createCompileTimeConstantWithType(expectedType: JetType): CompileTimeConstant<*>?
= CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(this.canBeUsedInAnnotations(), true, false), KotlinBuiltIns.getInstance()).createCompileTimeConstant(this.getValue(expectedType))
private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L')
public fun parseLong(text: String): Long? {
@@ -557,7 +586,7 @@ private fun parseBoolean(text: String): Boolean {
}
private fun createCompileTimeConstantForEquals(result: Any?, operationReference: JetExpression, factory: CompileTimeConstantFactory): CompileTimeConstant<*>? {
private fun createCompileTimeConstantForEquals(result: Any?, operationReference: JetExpression, factory: ConstantValueFactory): ConstantValue<*>? {
if (result is Boolean) {
assert(operationReference is JetSimpleNameExpression, "This method should be called only for equals operations")
val operationToken = (operationReference as JetSimpleNameExpression).getReferencedNameElementType()
@@ -575,7 +604,7 @@ private fun createCompileTimeConstantForEquals(result: Any?, operationReference:
return null
}
private fun createCompileTimeConstantForCompareTo(result: Any?, operationReference: JetExpression, factory: CompileTimeConstantFactory): CompileTimeConstant<*>? {
private fun createCompileTimeConstantForCompareTo(result: Any?, operationReference: JetExpression, factory: ConstantValueFactory): ConstantValue<*>? {
if (result is Int) {
assert(operationReference is JetSimpleNameExpression, "This method should be called only for compareTo operations")
val operationToken = (operationReference as JetSimpleNameExpression).getReferencedNameElementType()
@@ -594,19 +623,6 @@ private fun createCompileTimeConstantForCompareTo(result: Any?, operationReferen
return null
}
private fun createStringConstant(value: CompileTimeConstant<*>?): StringValue? {
return when (value) {
is IntegerValueTypeConstant -> CompileTimeConstantFactory(value.parameters, KotlinBuiltIns.getInstance()).createStringValue(value.getValue(TypeUtils.NO_EXPECTED_TYPE).toString())
is StringValue -> value
is IntValue, is ByteValue, is ShortValue, is LongValue,
is CharValue,
is DoubleValue, is FloatValue,
is BooleanValue,
is NullValue -> CompileTimeConstantFactory(value.parameters, KotlinBuiltIns.getInstance()).createStringValue("${value.value}")
else -> null
}
}
fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int || value is Long
private fun getReceiverExpressionType(resolvedCall: ResolvedCall<*>): JetType? {
@@ -668,4 +684,3 @@ private fun <A> unaryOperation(
private data class BinaryOperationKey<A, B>(val f: CompileTimeType<out A>, val s: CompileTimeType<out B>, val functionName: String)
private data class UnaryOperationKey<A>(val f: CompileTimeType<out A>, val functionName: String)
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.diagnostics.Severity;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.StringValue;
import org.jetbrains.kotlin.util.ExtensionProvider;
@@ -214,9 +214,9 @@ public class DiagnosticsWithSuppression implements Diagnostics {
if (!KotlinBuiltIns.isSuppressAnnotation(annotationDescriptor)) continue;
// We only add strings and skip other values to facilitate recovery in presence of erroneous code
for (CompileTimeConstant<?> arrayValue : annotationDescriptor.getAllValueArguments().values()) {
for (ConstantValue<?> arrayValue : annotationDescriptor.getAllValueArguments().values()) {
if ((arrayValue instanceof ArrayValue)) {
for (CompileTimeConstant<?> value : ((ArrayValue) arrayValue).getValue()) {
for (ConstantValue<?> value : ((ArrayValue) arrayValue).getValue()) {
if (value instanceof StringValue) {
builder.add(String.valueOf(((StringValue) value).getValue()).toLowerCase());
}
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMapping;
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.EnumValue;
import static kotlin.KotlinPackage.firstOrNull;
@@ -53,7 +53,7 @@ public class InlineUtil {
if (annotation == null) {
return InlineStrategy.NOT_INLINE;
}
CompileTimeConstant<?> argument = firstOrNull(annotation.getAllValueArguments().values());
ConstantValue<?> argument = firstOrNull(annotation.getAllValueArguments().values());
if (argument == null) {
return InlineStrategy.AS_FUNCTION;
}
@@ -72,9 +72,9 @@ public class InlineUtil {
private static boolean hasInlineOption(@NotNull ValueParameterDescriptor descriptor, @NotNull InlineOption option) {
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.inlineOptions);
if (annotation != null) {
CompileTimeConstant<?> argument = firstOrNull(annotation.getAllValueArguments().values());
ConstantValue<?> argument = firstOrNull(annotation.getAllValueArguments().values());
if (argument instanceof ArrayValue) {
for (CompileTimeConstant<?> value : ((ArrayValue) argument).getValue()) {
for (ConstantValue<?> value : ((ArrayValue) argument).getValue()) {
if (value instanceof EnumValue && ((EnumValue) value).getValue().getName().asString().equals(option.name())) {
return true;
}
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.AnnotationResolver
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
import org.jetbrains.kotlin.resolve.scopes.JetScope
@@ -109,7 +109,7 @@ public class LazyAnnotationDescriptor(
override fun getAllValueArguments() = valueArguments()
private fun computeValueArguments(): Map<ValueParameterDescriptor, CompileTimeConstant<*>> {
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
val resolutionResults = c.annotationResolver.resolveAnnotationCall(annotationEntry, c.scope, c.trace)
AnnotationResolver.checkAnnotationType(annotationEntry, c.trace, resolutionResults)
@@ -121,7 +121,7 @@ public class LazyAnnotationDescriptor(
if (resolvedArgument == null) null
else AnnotationResolver.getAnnotationArgumentValue(c.trace, valueParameter, resolvedArgument)
}
.filterValues { it != null } as Map<ValueParameterDescriptor, CompileTimeConstant<*>>
.filterValues { it != null } as Map<ValueParameterDescriptor, ConstantValue<*>>
}
override fun forceResolveAllContents() {
@@ -55,9 +55,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl;
@@ -121,19 +119,20 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override
public JetTypeInfo visitConstantExpression(@NotNull JetConstantExpression expression, ExpressionTypingContext context) {
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, context.trace, context.expectedType);
CompileTimeConstant<?> compileTimeConstant = ConstantExpressionEvaluator.evaluate(expression, context.trace, context.expectedType);
if (!(value instanceof IntegerValueTypeConstant)) {
if (!(compileTimeConstant instanceof IntegerValueTypeConstant)) {
CompileTimeConstantChecker compileTimeConstantChecker = context.getCompileTimeConstantChecker();
boolean hasError = compileTimeConstantChecker.checkConstantExpressionType(value, expression, context.expectedType);
ConstantValue constantValue = compileTimeConstant != null ? ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue() : null;
boolean hasError = compileTimeConstantChecker.checkConstantExpressionType(constantValue, expression, context.expectedType);
if (hasError) {
IElementType elementType = expression.getNode().getElementType();
return TypeInfoFactoryPackage.createTypeInfo(getDefaultType(elementType), context);
}
}
assert value != null : "CompileTimeConstant should be evaluated for constant expression or an error should be recorded " + expression.getText();
return createCompileTimeConstantTypeInfo(value, expression, context);
assert compileTimeConstant != null : "CompileTimeConstant should be evaluated for constant expression or an error should be recorded " + expression.getText();
return createCompileTimeConstantTypeInfo(compileTimeConstant, expression, context);
}
@NotNull
@@ -31,11 +31,9 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.constants.evaluate.EvaluatePackage;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.TypesPackage;
@@ -176,12 +174,9 @@ public class DataFlowUtils {
}
if (expression instanceof JetConstantExpression) {
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, c.trace, c.expectedType);
if (value instanceof IntegerValueTypeConstant) {
value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, c.expectedType);
}
ConstantValue<?> constantValue = ConstantExpressionEvaluator.evaluateToConstantValue(expression, c.trace, c.expectedType);
boolean error = new CompileTimeConstantChecker(c.trace, true)
.checkConstantExpressionType(value, (JetConstantExpression) expression, c.expectedType);
.checkConstantExpressionType(constantValue, (JetConstantExpression) expression, c.expectedType);
if (hasError != null) hasError.set(error);
return expressionType;
}
@@ -22,7 +22,6 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
@@ -33,6 +32,7 @@ import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant;
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl;
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassReceiver;
@@ -248,10 +248,19 @@ public class ExpressionTypingUtils {
@NotNull JetExpression expression,
@NotNull ExpressionTypingContext context
) {
JetType expressionType = value.getType();
if (value instanceof IntegerValueTypeConstant && context.contextDependency == INDEPENDENT) {
expressionType = ((IntegerValueTypeConstant) value).getType(context.expectedType);
ArgumentTypeResolver.updateNumberType(expressionType, expression, context);
JetType expressionType;
if (value instanceof IntegerValueTypeConstant) {
IntegerValueTypeConstant integerValueTypeConstant = (IntegerValueTypeConstant) value;
if (context.contextDependency == INDEPENDENT) {
expressionType = integerValueTypeConstant.getType(context.expectedType);
ArgumentTypeResolver.updateNumberType(expressionType, expression, context);
}
else {
expressionType = integerValueTypeConstant.getUnknownIntegerType();
}
}
else {
expressionType = ((TypedCompileTimeConstant<?>) value).getType();
}
return TypeInfoFactoryPackage.createCheckedTypeInfo(expressionType, context, expression);
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.serialization
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.resolve.constants.*
@@ -29,8 +28,6 @@ import org.jetbrains.kotlin.types.JetType
public class AnnotationSerializer(builtIns: KotlinBuiltIns) {
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.ThrowException, builtIns)
public fun serializeAnnotation(annotation: AnnotationDescriptor, stringTable: StringTable): ProtoBuf.Annotation {
return with(ProtoBuf.Annotation.newBuilder()) {
val annotationClass = annotation.getType().getConstructor().getDeclarationDescriptor() as? ClassDescriptor
@@ -52,7 +49,7 @@ public class AnnotationSerializer(builtIns: KotlinBuiltIns) {
}
}
fun valueProto(constant: CompileTimeConstant<*>, type: JetType, nameTable: StringTable): Value.Builder = with(Value.newBuilder()) {
fun valueProto(constant: ConstantValue<*>, type: JetType, nameTable: StringTable): Value.Builder = with(Value.newBuilder()) {
constant.accept(object : AnnotationArgumentVisitor<Unit, Unit> {
override fun visitAnnotationValue(value: AnnotationValue, data: Unit) {
setType(Type.ANNOTATION)
@@ -121,22 +118,6 @@ public class AnnotationSerializer(builtIns: KotlinBuiltIns) {
throw UnsupportedOperationException("Null should not appear in annotation arguments")
}
override fun visitNumberTypeValue(constant: IntegerValueTypeConstant, data: Unit) {
// TODO: IntegerValueTypeConstant should not occur in annotation arguments
val number = constant.getValue(type)
val specificConstant = with(KotlinBuiltIns.getInstance()) {
when (type) {
getLongType() -> factory.createLongValue(number.toLong())
getIntType() -> factory.createIntValue(number.toInt())
getShortType() -> factory.createShortValue(number.toShort())
getByteType() -> factory.createByteValue(number.toByte())
else -> throw IllegalStateException("Integer constant $constant has non-integer type $type")
}
}
specificConstant.accept(this, data)
}
override fun visitShortValue(value: ShortValue, data: Unit) {
setType(Type.SHORT)
setIntValue(value.value.toLong())
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.MemberComparator;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.NullValue;
import org.jetbrains.kotlin.types.*;
@@ -188,7 +188,7 @@ public class DescriptorSerializer {
}
}
CompileTimeConstant<?> compileTimeConstant = propertyDescriptor.getCompileTimeInitializer();
ConstantValue<?> compileTimeConstant = propertyDescriptor.getCompileTimeInitializer();
hasConstant = !(compileTimeConstant == null || compileTimeConstant instanceof NullValue);
}
@@ -8,4 +8,6 @@ class Foo {
public static final boolean bool = true;
public static final char c = 'c';
public static final String str = "str";
public static final int charAsInt = '3';
public static final char intAsChar = 3;
}
@@ -1,4 +1,4 @@
Ann(Foo.i, Foo.s, Foo.f, Foo.d, Foo.l, Foo.b, Foo.bool, Foo.c, Foo.str) class MyClass
Ann(Foo.i, Foo.s, Foo.f, Foo.d, Foo.l, Foo.b, Foo.bool, Foo.c, Foo.str, Foo.charAsInt, Foo.intAsChar) class MyClass
fun box(): String {
val ann = javaClass<MyClass>().getAnnotation(javaClass<Ann>())
@@ -12,6 +12,8 @@ fun box(): String {
if (!ann.bool) return "fail: annotation parameter i should be true, but was ${ann.i}"
if (ann.c != 'c') return "fail: annotation parameter i should be c, but was ${ann.i}"
if (ann.str != "str") return "fail: annotation parameter i should be str, but was ${ann.i}"
if (ann.i2 != '3'.toInt()) return "fail: annotation parameter i2 should be ${'3'.toInt()}, but was ${ann.i}"
if (ann.c2 != 3.toChar()) return "fail: annotation parameter c2 should be 3, but was ${ann.i}"
return "OK"
}
@@ -24,5 +26,7 @@ annotation(retention = AnnotationRetention.RUNTIME) class Ann(
val b: Byte,
val bool: Boolean,
val c: Char,
val str: String
val str: String,
val i2: Int,
val c2: Char
)
@@ -1,6 +1,6 @@
package
internal fun foo(): @[My(x = IntegerValueType(42))] kotlin.Int
internal fun foo(): @[My(x = 42)] kotlin.Int
kotlin.annotation.target(allowedTargets = {AnnotationTarget.TYPE}) kotlin.annotation.annotation() internal final class My : kotlin.Annotation {
public constructor My(/*0*/ x: kotlin.Int)
@@ -12,7 +12,7 @@ package test {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
test.A(a = IntegerValueType(12), c = "Hello") internal object SomeObject {
test.A(a = 12, c = "Hello") internal object SomeObject {
private constructor SomeObject()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -2,10 +2,10 @@ package
my() internal fun foo(): kotlin.Unit
my1() internal fun foo2(): kotlin.Unit
my1(i = IntegerValueType(2)) internal fun foo3(): kotlin.Unit
my1(i = 2) internal fun foo3(): kotlin.Unit
my2() internal fun foo4(): kotlin.Unit
my2() internal fun foo41(): kotlin.Unit
my2(i = IntegerValueType(2)) internal fun foo42(): kotlin.Unit
my2(i = 2) internal fun foo42(): kotlin.Unit
kotlin.annotation.annotation() internal final class my : kotlin.Annotation {
public constructor my()
@@ -1,7 +1,7 @@
package
Ann2(a = Ann1(a = IntegerValueType(1))) internal val a: kotlin.Int = 1
Ann2(a = Ann1(a = IntegerValueType(1))) internal val c: kotlin.Int = 2
Ann2(a = Ann1(a = 1)) internal val a: kotlin.Int = 1
Ann2(a = Ann1(a = 1)) internal val c: kotlin.Int = 2
internal fun bar(/*0*/ a: Ann = ...): kotlin.Unit
internal fun foo(): kotlin.Unit
internal fun </*0*/ T> javaClass(): java.lang.Class<T>
@@ -1,6 +1,6 @@
package
RecursivelyAnnotated(x = IntegerValueType(1)) kotlin.annotation.annotation() internal final class RecursivelyAnnotated : kotlin.Annotation {
RecursivelyAnnotated(x = 1) kotlin.annotation.annotation() internal final class RecursivelyAnnotated : kotlin.Annotation {
public constructor RecursivelyAnnotated(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -1,8 +1,8 @@
package
kotlin.annotation.annotation() internal final class RecursivelyAnnotated : kotlin.Annotation {
public constructor RecursivelyAnnotated(/*0*/ RecursivelyAnnotated(x = IntegerValueType(1)) x: kotlin.Int)
RecursivelyAnnotated(x = IntegerValueType(1)) internal final val x: kotlin.Int
public constructor RecursivelyAnnotated(/*0*/ RecursivelyAnnotated(x = 1) x: kotlin.Int)
RecursivelyAnnotated(x = 1) internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -1,8 +1,8 @@
package
kotlin.annotation.target(allowedTargets = {AnnotationTarget.TYPE}) kotlin.annotation.annotation() internal final class RecursivelyAnnotated : kotlin.Annotation {
public constructor RecursivelyAnnotated(/*0*/ x: @[RecursivelyAnnotated(x = IntegerValueType(1))] kotlin.Int)
internal final val x: @[RecursivelyAnnotated(x = IntegerValueType(1))] kotlin.Int
public constructor RecursivelyAnnotated(/*0*/ x: @[RecursivelyAnnotated(x = 1)] kotlin.Int)
internal final val x: @[RecursivelyAnnotated(x = 1)] kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -1,8 +1,8 @@
package
kotlin.annotation.annotation() internal final class RecursivelyAnnotated : kotlin.Annotation {
public constructor RecursivelyAnnotated(/*0*/ RecursivelyAnnotated(x = IntegerValueType(1)) x: kotlin.Int)
RecursivelyAnnotated(x = IntegerValueType(1)) internal final val x: kotlin.Int
public constructor RecursivelyAnnotated(/*0*/ RecursivelyAnnotated(x = 1) x: kotlin.Int)
RecursivelyAnnotated(x = 1) internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -1,8 +1,8 @@
package
internal final class RecursivelyAnnotated {
public constructor RecursivelyAnnotated(/*0*/ RecursivelyAnnotated(x = IntegerValueType(1)) x: kotlin.Int)
RecursivelyAnnotated(x = IntegerValueType(1)) internal final val x: kotlin.Int
public constructor RecursivelyAnnotated(/*0*/ RecursivelyAnnotated(x = 1) x: kotlin.Int)
RecursivelyAnnotated(x = 1) internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -11,7 +11,7 @@ package test {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
test.BadAnnotation(s = IntegerValueType(1)) internal object SomeObject {
test.BadAnnotation(s = 1) internal object SomeObject {
private constructor SomeObject()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -1,11 +1,11 @@
package
Ann(x = IntegerValueType(1)) Ann(x = IntegerValueType(2)) Ann(x = IntegerValueType(3)) private final class A {
Ann(x = 1) Ann(x = 2) Ann(x = 3) private final class A {
Ann() public constructor A()
Ann() internal final val x: kotlin.Int = 1
internal final fun bar(/*0*/ x: @[Ann(x = IntegerValueType(1)) Ann(x = IntegerValueType(2)) Ann(x = IntegerValueType(3))] kotlin.Int): kotlin.Unit
internal final fun bar(/*0*/ x: @[Ann(x = 1) Ann(x = 2) Ann(x = 3)] kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
Ann(x = IntegerValueType(5)) internal final fun foo(): kotlin.Unit
Ann(x = 5) internal final fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -9,7 +9,7 @@ internal final class A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final inner class B {
Ann(x = IntegerValueType(2)) public constructor B(/*0*/ y: kotlin.Int)
Ann(x = 2) public constructor B(/*0*/ y: kotlin.Int)
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -1,6 +1,6 @@
package
A(x = IntegerValueType(1), y = "2") internal fun test(): kotlin.Unit
A(x = 1, y = "2") internal fun test(): kotlin.Unit
public final class A : kotlin.Annotation {
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String)
@@ -3,7 +3,7 @@ package
internal final class A {
Ann1() public constructor A()
Ann2() public constructor A(/*0*/ x1: kotlin.Int)
Ann2(x = IntegerValueType(2)) public constructor A(/*0*/ x1: kotlin.Int, /*1*/ x2: kotlin.Int)
Ann2(x = 2) public constructor A(/*0*/ x1: kotlin.Int, /*1*/ x2: kotlin.Int)
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -14,7 +14,7 @@ public final class A : kotlin.Annotation {
public abstract fun value(): kotlin.String
}
A(arg = IntegerValueType(1), value = "a") internal final class MyClass {
A(arg = 1, value = "a") internal final class MyClass {
public constructor MyClass()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -29,7 +29,7 @@ Ann(i = {}) Ann(i = {1}) Ann(i = {}) Ann(i = {1}) Ann(i = {{1}}) internal final
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
AnnAnn(i = {Ann(i = {IntegerValueType(1)})}) AnnAnn(i = {}) internal final class TestAnn {
AnnAnn(i = {Ann(i = {1})}) AnnAnn(i = {}) internal final class TestAnn {
public constructor TestAnn()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -29,7 +29,7 @@ Ann(i = {}) Ann(i = {1}) Ann(i = {}) Ann(i = {1}) Ann(i = {}) Ann(i = {1}) Ann(i
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
AnnAnn(i = {Ann(i = {IntegerValueType(1)})}) AnnAnn(i = {}) internal final class TestAnn {
AnnAnn(i = {Ann(i = {1})}) AnnAnn(i = {}) internal final class TestAnn {
public constructor TestAnn()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -1,12 +1,12 @@
package
A(value = {"1", "2", "3"}, y = IntegerValueType(1)) internal fun test1(): kotlin.Unit
A(value = {"4"}, y = IntegerValueType(2)) internal fun test2(): kotlin.Unit
A(value = {{"5", "6"}, "7"}, y = IntegerValueType(3)) internal fun test3(): kotlin.Unit
A(value = {"1", "2", "3"}, x = kotlin.String::class, y = IntegerValueType(4)) internal fun test4(): kotlin.Unit
A(value = {"4"}, y = IntegerValueType(5)) internal fun test5(): kotlin.Unit
A(value = {{"5", "6"}, "7"}, x = kotlin.Any::class, y = IntegerValueType(6)) internal fun test6(): kotlin.Unit
A(value = {}, y = IntegerValueType(7)) internal fun test7(): kotlin.Unit
A(value = {"1", "2", "3"}, y = 1) internal fun test1(): kotlin.Unit
A(value = {"4"}, y = 2) internal fun test2(): kotlin.Unit
A(value = {{"5", "6"}, "7"}, y = 3) internal fun test3(): kotlin.Unit
A(value = {"1", "2", "3"}, x = kotlin.String::class, y = 4) internal fun test4(): kotlin.Unit
A(value = {"4"}, y = 5) internal fun test5(): kotlin.Unit
A(value = {{"5", "6"}, "7"}, x = kotlin.Any::class, y = 6) internal fun test6(): kotlin.Unit
A(value = {}, y = 7) internal fun test7(): kotlin.Unit
A(value = {"8", "9", "10"}) internal fun test8(): kotlin.Unit
public final class A : kotlin.Annotation {
@@ -1,16 +1,16 @@
package
A(value = {"1", "2", "3"}) internal fun test1(): kotlin.Unit
A(value = {"5", "6"}, x = kotlin.Any::class, y = IntegerValueType(3)) internal fun test10(): kotlin.Unit
A(value = {"5", "6", "7"}, x = kotlin.Any::class, y = IntegerValueType(3)) internal fun test11(): kotlin.Unit
A(value = {"5", "6"}, x = kotlin.Any::class, y = 3) internal fun test10(): kotlin.Unit
A(value = {"5", "6", "7"}, x = kotlin.Any::class, y = 3) internal fun test11(): kotlin.Unit
A(value = {"4"}) internal fun test2(): kotlin.Unit
A(value = {{"5", "6"}, "7"}) internal fun test3(): kotlin.Unit
A(value = {"1", "2", "3"}, x = kotlin.String::class) internal fun test4(): kotlin.Unit
A(value = {"4"}, y = IntegerValueType(2)) internal fun test5(): kotlin.Unit
A(value = {{"5", "6"}, "7"}, x = kotlin.Any::class, y = IntegerValueType(3)) internal fun test6(): kotlin.Unit
A(value = {"4"}, y = 2) internal fun test5(): kotlin.Unit
A(value = {{"5", "6"}, "7"}, x = kotlin.Any::class, y = 3) internal fun test6(): kotlin.Unit
A(value = {}) internal fun test7(): kotlin.Unit
A(value = {}) internal fun test8(): kotlin.Unit
A(value = {}, x = kotlin.Any::class, y = IntegerValueType(3)) internal fun test9(): kotlin.Unit
A(value = {}, x = kotlin.Any::class, y = 3) internal fun test9(): kotlin.Unit
public final class A : kotlin.Annotation {
public constructor A(/*0*/ vararg value: kotlin.String /*kotlin.Array<out kotlin.String>*/, /*1*/ x: kotlin.reflect.KClass<*> = ..., /*2*/ y: kotlin.Int = ...)
@@ -1,6 +1,6 @@
package
A(value = {IntegerValueType(1), "b"}) internal fun test(): kotlin.Unit
A(value = {1, "b"}) internal fun test(): kotlin.Unit
public final class A : kotlin.Annotation {
public constructor A(/*0*/ vararg value: kotlin.String /*kotlin.Array<out kotlin.String>*/)
@@ -1,6 +1,6 @@
package
B(args = {IntegerValueType(1), "b"}) internal fun test(): kotlin.Unit
B(args = {1, "b"}) internal fun test(): kotlin.Unit
kotlin.annotation.annotation() internal final class B : kotlin.Annotation {
public constructor B(/*0*/ vararg args: kotlin.String /*kotlin.Array<out kotlin.String>*/)
@@ -24,14 +24,14 @@ public final class B : kotlin.Annotation {
public abstract fun y(): kotlin.Int
}
A(arg = kotlin.String::class, b = B(y = IntegerValueType(1))) internal final class MyClass1 {
A(arg = kotlin.String::class, b = B(y = 1)) internal final class MyClass1 {
public constructor MyClass1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
A(b = B(y = IntegerValueType(3))) internal final class MyClass2 {
A(b = B(y = 3)) internal final class MyClass2 {
public constructor MyClass2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -18,7 +18,7 @@ A(arg = kotlin.String::class) internal final class MyClass1 {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
A(arg = kotlin.String::class, x = IntegerValueType(2)) internal final class MyClass2 {
A(arg = kotlin.String::class, x = 2) internal final class MyClass2 {
public constructor MyClass2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -11,14 +11,14 @@ public final class A : kotlin.Annotation {
public abstract fun x(): kotlin.Int
}
A(arg = kotlin.String::class, x = IntegerValueType(4)) internal final class MyClass2 {
A(arg = kotlin.String::class, x = 4) internal final class MyClass2 {
public constructor MyClass2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
A(x = IntegerValueType(5)) internal final class MyClass3 {
A(x = 5) internal final class MyClass3 {
public constructor MyClass3()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -25,14 +25,14 @@ A(value = kotlin.String::class) internal final class MyClass2 {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
A(value = kotlin.String::class, x = IntegerValueType(2)) internal final class MyClass3 {
A(value = kotlin.String::class, x = 2) internal final class MyClass3 {
public constructor MyClass3()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
A(value = kotlin.String::class, x = IntegerValueType(4)) internal final class MyClass4 {
A(value = kotlin.String::class, x = 4) internal final class MyClass4 {
public constructor MyClass4()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -11,21 +11,21 @@ public final class A : kotlin.Annotation {
public abstract fun x(): kotlin.Int
}
A(value = kotlin.String::class, x = IntegerValueType(2)) internal final class MyClass1 {
A(value = kotlin.String::class, x = 2) internal final class MyClass1 {
public constructor MyClass1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
A(value = kotlin.String::class, x = IntegerValueType(4)) internal final class MyClass2 {
A(value = kotlin.String::class, x = 4) internal final class MyClass2 {
public constructor MyClass2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
A(x = IntegerValueType(5)) internal final class MyClass3 {
A(x = 5) internal final class MyClass3 {
public constructor MyClass3()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -1,8 +1,8 @@
package
Ann(value = "a", x = IntegerValueType(1), y = 1.0.toDouble()) internal fun foo1(): kotlin.Unit
Ann(value = "b", x = IntegerValueType(2), y = 2.0.toDouble()) internal fun foo2(): kotlin.Unit
Ann(value = "c", x = IntegerValueType(3), y = 2.0.toDouble()) internal fun foo3(): kotlin.Unit
Ann(value = "a", x = 1, y = 1.0.toDouble()) internal fun foo1(): kotlin.Unit
Ann(value = "b", x = 2, y = 2.0.toDouble()) internal fun foo2(): kotlin.Unit
Ann(value = "c", x = 3, y = 2.0.toDouble()) internal fun foo3(): kotlin.Unit
kotlin.annotation.annotation() internal final class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ x: kotlin.Int, /*1*/ value: kotlin.String, /*2*/ y: kotlin.Double)
@@ -1,9 +1,9 @@
package
A(a = IntegerValueType(1), b = 1.0.toDouble(), value = "v1", x = false) internal fun foo1(): kotlin.Unit
A(a = IntegerValueType(2), b = 2.0.toDouble(), value = "v2", x = true) internal fun foo2(): kotlin.Unit
A(a = IntegerValueType(4), b = 3.0.toDouble(), value = "v2", x = true) internal fun foo3(): kotlin.Unit
A(a = IntegerValueType(4), b = 3.0.toDouble(), value = "v2", x = true) internal fun foo4(): kotlin.Unit
A(a = 1, b = 1.0.toDouble(), value = "v1", x = false) internal fun foo1(): kotlin.Unit
A(a = 2, b = 2.0.toDouble(), value = "v2", x = true) internal fun foo2(): kotlin.Unit
A(a = 4, b = 3.0.toDouble(), value = "v2", x = true) internal fun foo3(): kotlin.Unit
A(a = 4, b = 3.0.toDouble(), value = "v2", x = true) internal fun foo4(): kotlin.Unit
public final class A : kotlin.Annotation {
public constructor A(/*0*/ value: kotlin.String, /*1*/ a: kotlin.Int, /*2*/ b: kotlin.Double, /*3*/ x: kotlin.Boolean)
@@ -1,8 +1,8 @@
package
A(a = IntegerValueType(1), b = 1.0.toDouble(), x = false) internal fun foo1(): kotlin.Unit
A(a = IntegerValueType(2), b = 2.0.toDouble(), x = true) internal fun foo2(): kotlin.Unit
A(a = IntegerValueType(4), b = 3.0.toDouble(), x = true) internal fun foo3(): kotlin.Unit
A(a = 1, b = 1.0.toDouble(), x = false) internal fun foo1(): kotlin.Unit
A(a = 2, b = 2.0.toDouble(), x = true) internal fun foo2(): kotlin.Unit
A(a = 4, b = 3.0.toDouble(), x = true) internal fun foo3(): kotlin.Unit
public final class A : kotlin.Annotation {
public constructor A(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Double, /*2*/ x: kotlin.Boolean)
@@ -6,11 +6,17 @@ fun foo(): Boolean = true
val x = 1
// val prop1: null
// val prop1: false
val prop1 = MyEnum.A
// val prop2: null
val prop2 = foo()
// val prop3: true
val prop3 = "$x"
val prop3 = "$x"
// val prop4: false
val prop4 = intArrayOf(1, 2, 3)
// val prop5: true
val prop5 = intArrayOf(1, 2, x, x)
+1 -1
View File
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1, 1.toByte(), 128.toByte(), 128) class MyClass
// EXPECTED: Ann(b1 = IntegerValueType(1), b2 = 1.toByte(), b3 = -128.toByte(), b4 = IntegerValueType(128))
// EXPECTED: Ann(b1 = 1.toByte(), b2 = 1.toByte(), b3 = -128.toByte(), b4 = 128)
@@ -4,4 +4,4 @@ annotation class Ann(val c1: Char)
Ann('a' - 'a') class MyClass
// EXPECTED: Ann(c1 = IntegerValueType(0))
// EXPECTED: Ann(c1 = 0)
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1 / 1, 1 / 1, 1 / 1, 1 / 1) class MyClass
// EXPECTED: Ann(b = IntegerValueType(1), i = IntegerValueType(1), l = IntegerValueType(1), s = IntegerValueType(1))
// EXPECTED: Ann(b = 1.toByte(), i = 1, l = 1.toLong(), s = 1.toShort())
@@ -10,4 +10,4 @@ annotation class Ann(
Ann(1 plus 1, 1 minus 1, 1 times 1, 1 div 1, 1 mod 1) class MyClass
// EXPECTED: Ann(p1 = IntegerValueType(2), p2 = IntegerValueType(0), p3 = IntegerValueType(1), p4 = IntegerValueType(1), p5 = IntegerValueType(0))
// EXPECTED: Ann(p1 = 2, p2 = 0, p3 = 1, p4 = 1, p5 = 0)
@@ -10,4 +10,4 @@ annotation class Ann(p1: Int,
Ann(1 or 1, 1 and 1, 1 xor 1, 1 shl 1, 1 shr 1, 1 ushr 1) class MyClass
// EXPECTED: Ann(p1 = IntegerValueType(1), p2 = IntegerValueType(1), p3 = IntegerValueType(0), p4 = IntegerValueType(2), p5 = IntegerValueType(0), p6 = IntegerValueType(0))
// EXPECTED: Ann(p1 = 1, p2 = 1.toShort(), p3 = 0.toByte(), p4 = 2, p5 = 0, p6 = 0)
@@ -8,4 +8,4 @@ annotation class Ann(
Ann(1 + 1, java.lang.Long.MAX_VALUE + 1 - 1, java.lang.Long.MAX_VALUE - 1) class MyClass
// EXPECTED: Ann(l1 = IntegerValueType(2), l2 = 9223372036854775807.toLong(), l3 = 9223372036854775806.toLong())
// EXPECTED: Ann(l1 = 2.toLong(), l2 = 9223372036854775807.toLong(), l3 = 9223372036854775806.toLong())
@@ -16,4 +16,4 @@ Ann(
p5 = 1.toByte() + 1.toByte()
) class MyClass
// EXPECTED: Ann(p1 = 128, p2 = IntegerValueType(2), p3 = 128, p4 = 2, p5 = 2)
// EXPECTED: Ann(p1 = 128, p2 = 2.toByte(), p3 = 128, p4 = 2, p5 = 2)
@@ -16,4 +16,4 @@ Ann(
p5 = 1.toInt() + 1.toInt()
) class MyClass
// EXPECTED: Ann(p1 = -2147483648, p2 = IntegerValueType(2), p3 = -2147483648, p4 = 2, p5 = 2)
// EXPECTED: Ann(p1 = -2147483648, p2 = 2, p3 = -2147483648, p4 = 2, p5 = 2)
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1 * 1, 1 * 1, 1 * 1, 1 * 1) class MyClass
// EXPECTED: Ann(b = IntegerValueType(1), i = IntegerValueType(1), l = IntegerValueType(1), s = IntegerValueType(1))
// EXPECTED: Ann(b = 1.toByte(), i = 1, l = 1.toLong(), s = 1.toShort())
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1 - 1, 1 - 1, 1 - 1, 1 - 1) class MyClass
// EXPECTED: Ann(b = IntegerValueType(0), i = IntegerValueType(0), l = IntegerValueType(0), s = IntegerValueType(0))
// EXPECTED: Ann(b = 0.toByte(), i = 0, l = 0.toLong(), s = 0.toShort())
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1 % 1, 1 % 1, 1 % 1, 1 % 1) class MyClass
// EXPECTED: Ann(b = IntegerValueType(0), i = IntegerValueType(0), l = IntegerValueType(0), s = IntegerValueType(0))
// EXPECTED: Ann(b = 0.toByte(), i = 0, l = 0.toLong(), s = 0.toShort())
@@ -4,4 +4,4 @@ annotation class Ann(i: Int)
Ann((1 + 2) * 2) class MyClass
// EXPECTED: Ann(i = IntegerValueType(6))
// EXPECTED: Ann(i = 6)
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1 + 1, 1 + 1, 1 + 1, 1 + 1) class MyClass
// EXPECTED: Ann(b = IntegerValueType(2), i = IntegerValueType(2), l = IntegerValueType(2), s = IntegerValueType(2))
// EXPECTED: Ann(b = 2.toByte(), i = 2, l = 2.toLong(), s = 2.toShort())
@@ -10,4 +10,4 @@ annotation class Ann(
Ann(1.plus(1), 1.minus(1), 1.times(1), 1.div(1), 1.mod(1)) class MyClass
// EXPECTED: Ann(p1 = IntegerValueType(2), p2 = IntegerValueType(0), p3 = IntegerValueType(1), p4 = IntegerValueType(1), p5 = IntegerValueType(0))
// EXPECTED: Ann(p1 = 2, p2 = 0, p3 = 1, p4 = 1, p5 = 0)
@@ -11,4 +11,4 @@ annotation class Ann(
Ann(-1, -1, -1, -1, -1.0, -1.0.toFloat()) class MyClass
// EXPECTED: Ann(b1 = IntegerValueType(-1), b2 = IntegerValueType(-1), b3 = IntegerValueType(-1), b4 = IntegerValueType(-1), b5 = -1.0.toDouble(), b6 = -1.0.toFloat())
// EXPECTED: Ann(b1 = -1.toByte(), b2 = -1.toShort(), b3 = -1, b4 = -1.toLong(), b5 = -1.0.toDouble(), b6 = -1.0.toFloat())
@@ -11,4 +11,4 @@ annotation class Ann(
Ann(+1, +1, +1, +1, +1.0, +1.0.toFloat()) class MyClass
// EXPECTED: Ann(b1 = IntegerValueType(1), b2 = IntegerValueType(1), b3 = IntegerValueType(1), b4 = IntegerValueType(1), b5 = 1.0.toDouble(), b6 = 1.0.toFloat())
// EXPECTED: Ann(b1 = 1.toByte(), b2 = 1.toShort(), b3 = 1, b4 = 1.toLong(), b5 = 1.0.toDouble(), b6 = 1.0.toFloat())
+1 -1
View File
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1, 1.toInt(), 2147483648.toInt(), 2147483648) class MyClass
// EXPECTED: Ann(b1 = IntegerValueType(1), b2 = 1, b3 = -2147483648, b4 = IntegerValueType(2147483648))
// EXPECTED: Ann(b1 = 1, b2 = 1, b3 = -2147483648, b4 = 2147483648.toLong())
+1 -1
View File
@@ -7,4 +7,4 @@ annotation class Ann(
Ann(1, 1.toLong()) class MyClass
// EXPECTED: Ann(b1 = IntegerValueType(1), b2 = 1.toLong())
// EXPECTED: Ann(b1 = 1.toLong(), b2 = 1.toLong())
+1 -1
View File
@@ -9,4 +9,4 @@ annotation class Ann(
Ann(1, 1.toShort(), 32768.toShort(), 32768) class MyClass
// EXPECTED: Ann(b1 = IntegerValueType(1), b2 = 1.toShort(), b3 = -32768.toShort(), b4 = IntegerValueType(32768))
// EXPECTED: Ann(b1 = 1.toShort(), b2 = 1.toShort(), b3 = -32768.toShort(), b4 = 32768)
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.load.java.JavaBindingContext;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import java.util.*;
@@ -84,7 +84,7 @@ public class ExpectedLoadErrorsUtil {
if (annotation == null) return null;
// we expect exactly one annotation argument
CompileTimeConstant<?> argument = annotation.getAllValueArguments().values().iterator().next();
ConstantValue<?> argument = annotation.getAllValueArguments().values().iterator().next();
String error = (String) argument.getValue();
//noinspection ConstantConditions
@@ -21,7 +21,7 @@ import java.io.IOException;
public class AnnotationDescriptorResolveTest extends AbstractAnnotationDescriptorResolveTest {
public void testIntAnnotation() throws IOException {
String content = getContent("AnnInt(1)");
String expectedAnnotation = "AnnInt(a = IntegerValueType(1))";
String expectedAnnotation = "AnnInt(a = 1)";
doTest(content, expectedAnnotation);
}
@@ -51,13 +51,13 @@ public class AnnotationDescriptorResolveTest extends AbstractAnnotationDescripto
public void testIntArrayAnnotation() throws IOException {
String content = getContent("AnnIntArray(intArray(1, 2))");
String expectedAnnotation = "AnnIntArray(a = {IntegerValueType(1), IntegerValueType(2)})";
String expectedAnnotation = "AnnIntArray(a = {1, 2})";
doTest(content, expectedAnnotation);
}
public void testIntArrayVarargAnnotation() throws IOException {
String content = getContent("AnnIntVararg(1, 2)");
String expectedAnnotation = "AnnIntVararg(a = {IntegerValueType(1), IntegerValueType(2)})";
String expectedAnnotation = "AnnIntVararg(a = {1, 2})";
doTest(content, expectedAnnotation);
}
@@ -81,7 +81,7 @@ public class AnnotationDescriptorResolveTest extends AbstractAnnotationDescripto
public void testAnnotationAnnotation() throws Exception {
String content = getContent("AnnAnn(AnnInt(1))");
String expectedAnnotation = "AnnAnn(a = AnnInt(a = IntegerValueType(1)))";
String expectedAnnotation = "AnnAnn(a = AnnInt(a = 1))";
doTest(content, expectedAnnotation);
}
@@ -18,9 +18,12 @@ package org.jetbrains.kotlin.resolve.constants.evaluate
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.psi.JetProperty
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.annotation.AbstractAnnotationDescriptorResolveTest
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.JetTestUtils
@@ -47,12 +50,7 @@ public abstract class AbstractEvaluateExpressionTest : AbstractAnnotationDescrip
fun doIsPureTest(path: String) {
doTest(path) {
property, context ->
val compileTimeConstant = property.getCompileTimeInitializer()
if (compileTimeConstant is IntegerValueConstant) {
compileTimeConstant.isPure().toString()
} else {
"null"
}
evaluateInitializer(context, property)?.isPure.toString()
}
}
@@ -60,15 +58,20 @@ public abstract class AbstractEvaluateExpressionTest : AbstractAnnotationDescrip
fun doUsesVariableAsConstantTest(path: String) {
doTest(path) {
property, context ->
val compileTimeConstant = property.getCompileTimeInitializer()
if (compileTimeConstant == null) {
"null"
} else {
compileTimeConstant.usesVariableAsConstant().toString()
}
evaluateInitializer(context, property)?.usesVariableAsConstant.toString()
}
}
private fun evaluateInitializer(context: BindingContext, property: VariableDescriptor): CompileTimeConstant<*>? {
val propertyDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(property) as JetProperty
val compileTimeConstant = ConstantExpressionEvaluator.evaluate(
propertyDeclaration.getInitializer()!!,
DelegatingBindingTrace(context, "trace for evaluating compile time constant"),
property.getType()
)
return compileTimeConstant
}
private fun doTest(path: String, getValueToTest: (VariableDescriptor, BindingContext) -> String) {
val myFile = File(path)
val fileText = FileUtil.loadFile(myFile, true)
@@ -30,7 +30,8 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
import org.jetbrains.kotlin.types.*
@@ -64,7 +65,7 @@ class LazyJavaAnnotationDescriptor(
annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString())
}
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(true, false, false), c.module.builtIns)
private val factory = ConstantValueFactory(c.module.builtIns)
override fun getType(): JetType = type()
@@ -74,7 +75,7 @@ class LazyJavaAnnotationDescriptor(
override fun getAllValueArguments() = allValueArguments()
private fun computeValueArguments(): Map<ValueParameterDescriptor, CompileTimeConstant<*>> {
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
val constructors = getAnnotationClass().getConstructors()
if (constructors.isEmpty()) return mapOf()
@@ -100,9 +101,9 @@ class LazyJavaAnnotationDescriptor(
private fun getAnnotationClass() = getType().getConstructor().getDeclarationDescriptor() as ClassDescriptor
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): CompileTimeConstant<*>? {
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? {
return when (argument) {
is JavaLiteralAnnotationArgument -> factory.createCompileTimeConstant(argument.value)
is JavaLiteralAnnotationArgument -> factory.createConstantValue(argument.value)
is JavaEnumValueAnnotationArgument -> resolveFromEnumValue(argument.resolve())
is JavaArrayAnnotationArgument -> resolveFromArray(argument.name ?: DEFAULT_ANNOTATION_MEMBER_NAME, argument.getElements())
is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation())
@@ -111,13 +112,13 @@ class LazyJavaAnnotationDescriptor(
}
}
private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): CompileTimeConstant<*>? {
private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): ConstantValue<*>? {
val descriptor = c.resolveAnnotation(javaAnnotation) ?: return null
return factory.createAnnotationValue(descriptor)
}
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): CompileTimeConstant<*>? {
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): ConstantValue<*>? {
if (getType().isError()) return null
val valueParameter = DescriptorResolverUtils.getAnnotationParameterByName(argumentName, getAnnotationClass()) ?: return null
@@ -128,7 +129,7 @@ class LazyJavaAnnotationDescriptor(
return factory.createArrayValue(values, valueParameter.getType())
}
private fun resolveFromEnumValue(element: JavaField?): CompileTimeConstant<*>? {
private fun resolveFromEnumValue(element: JavaField?): ConstantValue<*>? {
if (element == null || !element.isEnumEntry()) return null
val containingJavaClass = element.getContainingClass()
@@ -142,7 +143,7 @@ class LazyJavaAnnotationDescriptor(
return factory.createEnumValue(classifier)
}
private fun resolveFromJavaClassObjectType(javaType: JavaType): CompileTimeConstant<*>? {
private fun resolveFromJavaClassObjectType(javaType: JavaType): ConstantValue<*>? {
// Class type is never nullable in 'Foo.class' in Java
val type = TypeUtils.makeNotNullable(c.typeResolver.transformJavaType(
javaType,
@@ -181,7 +181,7 @@ class LazyJavaClassDescriptor(
getAnnotations().
findAnnotation(JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION) ?: return null
val fqNameString = (annotation.getAllValueArguments().values().singleOrNull() as? StringValue)?.getValue() ?: return null
val fqNameString = (annotation.getAllValueArguments().values().singleOrNull() as? StringValue)?.value ?: return null
if (!isValidJavaFqName(fqNameString)) return null
return FqName(fqNameString)
@@ -1,42 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
public interface JavaPropertyInitializerEvaluator {
JavaPropertyInitializerEvaluator DO_NOTHING = new JavaPropertyInitializerEvaluator() {
@Nullable
@Override
public CompileTimeConstant<?> getInitializerConstant(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor) {
return null;
}
@Override
public boolean isNotNullCompileTimeConstant(@NotNull JavaField field) {
return false;
}
};
@Nullable
CompileTimeConstant<?> getInitializerConstant(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor);
boolean isNotNullCompileTimeConstant(@NotNull JavaField field);
}
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.java.structure
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.resolve.constants.ConstantValue
public interface JavaPropertyInitializerEvaluator {
public fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>?
public fun isNotNullCompileTimeConstant(field: JavaField): Boolean
public object DoNothing : JavaPropertyInitializerEvaluator {
override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor) = null
override fun isNotNullCompileTimeConstant(field: JavaField) = false
}
}
@@ -26,7 +26,9 @@ import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
@@ -42,16 +44,16 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
storageManager: StorageManager,
kotlinClassFinder: KotlinClassFinder,
errorReporter: ErrorReporter
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, CompileTimeConstant<*>>(
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>>(
storageManager, kotlinClassFinder, errorReporter
) {
private val annotationDeserializer = AnnotationDeserializer(module)
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.ThrowException, module.builtIns)
private val factory = ConstantValueFactory(module.builtIns)
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor =
annotationDeserializer.deserializeAnnotation(proto, nameResolver)
override fun loadConstant(desc: String, initializer: Any): CompileTimeConstant<*>? {
override fun loadConstant(desc: String, initializer: Any): ConstantValue<*>? {
val normalizedValue: Any = if (desc in "ZBCS") {
val intValue = initializer as Int
when (desc) {
@@ -66,7 +68,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
initializer
}
return factory.createCompileTimeConstant(normalizedValue)
return factory.createConstantValue(normalizedValue)
}
override fun loadAnnotation(
@@ -76,7 +78,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
val annotationClass = resolveClass(annotationClassId)
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
private val arguments = HashMap<ValueParameterDescriptor, CompileTimeConstant<*>>()
private val arguments = HashMap<ValueParameterDescriptor, ConstantValue<*>>()
override fun visit(name: Name?, value: Any?) {
if (name != null) {
@@ -90,7 +92,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
override fun visitArray(name: Name): AnnotationArrayArgumentVisitor? {
return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
private val elements = ArrayList<CompileTimeConstant<*>>()
private val elements = ArrayList<ConstantValue<*>>()
override fun visit(value: Any?) {
elements.add(createConstant(name, value))
@@ -122,7 +124,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
}
// NOTE: see analogous code in AnnotationDeserializer
private fun enumEntryValue(enumClassId: ClassId, name: Name): CompileTimeConstant<*> {
private fun enumEntryValue(enumClassId: ClassId, name: Name): ConstantValue<*> {
val enumClass = resolveClass(enumClassId)
if (enumClass.getKind() == ClassKind.ENUM_CLASS) {
val classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name)
@@ -137,12 +139,12 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
result.add(AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments))
}
private fun createConstant(name: Name?, value: Any?): CompileTimeConstant<*> {
return factory.createCompileTimeConstant(value) ?:
private fun createConstant(name: Name?, value: Any?): ConstantValue<*> {
return factory.createConstantValue(value) ?:
factory.createErrorValue("Unsupported annotation argument: $name")
}
private fun setArgumentValueByName(name: Name, argumentValue: CompileTimeConstant<*>) {
private fun setArgumentValueByName(name: Name, argumentValue: ConstantValue<*>) {
val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass)
if (parameter != null) {
arguments[parameter] = argumentValue
@@ -50,7 +50,7 @@ public class RuntimeModuleData private constructor(public val module: ModuleDesc
val globalJavaResolverContext = GlobalJavaResolverContext(
storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver,
ExternalAnnotationResolver.EMPTY, ExternalSignatureResolver.DO_NOTHING, RuntimeErrorReporter, JavaResolverCache.EMPTY,
JavaPropertyInitializerEvaluator.DO_NOTHING, SamConversionResolver, RuntimeSourceElementFactory, singleModuleClassResolver
JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver, RuntimeSourceElementFactory, singleModuleClassResolver
)
val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext, module, ReflectionTypes(module))
val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, module)
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.builtins
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.*
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.types.JetType
class BuiltInsAnnotationAndConstantLoader(
module: ModuleDescriptor
) : AnnotationAndConstantLoader<AnnotationDescriptor, CompileTimeConstant<*>> {
) : AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>> {
private val deserializer = AnnotationDeserializer(module)
override fun loadClassAnnotations(
@@ -68,7 +68,7 @@ class BuiltInsAnnotationAndConstantLoader(
proto: ProtoBuf.Callable,
nameResolver: NameResolver,
expectedType: JetType
): CompileTimeConstant<*>? {
): ConstantValue<*>? {
val value = proto.getExtension(BuiltInsProtoBuf.compileTimeValue)
return deserializer.resolveValue(expectedType, value, nameResolver)
}
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.types.*;
@@ -659,7 +659,7 @@ public class KotlinBuiltIns {
@NotNull
public AnnotationDescriptor createExtensionAnnotation() {
return new AnnotationDescriptorImpl(getBuiltInClassByName("extension").getDefaultType(),
Collections.<ValueParameterDescriptor, CompileTimeConstant<?>>emptyMap());
Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap());
}
private static boolean isTypeAnnotatedWithExtension(@NotNull JetType type) {
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeSubstitutor;
@@ -36,5 +36,5 @@ public interface VariableDescriptor extends CallableDescriptor {
boolean isVar();
@Nullable
CompileTimeConstant<?> getCompileTimeInitializer();
ConstantValue<?> getCompileTimeInitializer();
}
@@ -50,6 +50,4 @@ public interface AnnotationArgumentVisitor<R, D> {
R visitAnnotationValue(AnnotationValue value, D data);
R visitKClassValue(KClassValue value, D data);
R visitNumberTypeValue(IntegerValueTypeConstant value, D data);
}
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.descriptors.annotations;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.types.JetType;
import java.util.Map;
@@ -30,5 +30,5 @@ public interface AnnotationDescriptor {
@NotNull
@ReadOnly
Map<ValueParameterDescriptor, CompileTimeConstant<?>> getAllValueArguments();
Map<ValueParameterDescriptor, ConstantValue<?>> getAllValueArguments();
}
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.descriptors.annotations;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.types.JetType;
import java.util.Collections;
@@ -27,11 +27,11 @@ import java.util.Map;
public class AnnotationDescriptorImpl implements AnnotationDescriptor {
private final JetType annotationType;
private final Map<ValueParameterDescriptor, CompileTimeConstant<?>> valueArguments;
private final Map<ValueParameterDescriptor, ConstantValue<?>> valueArguments;
public AnnotationDescriptorImpl(
@NotNull JetType annotationType,
@NotNull Map<ValueParameterDescriptor, CompileTimeConstant<?>> valueArguments
@NotNull Map<ValueParameterDescriptor, ConstantValue<?>> valueArguments
) {
this.annotationType = annotationType;
this.valueArguments = Collections.unmodifiableMap(valueArguments);
@@ -45,7 +45,7 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor {
@Override
@NotNull
public Map<ValueParameterDescriptor, CompileTimeConstant<?>> getAllValueArguments() {
public Map<ValueParameterDescriptor, ConstantValue<?>> getAllValueArguments() {
return valueArguments;
}
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.constants.StringValue;
public abstract class DefaultAnnotationArgumentVisitor<R, D> implements AnnotationArgumentVisitor<R, D> {
public abstract R visitValue(@NotNull CompileTimeConstant<?> value, D data);
public abstract R visitValue(@NotNull ConstantValue<?> value, D data);
@Override
public R visitLongValue(@NotNull LongValue value, D data) {
@@ -92,9 +92,4 @@ public abstract class DefaultAnnotationArgumentVisitor<R, D> implements Annotati
public R visitAnnotationValue(AnnotationValue value, D data) {
return visitValue(value, data);
}
@Override
public R visitNumberTypeValue(IntegerValueTypeConstant value, D data) {
return visitValue(value, data);
}
}
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.storage.NullableLazyValue;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.LazyType;
@@ -32,7 +32,7 @@ import java.util.Set;
public abstract class VariableDescriptorImpl extends DeclarationDescriptorNonRootImpl implements VariableDescriptor {
private JetType outType;
protected NullableLazyValue<CompileTimeConstant<?>> compileTimeInitializer;
protected NullableLazyValue<ConstantValue<?>> compileTimeInitializer;
public VariableDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@@ -59,7 +59,7 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorNonRoo
@Nullable
@Override
public CompileTimeConstant<?> getCompileTimeInitializer() {
public ConstantValue<?> getCompileTimeInitializer() {
// Force computation and setting of compileTimeInitializer, if needed
if (compileTimeInitializer == null && outType instanceof LazyType) {
outType.getConstructor();
@@ -71,7 +71,7 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorNonRoo
return null;
}
public void setCompileTimeInitializer(@NotNull NullableLazyValue<CompileTimeConstant<?>> compileTimeInitializer) {
public void setCompileTimeInitializer(@NotNull NullableLazyValue<ConstantValue<?>> compileTimeInitializer) {
assert !isVar() : "Compile-time value for property initializer should be recorded only for final variables " + getName();
this.compileTimeInitializer = compileTimeInitializer;
}
@@ -20,23 +20,20 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.DefaultAnnotationArgumentVisitor
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameBase
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.KClassValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.ErrorUtils.UninferredParameterTypeConstructor
import org.jetbrains.kotlin.types.error.MissingDependencyErrorClass
import org.jetbrains.kotlin.utils.*
import java.util.*
import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject
import org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE
import org.jetbrains.kotlin.types.error.MissingDependencyErrorClass
import java.util.ArrayList
internal class DescriptorRendererImpl(
val options: DescriptorRendererOptionsImpl
@@ -384,7 +381,7 @@ internal class DescriptorRendererImpl(
return (defaultList + argumentList).sort()
}
private fun renderConstant(value: CompileTimeConstant<*>): String {
private fun renderConstant(value: ConstantValue<*>): String {
return when (value) {
is ArrayValue -> value.value.map { renderConstant(it) }.joinToString(", ", "{", "}")
is AnnotationValue -> renderAnnotation(value.value)
@@ -709,9 +706,8 @@ internal class DescriptorRendererImpl(
private fun renderInitializer(variable: VariableDescriptor, builder: StringBuilder) {
if (includePropertyConstant) {
val initializer = variable.getCompileTimeInitializer()
if (initializer != null) {
builder.append(" = ").append(escape(renderConstant(initializer)))
variable.getCompileTimeInitializer()?.let { constant ->
builder.append(" = ").append(escape(renderConstant(constant)))
}
}
}

Some files were not shown because too many files have changed in this diff Show More