Add a superclass for byte, short, int, long compile-time constants

This commit is contained in:
Natalia Ukhorskaya
2014-01-29 16:29:27 +04:00
parent 1cd7fa65d7
commit 9672026a53
25 changed files with 75 additions and 77 deletions
@@ -214,7 +214,13 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
}
private fun canBeUsedInAnnotation(expression: JetExpression) = trace.get(BindingContext.COMPILE_TIME_VALUE, expression)?.canBeUsedInAnnotations() ?: false
private fun isPureConstant(expression: JetExpression) = trace.get(BindingContext.COMPILE_TIME_VALUE, expression)?.isPure() ?: false
private fun isPureConstant(expression: JetExpression): Boolean {
val compileTimeConstant = trace.get(BindingContext.COMPILE_TIME_VALUE, expression)
if (compileTimeConstant is IntegerValueConstant) {
return compileTimeConstant.isPure()
}
return false
}
private fun evaluateUnaryAndCheck(receiver: OperationArgument, name: String, callExpression: JetExpression): Any? {
val functions = unaryOperations[UnaryOperationKey(receiver.ctcType, name)]
@@ -439,7 +445,7 @@ public fun recordCompileTimeValueForInitializerIfNeeded(
}
public fun IntegerValueTypeConstant.createCompileTimeConstantWithType(expectedType: JetType): CompileTimeConstant<*>?
= createCompileTimeConstant(this.getValue(expectedType), EvaluatorContext(this.canBeUsedInAnnotations(), this.isPure()))
= createCompileTimeConstant(this.getValue(expectedType), EvaluatorContext(this.canBeUsedInAnnotations(), true))
private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L')
@@ -39,6 +39,7 @@ import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImp
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsUtil;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueConstant;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -466,9 +467,9 @@ public class CallExpressionResolver {
}
CompileTimeConstant<?> value = ConstantExpressionEvaluator.object$.evaluate(expression, context.trace, context.expectedType);
if (value != null && value.isPure()) {
return BasicExpressionTypingVisitor.createCompileTimeConstantTypeInfo(value, expression, context);
}
if (value instanceof IntegerValueConstant && ((IntegerValueConstant) value).isPure()) {
return BasicExpressionTypingVisitor.createCompileTimeConstantTypeInfo(value, expression, context);
}
JetTypeInfo typeInfo = JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo());
if (context.contextDependency == INDEPENDENT) {
@@ -1,9 +0,0 @@
package test
enum class MyEnum { A }
// val prop1: false
val prop1 = MyEnum.A
// val prop2: false
val prop2 = javaClass<MyEnum>()
@@ -1,16 +0,0 @@
package test
// val prop1: false
val prop1 = ""
// val prop2: false
val prop2 = "a"
// val prop3: false
val prop3 = "\"a\""
// val prop5: false
val prop5 = "a${1 + 1}"
// val prop6: false
val prop6 = "a" + "b"
@@ -14,9 +14,3 @@ val prop4 = 1.toShort()
// val prop5: false
val prop5 = 1.toChar()
// val prop6: false
val prop6 = 1.toDouble()
// val prop7: false
val prop7 = 1.toFloat()
@@ -33,8 +33,9 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant
import org.jetbrains.jet.lang.resolve.constants.StringValue
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
import org.jetbrains.jet.lang.resolve.constants.IntegerValueConstant
abstract class AbstractEvaluateExpressionTest: AbstractAnnotationDescriptorResolveTest() {
abstract class AbstractEvaluateExpressionTest : AbstractAnnotationDescriptorResolveTest() {
// Test directives should look like [// val testedPropertyName: expectedValue]
fun doConstantTest(path: String) {
@@ -43,8 +44,7 @@ abstract class AbstractEvaluateExpressionTest: AbstractAnnotationDescriptorResol
val compileTimeConstant = context.get(BindingContext.COMPILE_TIME_VALUE, property.getInitializer())
if (compileTimeConstant is StringValue) {
"\\\"${compileTimeConstant.getValue()}\\\""
}
else {
} else {
compileTimeConstant.toString()
}
}
@@ -55,7 +55,11 @@ abstract class AbstractEvaluateExpressionTest: AbstractAnnotationDescriptorResol
doTest(path) {
property, context ->
val compileTimeConstant = context.get(BindingContext.COMPILE_TIME_VALUE, property.getInitializer())
compileTimeConstant?.isPure().toString()
if (compileTimeConstant is IntegerValueConstant) {
compileTimeConstant.isPure().toString()
} else {
"null"
}
}
}
@@ -74,7 +78,7 @@ abstract class AbstractEvaluateExpressionTest: AbstractAnnotationDescriptorResol
assertNotNull(expected, "Failed to find expected directive: $expectedPropertyPrefix")
val property = AbstractAnnotationDescriptorResolveTest.getPropertyDescriptor(packageView, propertyName, false)
?: AbstractAnnotationDescriptorResolveTest.getLocalVarDescriptor(context!!, propertyName)
?: AbstractAnnotationDescriptorResolveTest.getLocalVarDescriptor(context!!, propertyName)
val jetProperty = BindingContextUtils.descriptorToDeclaration(context!!, property) as JetProperty
@@ -96,8 +100,7 @@ abstract class AbstractEvaluateExpressionTest: AbstractAnnotationDescriptorResol
val matcher = pattern.matcher(it)
if (matcher.find()) {
matcher.group(0) ?: "Couldn't match tested object $it"
}
else "Couldn't match tested object $it"
} else "Couldn't match tested object $it"
}
}
@@ -136,11 +136,6 @@ public class EvaluateExpressionTestGenerated extends AbstractEvaluateExpressionT
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/evaluate/isPure"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("enum.kt")
public void testEnum() throws Exception {
doIsPureTest("compiler/testData/evaluate/isPure/enum.kt");
}
@TestMetadata("innerToType.kt")
public void testInnerToType() throws Exception {
doIsPureTest("compiler/testData/evaluate/isPure/innerToType.kt");
@@ -151,11 +146,6 @@ public class EvaluateExpressionTestGenerated extends AbstractEvaluateExpressionT
doIsPureTest("compiler/testData/evaluate/isPure/namedConstants.kt");
}
@TestMetadata("strings.kt")
public void testStrings() throws Exception {
doIsPureTest("compiler/testData/evaluate/isPure/strings.kt");
}
@TestMetadata("toType.kt")
public void testToType() throws Exception {
doIsPureTest("compiler/testData/evaluate/isPure/toType.kt");
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public class AnnotationValue extends CompileTimeConstant<AnnotationDescriptor> {
public AnnotationValue(@NotNull AnnotationDescriptor value) {
super(value, true, false);
super(value, true);
}
@NotNull
@@ -28,7 +28,7 @@ public class ArrayValue extends CompileTimeConstant<List<CompileTimeConstant<?>>
private final JetType type;
public ArrayValue(@NotNull List<CompileTimeConstant<?>> value, @NotNull JetType type, boolean canBeUsedInAnnotations) {
super(value, canBeUsedInAnnotations, false);
super(value, canBeUsedInAnnotations);
this.type = type;
}
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.types.JetType;
public class BooleanValue extends CompileTimeConstant<Boolean> {
public BooleanValue(boolean value, boolean canBeUseInAnnotation) {
super(value, canBeUseInAnnotation, false);
super(value, canBeUseInAnnotation);
}
@NotNull
@@ -21,7 +21,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public class ByteValue extends CompileTimeConstant<Byte> {
public class ByteValue extends IntegerValueConstant<Byte> {
public ByteValue(byte value, boolean canBeUsedInAnnotations, boolean pure) {
super(value, canBeUsedInAnnotations, pure);
@@ -21,7 +21,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lang.types.JetType;
public class CharValue extends CompileTimeConstant<Character> {
public class CharValue extends IntegerValueConstant<Character> {
public CharValue(char value, boolean canBeUsedInAnnotations, boolean pure) {
super(value, canBeUsedInAnnotations, pure);
@@ -25,23 +25,16 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public abstract class CompileTimeConstant<T> {
protected final T value;
private final boolean canBeUsedInAnnotations;
// if false = constant type cannot be changed, ex. val a: Long = 1.toInt() (should be a TYPE_MISMATCH error, 1.toInt() isn't pure)
private final boolean isPure;
protected CompileTimeConstant(T value, boolean canBeUsedInAnnotations, boolean pure) {
protected CompileTimeConstant(T value, boolean canBeUsedInAnnotations) {
this.value = value;
this.canBeUsedInAnnotations = canBeUsedInAnnotations;
this.isPure = pure;
}
public boolean canBeUsedInAnnotations() {
return canBeUsedInAnnotations;
}
public boolean isPure() {
return isPure;
}
@Nullable
public T getValue() {
return value;
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.types.JetType;
public class DoubleValue extends CompileTimeConstant<Double> {
public DoubleValue(double value, boolean canBeUsedInAnnotations) {
super(value, canBeUsedInAnnotations, false);
super(value, canBeUsedInAnnotations);
}
@NotNull
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public class EnumValue extends CompileTimeConstant<ClassDescriptor> {
public EnumValue(@NotNull ClassDescriptor value) {
super(value, true, false);
super(value, true);
}
@NotNull
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public abstract class ErrorValue extends CompileTimeConstant<Void> {
public ErrorValue() {
super(null, true, false);
super(null, true);
}
@Override
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.types.JetType;
public class FloatValue extends CompileTimeConstant<Float> {
public FloatValue(float value, boolean canBeUsedInAnnotations) {
super(value, canBeUsedInAnnotations, false);
super(value, canBeUsedInAnnotations);
}
@NotNull
@@ -21,7 +21,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public class IntValue extends CompileTimeConstant<Integer> {
public class IntValue extends IntegerValueConstant<Integer> {
public IntValue(int value, boolean canBeUsedInAnnotations, boolean pure) {
super(value, canBeUsedInAnnotations, pure);
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2014 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.jet.lang.resolve.constants;
public abstract class IntegerValueConstant<T> extends CompileTimeConstant<T> {
/*
* if false then constant type cannot be changed
* ex1. val a: Long = 1.toInt() (TYPE_MISMATCH error, 1.toInt() isn't pure)
* ex2. val b: Int = a (TYPE_MISMATCH error, a isn't pure)
* */
private final boolean isPure;
protected IntegerValueConstant(T value, boolean canBeUsedInAnnotations, boolean pure) {
super(value, canBeUsedInAnnotations);
isPure = pure;
}
public boolean isPure() {
return isPure;
}
}
@@ -26,7 +26,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import java.util.Collections;
public class IntegerValueTypeConstant extends CompileTimeConstant<Number> {
public class IntegerValueTypeConstant extends IntegerValueConstant<Number> {
private final IntegerValueTypeConstructor typeConstructor;
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public class JavaClassValue extends CompileTimeConstant<JetType> {
public JavaClassValue(@NotNull JetType value) {
super(value, true, false);
super(value, true);
}
@NotNull
@@ -21,7 +21,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public class LongValue extends CompileTimeConstant<Long> {
public class LongValue extends IntegerValueConstant<Long> {
public LongValue(long value, boolean canBeUsedInAnnotations, boolean pure) {
super(value, canBeUsedInAnnotations, pure);
@@ -26,7 +26,7 @@ public class NullValue extends CompileTimeConstant<Void> {
public static final NullValue NULL = new NullValue();
private NullValue() {
super(null, false, false);
super(null, false);
}
@NotNull
@@ -21,7 +21,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
public class ShortValue extends CompileTimeConstant<Short> {
public class ShortValue extends IntegerValueConstant<Short> {
public ShortValue(short value, boolean canBeUsedInAnnotations, boolean pure) {
super(value, canBeUsedInAnnotations, pure);
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.types.JetType;
public class StringValue extends CompileTimeConstant<String> {
public StringValue(String value, boolean canBeUsedInAnnotations) {
super(value, canBeUsedInAnnotations, false);
super(value, canBeUsedInAnnotations);
}
@NotNull