Record COMPILE_TIME_INITIALIZER for all final variables
This commit is contained in:
+57
-29
@@ -182,8 +182,9 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
|
||||
if (argumentsEntrySet.isEmpty()) {
|
||||
val result = evaluateUnaryAndCheck(argumentForReceiver, resultingDescriptorName.asString(), callExpression)
|
||||
val isArgumentPure = trace.get(BindingContext.IS_PURE_CONSTANT_EXPRESSION, argumentForReceiver.expression) ?: false
|
||||
val canBeUsedInAnnotation = canBeUsedInAnnotation(argumentForReceiver.expression)
|
||||
val isNumberConversionMethod = resultingDescriptorName in OperatorConventions.NUMBER_CONVERSIONS
|
||||
return createCompileTimeConstant(result, fullExpression, expectedType, !isNumberConversionMethod && isArgumentPure)
|
||||
return createCompileTimeConstant(result, fullExpression, expectedType, !isNumberConversionMethod && isArgumentPure, canBeUsedInAnnotation)
|
||||
}
|
||||
else if (argumentsEntrySet.size() == 1) {
|
||||
val (parameter, argument) = argumentsEntrySet.first()
|
||||
@@ -203,7 +204,8 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
|
||||
else -> {
|
||||
val areArgumentsPure = trace.get(BindingContext.IS_PURE_CONSTANT_EXPRESSION, argumentForReceiver.expression) ?: false &&
|
||||
trace.get(BindingContext.IS_PURE_CONSTANT_EXPRESSION, argumentForParameter.expression) ?: false
|
||||
createCompileTimeConstant(result, fullExpression, expectedType, areArgumentsPure)
|
||||
val canBeUsedInAnnotation = canBeUsedInAnnotation(argumentForReceiver.expression) && canBeUsedInAnnotation(argumentForParameter.expression)
|
||||
createCompileTimeConstant(result, fullExpression, expectedType, areArgumentsPure, canBeUsedInAnnotation)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,6 +213,8 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
|
||||
return null
|
||||
}
|
||||
|
||||
private fun canBeUsedInAnnotation(expression: JetExpression) = trace.get(BindingContext.COMPILE_TIME_VALUE, expression)?.canBeUsedInAnnotations() ?: false
|
||||
|
||||
private fun evaluateUnaryAndCheck(receiver: OperationArgument, name: String, callExpression: JetExpression): Any? {
|
||||
val functions = unaryOperations[UnaryOperationKey(receiver.ctcType, name)]
|
||||
if (functions == null) return null
|
||||
@@ -254,7 +258,7 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
|
||||
return actualResult
|
||||
}
|
||||
|
||||
private fun isDivisionByZero(name: String, parameter: Any?): Boolean {
|
||||
private fun isDivisionByZero(name: String, parameter: Any?): Boolean {
|
||||
if (name == OperatorConventions.BINARY_OPERATION_NAMES[JetTokens.DIV]!!.asString()) {
|
||||
if (isIntegerType(parameter)) {
|
||||
return (parameter as Number).toLong() == 0.toLong()
|
||||
@@ -282,10 +286,17 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
|
||||
val resolvedCall = trace.getBindingContext().get(BindingContext.RESOLVED_CALL, expression)
|
||||
if (resolvedCall != null) {
|
||||
val callableDescriptor = resolvedCall.getResultingDescriptor()
|
||||
if (callableDescriptor is PropertyDescriptor) {
|
||||
if (AnnotationUtils.isPropertyCompileTimeConstant(callableDescriptor)) {
|
||||
return trace.getBindingContext().get(COMPILE_TIME_INITIALIZER, callableDescriptor)
|
||||
}
|
||||
if (callableDescriptor is VariableDescriptor) {
|
||||
val compileTimeConstant = trace.getBindingContext().get(COMPILE_TIME_INITIALIZER, callableDescriptor)
|
||||
if (compileTimeConstant == null) return null
|
||||
|
||||
val value: Any? =
|
||||
if (compileTimeConstant is IntegerValueTypeConstant)
|
||||
compileTimeConstant.getValue(expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
|
||||
else
|
||||
compileTimeConstant.getValue()
|
||||
return createCompileTimeConstant(value, expression, expectedType, false,
|
||||
AnnotationUtils.isPropertyCompileTimeConstant(callableDescriptor))
|
||||
}
|
||||
}
|
||||
return null
|
||||
@@ -306,7 +317,11 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
|
||||
|
||||
// MyEnum.A, Integer.MAX_VALUE
|
||||
if (selectorExpression != null) {
|
||||
return evaluate(selectorExpression, expectedType)
|
||||
val compileTimeConstant = evaluate(selectorExpression, expectedType)
|
||||
if (trace.get(BindingContext.IS_PURE_CONSTANT_EXPRESSION, selectorExpression) == true) {
|
||||
trace.record(BindingContext.IS_PURE_CONSTANT_EXPRESSION, expression, true)
|
||||
}
|
||||
return compileTimeConstant
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -404,18 +419,36 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
|
||||
return OperationArgument(evaluationResult, compileTimeType, expression)
|
||||
}
|
||||
|
||||
fun createCompileTimeConstant(value: Any?, expression: JetExpression, expectedType: JetType?, isPure: Boolean = true): CompileTimeConstant<*>? {
|
||||
if (isPure) {
|
||||
val compileTimeConstant = createCompileTimeConstant(value, expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
|
||||
trace.record(BindingContext.IS_PURE_CONSTANT_EXPRESSION, expression, true)
|
||||
return compileTimeConstant
|
||||
}
|
||||
fun createCompileTimeConstant(value: Any?, expression: JetExpression, expectedType: JetType?, isPure: Boolean = true, canBeUsedInAnnotation: Boolean = true): CompileTimeConstant<*>? {
|
||||
val compileTimeConstant =
|
||||
if (isPure) {
|
||||
trace.record(BindingContext.IS_PURE_CONSTANT_EXPRESSION, expression, true)
|
||||
createCompileTimeConstant(value, expectedType ?: TypeUtils.NO_EXPECTED_TYPE)
|
||||
}
|
||||
else createCompileTimeConstant(value)
|
||||
|
||||
compileTimeConstant?.setCanBeUsedInAnnotations(canBeUsedInAnnotation)
|
||||
|
||||
val compileTimeConstant = createCompileTimeConstant(value)
|
||||
return compileTimeConstant
|
||||
}
|
||||
}
|
||||
|
||||
public fun recordCompileTimeValueForInitializerIfNeeded(
|
||||
variableDescriptor: VariableDescriptor,
|
||||
initializer: JetExpression,
|
||||
variableType: JetType,
|
||||
trace: BindingTrace
|
||||
) {
|
||||
if (!variableDescriptor.isVar()) {
|
||||
if (trace.get(BindingContext.COMPILE_TIME_INITIALIZER, variableDescriptor) == null) {
|
||||
val constant = ConstantExpressionEvaluator.evaluate(initializer, trace, variableType)
|
||||
if (constant != null) {
|
||||
trace.record(BindingContext.COMPILE_TIME_INITIALIZER, variableDescriptor, constant)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun IntegerValueTypeConstant.createCompileTimeConstantWithType(expectedType: JetType): CompileTimeConstant<*>?
|
||||
= createCompileTimeConstant(getValue(expectedType))
|
||||
|
||||
@@ -524,21 +557,16 @@ private fun createStringConstant(value: CompileTimeConstant<*>?): StringValue? {
|
||||
}
|
||||
|
||||
private fun createCompileTimeConstant(value: Any?, expectedType: JetType? = null): CompileTimeConstant<*>? {
|
||||
return when(value) {
|
||||
is Byte, is Short, is Int, is Long -> {
|
||||
return if (expectedType == null) {
|
||||
when(value) {
|
||||
is Byte -> ByteValue(value)
|
||||
is Short -> ShortValue(value)
|
||||
is Int -> IntValue(value)
|
||||
is Long -> LongValue(value)
|
||||
else -> throw IllegalArgumentException("All cases should be catched: $value")
|
||||
}
|
||||
}
|
||||
else {
|
||||
getIntegerValue((value as Number).toLong(), expectedType)
|
||||
}
|
||||
if (expectedType == null) {
|
||||
when(value) {
|
||||
is Byte -> return ByteValue(value)
|
||||
is Short -> return ShortValue(value)
|
||||
is Int -> return IntValue(value)
|
||||
is Long -> return LongValue(value)
|
||||
}
|
||||
}
|
||||
return when(value) {
|
||||
is Byte, is Short, is Int, is Long -> getIntegerValue((value as Number).toLong(), expectedType)
|
||||
is Char -> CharValue(value)
|
||||
is Float -> FloatValue(value)
|
||||
is Double -> DoubleValue(value)
|
||||
|
||||
@@ -252,7 +252,7 @@ public class AnnotationResolver {
|
||||
JetType defaultType = ((IntegerValueTypeConstant) constant).getType(expectedType);
|
||||
ArgumentTypeResolver.updateNumberType(defaultType, argumentExpression, trace);
|
||||
}
|
||||
if (constant != null) {
|
||||
if (constant != null && constant.canBeUsedInAnnotations()) {
|
||||
constants.add(constant);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -20,7 +20,6 @@ import jet.runtime.Intrinsic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
@@ -116,7 +115,7 @@ public class AnnotationUtils {
|
||||
return "kotlin.javaClass.function".equals(getIntrinsicAnnotationArgument(resolvedCall.getResultingDescriptor().getOriginal()));
|
||||
}
|
||||
|
||||
public static boolean isPropertyCompileTimeConstant(@NotNull PropertyDescriptor descriptor) {
|
||||
public static boolean isPropertyCompileTimeConstant(@NotNull VariableDescriptor descriptor) {
|
||||
if (descriptor.isVar()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public interface BindingContext {
|
||||
|
||||
WritableSlice<JetExpression, Boolean> IS_PURE_CONSTANT_EXPRESSION = Slices.createSimpleSlice();
|
||||
WritableSlice<JetExpression, CompileTimeConstant<?>> COMPILE_TIME_VALUE = Slices.createSimpleSlice();
|
||||
WritableSlice<PropertyDescriptor, CompileTimeConstant<?>> COMPILE_TIME_INITIALIZER = Slices.createSimpleSlice();
|
||||
WritableSlice<VariableDescriptor, CompileTimeConstant<?>> COMPILE_TIME_INITIALIZER = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<JetTypeReference, JetType> TYPE = Slices.createSimpleSlice();
|
||||
WritableSlice<JetExpression, JetType> EXPRESSION_TYPE = new BasicWritableSlice<JetExpression, JetType>(DO_NOTHING);
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
||||
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency;
|
||||
@@ -33,7 +33,6 @@ import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCacheImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.SimpleResolutionContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
@@ -573,12 +572,8 @@ public class BodyResolver {
|
||||
scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace);
|
||||
JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, context.getOuterDataFlowInfo(), trace);
|
||||
if (AnnotationUtils.isPropertyCompileTimeConstant(propertyDescriptor)) {
|
||||
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.object$.evaluate(initializer, trace, expectedTypeForInitializer);
|
||||
if (constant != null) {
|
||||
trace.record(BindingContext.COMPILE_TIME_INITIALIZER, propertyDescriptor, constant);
|
||||
}
|
||||
}
|
||||
|
||||
EvaluatePackage.recordCompileTimeValueForInitializerIfNeeded(propertyDescriptor, initializer, expectedTypeForInitializer, trace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1;
|
||||
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
@@ -952,6 +953,10 @@ public class DescriptorResolver {
|
||||
JetType type =
|
||||
resolveInitializerType(scope, initializer, dataFlowInfo, trace);
|
||||
|
||||
EvaluatePackage.recordCompileTimeValueForInitializerIfNeeded(
|
||||
variableDescriptor,
|
||||
initializer, type,
|
||||
trace);
|
||||
return transformAnonymousTypeIfNeeded(variableDescriptor, variable, type,
|
||||
trace);
|
||||
}
|
||||
|
||||
+4
-2
@@ -466,8 +466,10 @@ public class CallExpressionResolver {
|
||||
}
|
||||
|
||||
CompileTimeConstant<?> value = ConstantExpressionEvaluator.object$.evaluate(expression, context.trace, context.expectedType);
|
||||
if (value != null) {
|
||||
return BasicExpressionTypingVisitor.createCompileTimeConstantTypeInfo(value, expression, context);
|
||||
if (Boolean.TRUE.equals(context.trace.get(BindingContext.IS_PURE_CONSTANT_EXPRESSION, expression))) {
|
||||
if (value != null) {
|
||||
return BasicExpressionTypingVisitor.createCompileTimeConstantTypeInfo(value, expression, context);
|
||||
}
|
||||
}
|
||||
|
||||
JetTypeInfo typeInfo = JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo());
|
||||
|
||||
+3
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
@@ -125,6 +126,8 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
JetType outType = propertyDescriptor.getType();
|
||||
JetTypeInfo typeInfo = facade.getTypeInfo(initializer, context.replaceExpectedType(outType));
|
||||
dataFlowInfo = typeInfo.getDataFlowInfo();
|
||||
|
||||
EvaluatePackage.recordCompileTimeValueForInitializerIfNeeded(propertyDescriptor, initializer, outType, context.trace);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
val intMaxValue: Int = 0x7fffffff
|
||||
val intMinValue: Int = 1 shl 31
|
||||
|
||||
@@ -18,4 +20,48 @@ val i15: Int = <!INTEGER_OVERFLOW!>intMinValue / -1<!>
|
||||
val l20: Int = <!INTEGER_OVERFLOW!>30 * 24 * 60 * 60 * 1000<!>
|
||||
val l21: Int = intMinValue - intMinValue
|
||||
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
||||
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||
|
||||
fun foo() {
|
||||
val a3: Int = <!INTEGER_OVERFLOW!><!INTEGER_OVERFLOW!>intMaxValue + 1<!> - 10<!>
|
||||
val a4: Int = <!INTEGER_OVERFLOW!>intMaxValue + 1<!> + 10
|
||||
val i2: Int = <!INTEGER_OVERFLOW!>intMaxValue - 1 + 2<!>
|
||||
val i3: Int = <!INTEGER_OVERFLOW!>intMaxValue - intMinValue<!>
|
||||
val i4: Int = <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||
val i5: Int = <!INTEGER_OVERFLOW!>intMinValue - 1<!>
|
||||
val i6: Int = <!INTEGER_OVERFLOW!>intMinValue - intMaxValue<!>
|
||||
val i7: Int = intMinValue + intMaxValue
|
||||
val i8: Int = -intMaxValue
|
||||
val i10: Int = <!INTEGER_OVERFLOW!>intMinValue * -1<!>
|
||||
val i11: Int = <!INTEGER_OVERFLOW!>intMinValue * 2<!>
|
||||
val i12: Int = <!INTEGER_OVERFLOW!>intMaxValue * -2<!>
|
||||
val i13: Int = intMaxValue * -1
|
||||
val i15: Int = <!INTEGER_OVERFLOW!>intMinValue / -1<!>
|
||||
val l20: Int = <!INTEGER_OVERFLOW!>30 * 24 * 60 * 60 * 1000<!>
|
||||
val l21: Int = intMinValue - intMinValue
|
||||
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
||||
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||
}
|
||||
|
||||
class A {
|
||||
fun foo() {
|
||||
val a3: Int = <!INTEGER_OVERFLOW!><!INTEGER_OVERFLOW!>intMaxValue + 1<!> - 10<!>
|
||||
val a4: Int = <!INTEGER_OVERFLOW!>intMaxValue + 1<!> + 10
|
||||
val i2: Int = <!INTEGER_OVERFLOW!>intMaxValue - 1 + 2<!>
|
||||
val i3: Int = <!INTEGER_OVERFLOW!>intMaxValue - intMinValue<!>
|
||||
val i4: Int = <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||
val i5: Int = <!INTEGER_OVERFLOW!>intMinValue - 1<!>
|
||||
val i6: Int = <!INTEGER_OVERFLOW!>intMinValue - intMaxValue<!>
|
||||
val i7: Int = intMinValue + intMaxValue
|
||||
val i8: Int = -intMaxValue
|
||||
val i10: Int = <!INTEGER_OVERFLOW!>intMinValue * -1<!>
|
||||
val i11: Int = <!INTEGER_OVERFLOW!>intMinValue * 2<!>
|
||||
val i12: Int = <!INTEGER_OVERFLOW!>intMaxValue * -2<!>
|
||||
val i13: Int = intMaxValue * -1
|
||||
val i15: Int = <!INTEGER_OVERFLOW!>intMinValue / -1<!>
|
||||
val l20: Int = <!INTEGER_OVERFLOW!>30 * 24 * 60 * 60 * 1000<!>
|
||||
val l21: Int = intMinValue - intMinValue
|
||||
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
|
||||
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
val longMaxValue: Long = 0x7fffffffffffffff
|
||||
val longMinValue: Long = -longMaxValue - 1
|
||||
val intMaxValue: Int = 0x7fffffff
|
||||
@@ -20,4 +22,44 @@ val l13: Long = <!INTEGER_OVERFLOW!>longMinValue * -1<!>
|
||||
val l14: Long = <!INTEGER_OVERFLOW!>longMinValue * 2<!>
|
||||
val l15: Long = <!INTEGER_OVERFLOW!>longMaxValue * -2<!>
|
||||
val l16: Long = intMinValue.toLong() * -1
|
||||
val l19: Long = <!INTEGER_OVERFLOW!>longMinValue / -1<!>
|
||||
val l19: Long = <!INTEGER_OVERFLOW!>longMinValue / -1<!>
|
||||
|
||||
fun foo() {
|
||||
val l1: Long = <!INTEGER_OVERFLOW!>longMaxValue + 1<!>
|
||||
val l2: Long = <!INTEGER_OVERFLOW!>longMaxValue - 1 + 2<!>
|
||||
val l3: Long = <!INTEGER_OVERFLOW!>longMaxValue - longMinValue<!>
|
||||
val l4: Long = <!INTEGER_OVERFLOW!>-longMinValue<!>
|
||||
val l5: Long = <!INTEGER_OVERFLOW!>longMinValue - 1<!>
|
||||
val l6: Long = <!INTEGER_OVERFLOW!>longMinValue - longMaxValue<!>
|
||||
val l7: Long = longMinValue + longMaxValue
|
||||
val l8: Long = -longMaxValue
|
||||
val l10: Long = -intMinValue.toLong()
|
||||
val l11: Long = -1 + intMinValue.toLong()
|
||||
val l12: Long = <!INTEGER_OVERFLOW!>longMinValue * intMinValue<!>
|
||||
val l13: Long = <!INTEGER_OVERFLOW!>longMinValue * -1<!>
|
||||
val l14: Long = <!INTEGER_OVERFLOW!>longMinValue * 2<!>
|
||||
val l15: Long = <!INTEGER_OVERFLOW!>longMaxValue * -2<!>
|
||||
val l16: Long = intMinValue.toLong() * -1
|
||||
val l19: Long = <!INTEGER_OVERFLOW!>longMinValue / -1<!>
|
||||
}
|
||||
|
||||
class A {
|
||||
fun foo() {
|
||||
val l1: Long = <!INTEGER_OVERFLOW!>longMaxValue + 1<!>
|
||||
val l2: Long = <!INTEGER_OVERFLOW!>longMaxValue - 1 + 2<!>
|
||||
val l3: Long = <!INTEGER_OVERFLOW!>longMaxValue - longMinValue<!>
|
||||
val l4: Long = <!INTEGER_OVERFLOW!>-longMinValue<!>
|
||||
val l5: Long = <!INTEGER_OVERFLOW!>longMinValue - 1<!>
|
||||
val l6: Long = <!INTEGER_OVERFLOW!>longMinValue - longMaxValue<!>
|
||||
val l7: Long = longMinValue + longMaxValue
|
||||
val l8: Long = -longMaxValue
|
||||
val l10: Long = -intMinValue.toLong()
|
||||
val l11: Long = -1 + intMinValue.toLong()
|
||||
val l12: Long = <!INTEGER_OVERFLOW!>longMinValue * intMinValue<!>
|
||||
val l13: Long = <!INTEGER_OVERFLOW!>longMinValue * -1<!>
|
||||
val l14: Long = <!INTEGER_OVERFLOW!>longMinValue * 2<!>
|
||||
val l15: Long = <!INTEGER_OVERFLOW!>longMaxValue * -2<!>
|
||||
val l16: Long = intMinValue.toLong() * -1
|
||||
val l19: Long = <!INTEGER_OVERFLOW!>longMinValue / -1<!>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// FILE: a.kt
|
||||
package example.ns
|
||||
val y: Any? = 2
|
||||
|
||||
// FILE: b.kt
|
||||
package example
|
||||
|
||||
val x: Int = if (ns.y is Int) <!DEBUG_INFO_AUTOCAST!>ns.y<!> else 2
|
||||
@@ -0,0 +1,49 @@
|
||||
package test
|
||||
|
||||
// val prop1: 1.toInt()
|
||||
val prop1 = A.a
|
||||
|
||||
// val prop2: 2.toInt()
|
||||
val prop2 = A.a + 1
|
||||
|
||||
class A {
|
||||
// val prop3: 1.toInt()
|
||||
val prop3 = A.a
|
||||
|
||||
// val prop4: 2.toInt()
|
||||
val prop4 = A.a + 1
|
||||
|
||||
class object {
|
||||
val a = 1
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
// val prop5: 1.toInt()
|
||||
val prop5 = A.a
|
||||
|
||||
// val prop6: 2.toInt()
|
||||
val prop6 = A.a + 1
|
||||
|
||||
val b = {
|
||||
// val prop11: 1.toInt()
|
||||
val prop11 = A.a
|
||||
|
||||
// val prop12: 2.toInt()
|
||||
val prop12 = A.a + 1
|
||||
}
|
||||
|
||||
val c = object: Foo {
|
||||
override fun f() {
|
||||
// val prop9: 1.toInt()
|
||||
val prop9 = A.a
|
||||
|
||||
// val prop10: 2.toInt()
|
||||
val prop10 = A.a + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fun f()
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package test
|
||||
|
||||
// val prop1: 1.toInt()
|
||||
val prop1 = A().a
|
||||
|
||||
// val prop2: 2.toInt()
|
||||
val prop2 = A().a + 1
|
||||
|
||||
class A() {
|
||||
val a = 1
|
||||
|
||||
// val prop3: 1.toInt()
|
||||
val prop3 = a
|
||||
|
||||
// val prop4: 2.toInt()
|
||||
val prop4 = a + 1
|
||||
|
||||
fun foo() {
|
||||
// val prop5: 1.toInt()
|
||||
val prop5 = A().a
|
||||
|
||||
// val prop6: 2.toInt()
|
||||
val prop6 = A().a + 1
|
||||
|
||||
val b = {
|
||||
// val prop11: 1.toInt()
|
||||
val prop11 = A().a
|
||||
|
||||
// val prop12: 2.toInt()
|
||||
val prop12 = A().a + 1
|
||||
}
|
||||
|
||||
val c = object: Foo {
|
||||
override fun f() {
|
||||
// val prop9: 1.toInt()
|
||||
val prop9 = A().a
|
||||
|
||||
// val prop10: 2.toInt()
|
||||
val prop10 = A().a + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
// val prop7: 1.toInt()
|
||||
val prop7 = A().a
|
||||
|
||||
// val prop8: 2.toInt()
|
||||
val prop8 = A().a + 1
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fun f()
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package test
|
||||
|
||||
class A() {
|
||||
fun foo() {
|
||||
val a = 1
|
||||
|
||||
// val prop5: 1.toInt()
|
||||
val prop5 = a
|
||||
|
||||
// val prop6: 2.toInt()
|
||||
val prop6 = a + 1
|
||||
|
||||
fun local() {
|
||||
// val prop1: 1.toInt()
|
||||
val prop1 = a
|
||||
|
||||
// val prop2: 2.toInt()
|
||||
val prop2 = a + 1
|
||||
}
|
||||
|
||||
val b = {
|
||||
// val prop3: 1.toInt()
|
||||
val prop3 = a
|
||||
|
||||
// val prop4: 2.toInt()
|
||||
val prop4 = a + 1
|
||||
}
|
||||
|
||||
val c = object: Foo {
|
||||
override fun f() {
|
||||
// val prop9: 1.toInt()
|
||||
val prop9 = a
|
||||
|
||||
// val prop10: 2.toInt()
|
||||
val prop10 = a + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val a = 1
|
||||
|
||||
// val prop7: 1.toInt()
|
||||
val prop7 = a
|
||||
|
||||
// val prop8: 2.toInt()
|
||||
val prop8 = a + 1
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fun f()
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package test
|
||||
|
||||
class A() {
|
||||
fun foo() {
|
||||
var a = 1
|
||||
|
||||
// val prop5: null
|
||||
val prop5 = a
|
||||
|
||||
// val prop6: null
|
||||
val prop6 = a + 1
|
||||
|
||||
fun local() {
|
||||
// val prop1: null
|
||||
val prop1 = a
|
||||
|
||||
// val prop2: null
|
||||
val prop2 = a + 1
|
||||
}
|
||||
|
||||
val b = {
|
||||
// val prop3: null
|
||||
val prop3 = a
|
||||
|
||||
// val prop4: null
|
||||
val prop4 = a + 1
|
||||
}
|
||||
|
||||
val c = object: Foo {
|
||||
override fun f() {
|
||||
// val prop9: null
|
||||
val prop9 = a
|
||||
|
||||
// val prop10: null
|
||||
val prop10 = a + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
var a = 1
|
||||
|
||||
// val prop7: null
|
||||
val prop7 = a
|
||||
|
||||
// val prop8: null
|
||||
val prop8 = a + 1
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fun f()
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package test
|
||||
|
||||
// val prop1: null
|
||||
val prop1 = A().a
|
||||
|
||||
// val prop2: null
|
||||
val prop2 = A().a + 1
|
||||
|
||||
class A() {
|
||||
var a = 1
|
||||
|
||||
// val prop3: null
|
||||
val prop3 = a
|
||||
|
||||
// val prop4: null
|
||||
val prop4 = a + 1
|
||||
|
||||
fun foo() {
|
||||
// val prop5: null
|
||||
val prop5 = A().a
|
||||
|
||||
// val prop6: null
|
||||
val prop6 = A().a + 1
|
||||
|
||||
val b = {
|
||||
// val prop11: null
|
||||
val prop11 = A().a
|
||||
|
||||
// val prop12: null
|
||||
val prop12 = A().a + 1
|
||||
}
|
||||
|
||||
val c = object: Foo {
|
||||
override fun f() {
|
||||
// val prop9: null
|
||||
val prop9 = A().a
|
||||
|
||||
// val prop10: null
|
||||
val prop10 = A().a + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
// val prop7: null
|
||||
val prop7 = A().a
|
||||
|
||||
// val prop8: null
|
||||
val prop8 = A().a + 1
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fun f()
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package test
|
||||
|
||||
val a = 1
|
||||
|
||||
// val prop1: 1.toInt()
|
||||
val prop1 = a
|
||||
|
||||
// val prop2: 2.toInt()
|
||||
val prop2 = a + 1
|
||||
|
||||
class A {
|
||||
// val prop3: 1.toInt()
|
||||
val prop3 = a
|
||||
|
||||
// val prop4: 2.toInt()
|
||||
val prop4 = a + 1
|
||||
|
||||
val b = {
|
||||
// val prop11: 1.toInt()
|
||||
val prop11 = a
|
||||
|
||||
// val prop12: 2.toInt()
|
||||
val prop12 = a + 1
|
||||
}
|
||||
|
||||
val c = object: Foo {
|
||||
override fun f() {
|
||||
// val prop9: 1.toInt()
|
||||
val prop9 = a
|
||||
|
||||
// val prop10: 2.toInt()
|
||||
val prop10 = a + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
// val prop5: 1.toInt()
|
||||
val prop5 = a
|
||||
|
||||
// val prop6: 2.toInt()
|
||||
val prop6 = a + 1
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fun f()
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package test
|
||||
|
||||
var a = 1
|
||||
|
||||
// val prop1: null
|
||||
val prop1 = a
|
||||
|
||||
// val prop2: null
|
||||
val prop2 = a + 1
|
||||
|
||||
class A {
|
||||
// val prop3: null
|
||||
val prop3 = a
|
||||
|
||||
// val prop4: null
|
||||
val prop4 = a + 1
|
||||
|
||||
val b = {
|
||||
// val prop11: null
|
||||
val prop11 = a
|
||||
|
||||
// val prop12: null
|
||||
val prop12 = a + 1
|
||||
}
|
||||
|
||||
val c = object: Foo {
|
||||
override fun f() {
|
||||
// val prop9: null
|
||||
val prop9 = a
|
||||
|
||||
// val prop10: null
|
||||
val prop10 = a + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
// val prop5: null
|
||||
val prop5 = a
|
||||
|
||||
// val prop6: null
|
||||
val prop6 = a + 1
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fun f()
|
||||
}
|
||||
@@ -2889,6 +2889,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest("compiler/testData/diagnostics/tests/evaluate/parentesized.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("qualifiedExpressions.kt")
|
||||
public void testQualifiedExpressions() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/evaluate/qualifiedExpressions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unaryMinusDepOnExpType.kt")
|
||||
public void testUnaryMinusDepOnExpType() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/evaluate/unaryMinusDepOnExpType.kt");
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.jet.JetTestUtils
|
||||
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
|
||||
|
||||
abstract class AbstractEvaluateExpressionTest: AbstractAnnotationDescriptorResolveTest() {
|
||||
|
||||
@@ -72,7 +73,9 @@ abstract class AbstractEvaluateExpressionTest: AbstractAnnotationDescriptorResol
|
||||
val expected = InTextDirectivesUtils.findStringWithPrefixes(fileText, expectedPropertyPrefix)
|
||||
assertNotNull(expected, "Failed to find expected directive: $expectedPropertyPrefix")
|
||||
|
||||
val property = AbstractAnnotationDescriptorResolveTest.getPropertyDescriptor(packageView, propertyName)
|
||||
val property = AbstractAnnotationDescriptorResolveTest.getPropertyDescriptor(packageView, propertyName, false)
|
||||
?: AbstractAnnotationDescriptorResolveTest.getLocalVarDescriptor(context!!, propertyName)
|
||||
|
||||
val jetProperty = BindingContextUtils.descriptorToDeclaration(context!!, property) as JetProperty
|
||||
|
||||
val testedObject = getValueToTest(jetProperty, context!!)
|
||||
|
||||
@@ -38,6 +38,11 @@ public class EvaluateExpressionTestGenerated extends AbstractEvaluateExpressionT
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/evaluate/constant"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectProperty.kt")
|
||||
public void testClassObjectProperty() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/classObjectProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compareTo.kt")
|
||||
public void testCompareTo() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/compareTo.kt");
|
||||
@@ -58,6 +63,11 @@ public class EvaluateExpressionTestGenerated extends AbstractEvaluateExpressionT
|
||||
doConstantTest("compiler/testData/evaluate/constant/exceptionWhenEvaluate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("finalProperty.kt")
|
||||
public void testFinalProperty() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/finalProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("float.kt")
|
||||
public void testFloat() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/float.kt");
|
||||
@@ -78,11 +88,36 @@ public class EvaluateExpressionTestGenerated extends AbstractEvaluateExpressionT
|
||||
doConstantTest("compiler/testData/evaluate/constant/integers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVal.kt")
|
||||
public void testLocalVal() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/localVal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVar.kt")
|
||||
public void testLocalVar() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/localVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonFinalProperty.kt")
|
||||
public void testNonFinalProperty() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/nonFinalProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("strings.kt")
|
||||
public void testStrings() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/strings.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelVal.kt")
|
||||
public void testTopLevelVal() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/topLevelVal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelVar.kt")
|
||||
public void testTopLevelVar() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/topLevelVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unaryMinusIndepWoExpType.kt")
|
||||
public void testUnaryMinusIndepWoExpType() throws Exception {
|
||||
doConstantTest("compiler/testData/evaluate/constant/unaryMinusIndepWoExpType.kt");
|
||||
|
||||
+25
-6
@@ -20,6 +20,7 @@ package org.jetbrains.jet.resolve.annotation;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
@@ -87,7 +88,7 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
|
||||
FunctionDescriptor topFoo = getFunctionDescriptor(test, "topFoo");
|
||||
checkAnnotationsOnFunction(expectedAnnotation, topFoo);
|
||||
|
||||
PropertyDescriptor topProp = getPropertyDescriptor(test, "topProp");
|
||||
PropertyDescriptor topProp = getPropertyDescriptor(test, "topProp", true);
|
||||
checkAnnotationsOnProperty(expectedAnnotation, topProp);
|
||||
|
||||
checkDescriptor(expectedAnnotation, getClassDescriptor(test, "MyObject"));
|
||||
@@ -100,7 +101,7 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
|
||||
checkDescriptor(expectedAnnotation, getLocalClassDescriptor("LocalClass"));
|
||||
checkDescriptor(expectedAnnotation, getLocalObjectDescriptor("LocalObject"));
|
||||
checkDescriptor(expectedAnnotation, getLocalFunDescriptor("localFun"));
|
||||
checkDescriptor(expectedAnnotation, getLocalVarDescriptor("localVar"));
|
||||
checkDescriptor(expectedAnnotation, getLocalVarDescriptor(context, "localVar"));
|
||||
}
|
||||
|
||||
private static void checkAnnotationsOnProperty(String expectedAnnotation, PropertyDescriptor prop) {
|
||||
@@ -134,12 +135,30 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
|
||||
return functions.iterator().next();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static PropertyDescriptor getPropertyDescriptor(@NotNull PackageViewDescriptor packageView, @NotNull String name) {
|
||||
@Nullable
|
||||
protected static PropertyDescriptor getPropertyDescriptor(@NotNull PackageViewDescriptor packageView, @NotNull String name, boolean failOnMissing) {
|
||||
Name propertyName = Name.identifier(name);
|
||||
JetScope memberScope = packageView.getMemberScope();
|
||||
Collection<VariableDescriptor> properties = memberScope.getProperties(propertyName);
|
||||
assert properties.size() == 1 : "Failed to find property " + propertyName + " in class " + packageView.getName();
|
||||
if (properties.isEmpty()) {
|
||||
for (DeclarationDescriptor descriptor : memberScope.getAllDescriptors()) {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
Collection<VariableDescriptor> classProperties =
|
||||
((ClassDescriptor) descriptor).getMemberScope(Collections.<TypeProjection>emptyList())
|
||||
.getProperties(propertyName);
|
||||
if (!classProperties.isEmpty()) {
|
||||
properties = classProperties;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (failOnMissing) {
|
||||
assert properties.size() == 1 : "Failed to find property " + propertyName + " in class " + packageView.getName();
|
||||
}
|
||||
else if (properties.size() != 1) {
|
||||
return null;
|
||||
}
|
||||
return (PropertyDescriptor) properties.iterator().next();
|
||||
}
|
||||
|
||||
@@ -216,7 +235,7 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private VariableDescriptor getLocalVarDescriptor(@NotNull String name) {
|
||||
protected static VariableDescriptor getLocalVarDescriptor(@NotNull BindingContext context, @NotNull String name) {
|
||||
for (VariableDescriptor descriptor : context.getSliceContents(BindingContext.VARIABLE).values()) {
|
||||
if (descriptor.getName().asString().equals(name)) {
|
||||
return descriptor;
|
||||
|
||||
@@ -24,11 +24,20 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
public abstract class CompileTimeConstant<T> {
|
||||
protected final T value;
|
||||
private boolean canBeUsedInAnnotations = true;
|
||||
|
||||
protected CompileTimeConstant(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean canBeUsedInAnnotations() {
|
||||
return canBeUsedInAnnotations;
|
||||
}
|
||||
|
||||
public void setCanBeUsedInAnnotations(boolean canBeUsedInAnnotations) {
|
||||
this.canBeUsedInAnnotations = canBeUsedInAnnotations;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T getValue() {
|
||||
return value;
|
||||
|
||||
Reference in New Issue
Block a user