diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index ec8609d9fea..e302df6a9e1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -257,11 +257,8 @@ public abstract class AnnotationCodegen { @Override public Void visitNumberTypeValue(IntegerValueTypeConstant value, Void data) { - IntegerValueTypeConstructor typeConstructor = value.getValue(); - Object numberType = EvaluatePackage.getValueForNumberType(typeConstructor, expectedType); - if (numberType != null) { - annotationVisitor.visit(name, numberType); - } + Object numberType = value.getValue(expectedType); + annotationVisitor.visit(name, numberType); return null; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f5e81887291..a01cbfbbd70 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -52,7 +52,6 @@ import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant; -import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstructor; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor; @@ -1222,7 +1221,7 @@ public class ExpressionCodegen extends JetVisitor implem CompileTimeConstant compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression); if (compileTimeValue instanceof IntegerValueTypeConstant) { JetType expectedType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); - return EvaluatePackage.getCompileTimeConstantForNumberType((IntegerValueTypeConstructor) compileTimeValue.getValue(), expectedType); + return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) compileTimeValue, expectedType); } return compileTimeValue; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt index 19dde3a8dc2..edb36056cd9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt @@ -386,43 +386,34 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet } private fun createOperationArgument(expression: JetExpression, expressionType: JetType, compileTimeType: CompileTimeType<*>): OperationArgument? { - val evaluationResult = evaluate(expression, expressionType)?.getValue() - if (evaluationResult == null) return null + val evaluatedConstant = evaluate(expression, expressionType) + if (evaluatedConstant == null) return null - if (evaluationResult is IntegerValueTypeConstructor) { - val evaluationResultWithNewType = evaluationResult.getValueForNumberType(expressionType) - if (evaluationResultWithNewType != null) { - return OperationArgument(evaluationResultWithNewType, compileTimeType, expression) - } + if (evaluatedConstant is IntegerValueTypeConstant) { + val evaluationResultWithNewType = evaluatedConstant.getValue(expressionType) + return OperationArgument(evaluationResultWithNewType, compileTimeType, expression) } + val evaluationResult = evaluatedConstant.getValue() + if (evaluationResult == null) return null + return OperationArgument(evaluationResult, compileTimeType, expression) } fun createCompileTimeConstant(value: Any?, expression: JetExpression, expectedType: JetType?, isPure: Boolean = true): CompileTimeConstant<*>? { if (isPure) { - val compileTimeConstant = createConvertibleCompileTimeConstant(value, expectedType) + val compileTimeConstant = createCompileTimeConstant(value, expectedType ?: TypeUtils.NO_EXPECTED_TYPE) trace.record(BindingContext.IS_PURE_CONSTANT_EXPRESSION, expression, true) return compileTimeConstant } - val compileTimeConstant = createUnconvertibleCompileTimeConstant(value) + val compileTimeConstant = createCompileTimeConstant(value) return compileTimeConstant } } -public fun IntegerValueTypeConstructor.getValueForNumberType(expectedType: JetType): Any? { - val valueWithNewType = this.getCompileTimeConstantForNumberType(expectedType) - if (valueWithNewType != null) { - return valueWithNewType.getValue() - } - return null -} - -public fun IntegerValueTypeConstructor.getCompileTimeConstantForNumberType(expectedType: JetType): CompileTimeConstant<*>? { - val defaultType = TypeUtils.getPrimitiveNumberType(this, expectedType) - return createConvertibleCompileTimeConstant(this.getValue(), defaultType) -} +public fun IntegerValueTypeConstant.createCompileTimeConstantWithType(expectedType: JetType): CompileTimeConstant<*>? + = createCompileTimeConstant(getValue(expectedType)) private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L') @@ -515,25 +506,9 @@ private fun createCompileTimeConstantForCompareTo(result: Any?, operationReferen return null } -private fun createUnconvertibleCompileTimeConstant(value: Any?): CompileTimeConstant<*>? { - return when(value) { - null -> null - is Byte -> ByteValue(value) - is Short -> ShortValue(value) - is Int -> IntValue(value) - is Long -> LongValue(value) - is Char -> CharValue(value) - is Float -> FloatValue(value) - is Double -> DoubleValue(value) - is Boolean -> BooleanValue.valueOf(value) - else -> null - } -} - private fun createStringConstant(value: CompileTimeConstant<*>?): StringValue? { return when (value) { - null -> null - is IntegerValueTypeConstant -> createStringConstant(value.getValue()!!.getCompileTimeConstantForNumberType(TypeUtils.NO_EXPECTED_TYPE)) + is IntegerValueTypeConstant -> StringValue(value.getValue(TypeUtils.NO_EXPECTED_TYPE).toString()) is StringValue -> value is IntValue, is ByteValue, is ShortValue, is LongValue, is CharValue, @@ -543,10 +518,22 @@ private fun createStringConstant(value: CompileTimeConstant<*>?): StringValue? { } } -private fun createConvertibleCompileTimeConstant(value: Any?, expectedType: JetType?): CompileTimeConstant<*>? { +private fun createCompileTimeConstant(value: Any?, expectedType: JetType? = null): CompileTimeConstant<*>? { return when(value) { - null -> null - is Byte, is Short, is Int, is Long-> getIntegerValue((value as Number).toLong(), expectedType ?: TypeUtils.NO_EXPECTED_TYPE) + 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) + } + } is Char -> CharValue(value) is Float -> FloatValue(value) is Double -> DoubleValue(value) @@ -556,6 +543,7 @@ private fun createConvertibleCompileTimeConstant(value: Any?, expectedType: JetT } } + fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int || value is Long private fun getIntegerValue(value: Long, expectedType: JetType): CompileTimeConstant<*>? { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index 56630390509..fff8e64b7e6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -249,8 +249,7 @@ public class AnnotationResolver { if (argumentExpression != null) { CompileTimeConstant constant = ConstantExpressionEvaluator.object$.evaluate(argumentExpression, trace, expectedType); if (constant instanceof IntegerValueTypeConstant) { - IntegerValueTypeConstructor typeConstructor = ((IntegerValueTypeConstant) constant).getValue(); - JetType defaultType = getPrimitiveNumberType(typeConstructor, expectedType); + JetType defaultType = ((IntegerValueTypeConstant) constant).getType(expectedType); ArgumentTypeResolver.updateNumberType(defaultType, argumentExpression, trace); } if (constant != null) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index c3c9dab4b03..f3cefe7b09e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -713,7 +713,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ) { JetType expressionType = value.getType(KotlinBuiltIns.getInstance()); if (value instanceof IntegerValueTypeConstant && context.contextDependency == INDEPENDENT) { - expressionType = getPrimitiveNumberType(((IntegerValueTypeConstant) value).getValue(), context.expectedType); + expressionType = ((IntegerValueTypeConstant) value).getType(context.expectedType); ArgumentTypeResolver.updateNumberType(expressionType, expression, context.trace); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java index 5a05a6ccd92..270f4d1cba7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java @@ -171,7 +171,7 @@ public class DataFlowUtils { if (expression instanceof JetConstantExpression) { CompileTimeConstant value = ConstantExpressionEvaluator.object$.evaluate(expression, trace, expectedType); if (value instanceof IntegerValueTypeConstant) { - value = EvaluatePackage.getCompileTimeConstantForNumberType(((IntegerValueTypeConstant) value).getValue(), expectedType); + value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, expectedType); } new CompileTimeConstantChecker(trace, true).checkConstantExpressionType(value, (JetConstantExpression) expression, expectedType); return expressionType; diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/IntegerValueTypeConstant.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/IntegerValueTypeConstant.java index 4355203267f..2e6718e9118 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/IntegerValueTypeConstant.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/IntegerValueTypeConstant.java @@ -17,29 +17,63 @@ package org.jetbrains.jet.lang.resolve.constants; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor; -import org.jetbrains.jet.lang.descriptors.annotations.Annotations; -import org.jetbrains.jet.lang.types.ErrorUtils; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.JetTypeImpl; -import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import java.util.Collections; -public class IntegerValueTypeConstant extends CompileTimeConstant { +public class IntegerValueTypeConstant extends CompileTimeConstant { - public IntegerValueTypeConstant(long value) { - super(new IntegerValueTypeConstructor(value)); + private final IntegerValueTypeConstructor typeConstructor; + + public IntegerValueTypeConstant(@NotNull Number value) { + super(value); + this.typeConstructor = new IntegerValueTypeConstructor(value.longValue()); } @NotNull @Override public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) { return new JetTypeImpl( - Annotations.EMPTY, getValue(), + Annotations.EMPTY, typeConstructor, false, Collections.emptyList(), - ErrorUtils.createErrorScope("Scope for number value type (" + getValue().toString() + ")", true)); + ErrorUtils.createErrorScope("Scope for number value type (" + typeConstructor.toString() + ")", true)); + } + + @Nullable + @Override + @Deprecated + public Number getValue() { + throw new UnsupportedOperationException("Use IntegerValueTypeConstant.getValue(expectedType) instead"); + } + + @NotNull + public JetType getType(@NotNull JetType expectedType) { + return TypeUtils.getPrimitiveNumberType(typeConstructor, expectedType); + } + + @NotNull + public Number getValue(@NotNull JetType expectedType) { + Number numberValue = typeConstructor.getValue(); + KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); + + JetType valueType = getType(expectedType); + if (valueType.equals(builtIns.getIntType())) { + return numberValue.intValue(); + } + else if (valueType.equals(builtIns.getByteType())) { + return numberValue.byteValue(); + } + else if (valueType.equals(builtIns.getShortType())) { + return numberValue.shortValue(); + } + else { + return numberValue.longValue(); + } } @Override @@ -49,6 +83,6 @@ public class IntegerValueTypeConstant extends CompileTimeConstant { return JsLiteral.NULL; } - Object value = compileTimeValue.getValue(); - if (value instanceof IntegerValueTypeConstructor) { - JetType expectedType = context.bindingContext().get(BindingContext.EXPRESSION_TYPE, expression); - CompileTimeConstant newConstant = - EvaluatePackage.getCompileTimeConstantForNumberType((IntegerValueTypeConstructor) value, expectedType); - assert newConstant != null: "IntegerValueTypeConstant should always have notnull value " + compileTimeValue; - value = newConstant.getValue(); - } + Object value = getCompileTimeValue(context.bindingContext(), expression, compileTimeValue); if (value instanceof Integer || value instanceof Short || value instanceof Byte) { return context.program().getNumberLiteral(((Number) value).intValue()); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index 66fc045267a..5f7819fa696 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -27,7 +27,9 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; +import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; import java.util.List; @@ -187,7 +189,19 @@ public final class BindingUtils { public static Object getCompileTimeValue(@NotNull BindingContext context, @NotNull JetExpression expression) { CompileTimeConstant compileTimeValue = context.get(BindingContext.COMPILE_TIME_VALUE, expression); if (compileTimeValue != null) { - return compileTimeValue.getValue(); + return getCompileTimeValue(context, expression, compileTimeValue); + } + return null; + } + + @Nullable + public static Object getCompileTimeValue(@NotNull BindingContext context, @NotNull JetExpression expression, @NotNull CompileTimeConstant constant) { + if (constant != null) { + if (constant instanceof IntegerValueTypeConstant) { + JetType expectedType = context.get(BindingContext.EXPRESSION_TYPE, expression); + return ((IntegerValueTypeConstant) constant).getValue(expectedType == null ? TypeUtils.NO_EXPECTED_TYPE : expectedType); + } + return constant.getValue(); } return null; }