Make IntegerValueTypeConstant implements CompileTimeValue<Number>. getValue() method for it is now deprecated - getValue(expectedType) should be used

This commit is contained in:
Natalia Ukhorskaya
2014-01-16 15:33:23 +04:00
parent a71e062504
commit 694db27da0
9 changed files with 98 additions and 74 deletions
@@ -257,11 +257,8 @@ public abstract class AnnotationCodegen {
@Override @Override
public Void visitNumberTypeValue(IntegerValueTypeConstant value, Void data) { public Void visitNumberTypeValue(IntegerValueTypeConstant value, Void data) {
IntegerValueTypeConstructor typeConstructor = value.getValue(); Object numberType = value.getValue(expectedType);
Object numberType = EvaluatePackage.getValueForNumberType(typeConstructor, expectedType); annotationVisitor.visit(name, numberType);
if (numberType != null) {
annotationVisitor.visit(name, numberType);
}
return null; return null;
} }
@@ -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.calls.util.ExpressionAsFunctionDescriptor;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant; 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.AsmTypeConstants;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor; import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor;
@@ -1222,7 +1221,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
CompileTimeConstant<?> compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression); CompileTimeConstant<?> compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression);
if (compileTimeValue instanceof IntegerValueTypeConstant) { if (compileTimeValue instanceof IntegerValueTypeConstant) {
JetType expectedType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); JetType expectedType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
return EvaluatePackage.getCompileTimeConstantForNumberType((IntegerValueTypeConstructor) compileTimeValue.getValue(), expectedType); return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) compileTimeValue, expectedType);
} }
return compileTimeValue; return compileTimeValue;
} }
@@ -386,43 +386,34 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
} }
private fun createOperationArgument(expression: JetExpression, expressionType: JetType, compileTimeType: CompileTimeType<*>): OperationArgument? { private fun createOperationArgument(expression: JetExpression, expressionType: JetType, compileTimeType: CompileTimeType<*>): OperationArgument? {
val evaluationResult = evaluate(expression, expressionType)?.getValue() val evaluatedConstant = evaluate(expression, expressionType)
if (evaluationResult == null) return null if (evaluatedConstant == null) return null
if (evaluationResult is IntegerValueTypeConstructor) { if (evaluatedConstant is IntegerValueTypeConstant) {
val evaluationResultWithNewType = evaluationResult.getValueForNumberType(expressionType) val evaluationResultWithNewType = evaluatedConstant.getValue(expressionType)
if (evaluationResultWithNewType != null) { return OperationArgument(evaluationResultWithNewType, compileTimeType, expression)
return OperationArgument(evaluationResultWithNewType, compileTimeType, expression)
}
} }
val evaluationResult = evaluatedConstant.getValue()
if (evaluationResult == null) return null
return OperationArgument(evaluationResult, compileTimeType, expression) return OperationArgument(evaluationResult, compileTimeType, expression)
} }
fun createCompileTimeConstant(value: Any?, expression: JetExpression, expectedType: JetType?, isPure: Boolean = true): CompileTimeConstant<*>? { fun createCompileTimeConstant(value: Any?, expression: JetExpression, expectedType: JetType?, isPure: Boolean = true): CompileTimeConstant<*>? {
if (isPure) { 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) trace.record(BindingContext.IS_PURE_CONSTANT_EXPRESSION, expression, true)
return compileTimeConstant return compileTimeConstant
} }
val compileTimeConstant = createUnconvertibleCompileTimeConstant(value) val compileTimeConstant = createCompileTimeConstant(value)
return compileTimeConstant return compileTimeConstant
} }
} }
public fun IntegerValueTypeConstructor.getValueForNumberType(expectedType: JetType): Any? { public fun IntegerValueTypeConstant.createCompileTimeConstantWithType(expectedType: JetType): CompileTimeConstant<*>?
val valueWithNewType = this.getCompileTimeConstantForNumberType(expectedType) = createCompileTimeConstant(getValue(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)
}
private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L') private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L')
@@ -515,25 +506,9 @@ private fun createCompileTimeConstantForCompareTo(result: Any?, operationReferen
return null 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? { private fun createStringConstant(value: CompileTimeConstant<*>?): StringValue? {
return when (value) { return when (value) {
null -> null is IntegerValueTypeConstant -> StringValue(value.getValue(TypeUtils.NO_EXPECTED_TYPE).toString())
is IntegerValueTypeConstant -> createStringConstant(value.getValue()!!.getCompileTimeConstantForNumberType(TypeUtils.NO_EXPECTED_TYPE))
is StringValue -> value is StringValue -> value
is IntValue, is ByteValue, is ShortValue, is LongValue, is IntValue, is ByteValue, is ShortValue, is LongValue,
is CharValue, 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) { return when(value) {
null -> null is Byte, is Short, is Int, is Long -> {
is Byte, is Short, is Int, is Long-> getIntegerValue((value as Number).toLong(), expectedType ?: TypeUtils.NO_EXPECTED_TYPE) 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 Char -> CharValue(value)
is Float -> FloatValue(value) is Float -> FloatValue(value)
is Double -> DoubleValue(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 fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int || value is Long
private fun getIntegerValue(value: Long, expectedType: JetType): CompileTimeConstant<*>? { private fun getIntegerValue(value: Long, expectedType: JetType): CompileTimeConstant<*>? {
@@ -249,8 +249,7 @@ public class AnnotationResolver {
if (argumentExpression != null) { if (argumentExpression != null) {
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.object$.evaluate(argumentExpression, trace, expectedType); CompileTimeConstant<?> constant = ConstantExpressionEvaluator.object$.evaluate(argumentExpression, trace, expectedType);
if (constant instanceof IntegerValueTypeConstant) { if (constant instanceof IntegerValueTypeConstant) {
IntegerValueTypeConstructor typeConstructor = ((IntegerValueTypeConstant) constant).getValue(); JetType defaultType = ((IntegerValueTypeConstant) constant).getType(expectedType);
JetType defaultType = getPrimitiveNumberType(typeConstructor, expectedType);
ArgumentTypeResolver.updateNumberType(defaultType, argumentExpression, trace); ArgumentTypeResolver.updateNumberType(defaultType, argumentExpression, trace);
} }
if (constant != null) { if (constant != null) {
@@ -713,7 +713,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
) { ) {
JetType expressionType = value.getType(KotlinBuiltIns.getInstance()); JetType expressionType = value.getType(KotlinBuiltIns.getInstance());
if (value instanceof IntegerValueTypeConstant && context.contextDependency == INDEPENDENT) { 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); ArgumentTypeResolver.updateNumberType(expressionType, expression, context.trace);
} }
@@ -171,7 +171,7 @@ public class DataFlowUtils {
if (expression instanceof JetConstantExpression) { if (expression instanceof JetConstantExpression) {
CompileTimeConstant<?> value = ConstantExpressionEvaluator.object$.evaluate(expression, trace, expectedType); CompileTimeConstant<?> value = ConstantExpressionEvaluator.object$.evaluate(expression, trace, expectedType);
if (value instanceof IntegerValueTypeConstant) { 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); new CompileTimeConstantChecker(trace, true).checkConstantExpressionType(value, (JetConstantExpression) expression, expectedType);
return expressionType; return expressionType;
@@ -17,29 +17,63 @@
package org.jetbrains.jet.lang.resolve.constants; package org.jetbrains.jet.lang.resolve.constants;
import org.jetbrains.annotations.NotNull; 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.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.*;
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.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import java.util.Collections; import java.util.Collections;
public class IntegerValueTypeConstant extends CompileTimeConstant<IntegerValueTypeConstructor> { public class IntegerValueTypeConstant extends CompileTimeConstant<Number> {
public IntegerValueTypeConstant(long value) { private final IntegerValueTypeConstructor typeConstructor;
super(new IntegerValueTypeConstructor(value));
public IntegerValueTypeConstant(@NotNull Number value) {
super(value);
this.typeConstructor = new IntegerValueTypeConstructor(value.longValue());
} }
@NotNull @NotNull
@Override @Override
public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) { public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) {
return new JetTypeImpl( return new JetTypeImpl(
Annotations.EMPTY, getValue(), Annotations.EMPTY, typeConstructor,
false, Collections.<TypeProjection>emptyList(), false, Collections.<TypeProjection>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 @Override
@@ -49,6 +83,6 @@ public class IntegerValueTypeConstant extends CompileTimeConstant<IntegerValueTy
@Override @Override
public String toString() { public String toString() {
return value.toString(); return typeConstructor.toString();
} }
} }
@@ -24,14 +24,14 @@ import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstructor; import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.jet.lang.resolve.constants.NullValue; import org.jetbrains.jet.lang.resolve.constants.NullValue;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
@@ -85,14 +85,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
return JsLiteral.NULL; return JsLiteral.NULL;
} }
Object value = compileTimeValue.getValue(); Object value = getCompileTimeValue(context.bindingContext(), expression, compileTimeValue);
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();
}
if (value instanceof Integer || value instanceof Short || value instanceof Byte) { if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
return context.program().getNumberLiteral(((Number) value).intValue()); return context.program().getNumberLiteral(((Number) value).intValue());
} }
@@ -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.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; 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.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import java.util.List; import java.util.List;
@@ -187,7 +189,19 @@ public final class BindingUtils {
public static Object getCompileTimeValue(@NotNull BindingContext context, @NotNull JetExpression expression) { public static Object getCompileTimeValue(@NotNull BindingContext context, @NotNull JetExpression expression) {
CompileTimeConstant<?> compileTimeValue = context.get(BindingContext.COMPILE_TIME_VALUE, expression); CompileTimeConstant<?> compileTimeValue = context.get(BindingContext.COMPILE_TIME_VALUE, expression);
if (compileTimeValue != null) { 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; return null;
} }