fix for KT-48

This commit is contained in:
Alex Tkachman
2011-09-05 13:47:54 +02:00
parent eb82967860
commit a8a438ffd3
6 changed files with 152 additions and 5 deletions
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
import org.objectweb.asm.ClassVisitor;
@@ -413,8 +414,41 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
if (initializer != null) {
CompileTimeConstant<?> compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer);
if(compileTimeValue != null) {
assert compileTimeValue != null;
Object value = compileTimeValue.getValue();
Type type = state.getTypeMapper().mapType(propertyDescriptor.getOutType());
if(JetTypeMapper.isPrimitive(type)) {
if( !propertyDescriptor.getOutType().isNullable() && value instanceof Number) {
if(type == Type.INT_TYPE && ((Number)value).intValue() == 0)
continue;
if(type == Type.BYTE_TYPE && ((Number)value).byteValue() == 0)
continue;
if(type == Type.LONG_TYPE && ((Number)value).longValue() == 0L)
continue;
if(type == Type.SHORT_TYPE && ((Number)value).shortValue() == 0)
continue;
if(type == Type.DOUBLE_TYPE && ((Number)value).doubleValue() == 0d)
continue;
if(type == Type.FLOAT_TYPE && ((Number)value).byteValue() == 0f)
continue;
}
if(type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean)value))
continue;
if(type == Type.CHAR_TYPE && value instanceof Character && ((Character)value) == 0)
continue;
}
else {
if(value == null)
continue;
}
}
iv.load(0, JetTypeMapper.TYPE_OBJECT);
codegen.genToJVMStack(initializer);
Type type = codegen.expressionType(initializer);
if(propertyDescriptor.getOutType().isNullable())
type = state.getTypeMapper().boxType(type);
codegen.gen(initializer, type);
codegen.intermediateValueForProperty(propertyDescriptor, false, false).store(iv);
}
@@ -19,6 +19,8 @@ public interface AnnotationArgumentVisitor<R, D> {
R visitDoubleValue(DoubleValue value, D data);
R visitFloatValue(FloatValue value, D data);
R visitBooleanValue(BooleanValue value, D data);
R visitCharValue(CharValue value, D data);
@@ -0,0 +1,38 @@
package org.jetbrains.jet.lang.resolve.constants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
/**
* @author alex.tkachman
*/
public class FloatValue implements CompileTimeConstant<Float> {
private final float value;
public FloatValue(float value) {
this.value = value;
}
@Override
public Float getValue() {
return value;
}
@NotNull
@Override
public JetType getType(@NotNull JetStandardLibrary standardLibrary) {
return standardLibrary.getFloatType();
}
@Override
public <R, D> R accept(AnnotationArgumentVisitor<R, D> visitor, D data) {
return visitor.visitFloatValue(this, data);
}
@Override
public String toString() {
return value + ".flt";
}
}
@@ -18,10 +18,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.types.inference.ConstraintSystem;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorRenderer;
@@ -35,6 +32,17 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*;
* @author abreslav
*/
public class JetTypeInferrer {
private static final Set<String> numberConversions = new HashSet();
static {
numberConversions.add("dbl");
numberConversions.add("flt");
numberConversions.add("lng");
numberConversions.add("sht");
numberConversions.add("byt");
numberConversions.add("int");
}
private static final JetType FORBIDDEN = new JetType() {
@NotNull
@@ -2156,7 +2164,38 @@ public class JetTypeInferrer {
// TODO : functions as values
JetExpression selectorExpression = expression.getSelectorExpression();
JetExpression receiverExpression = expression.getReceiverExpression();
JetType receiverType = context.services.typeInferrerVisitorWithNamespaces.getType(receiverExpression, new TypeInferenceContext(context.trace, context.scope, false, context.dataFlowInfo, NO_EXPECTED_TYPE, NO_EXPECTED_TYPE));
if(selectorExpression instanceof JetSimpleNameExpression) {
CompileTimeConstant<?> compileTimeConstant = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, receiverExpression);
CompileTimeConstant<?> expressionCompileTimeConstant = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression);
if(expressionCompileTimeConstant == null && compileTimeConstant != null && compileTimeConstant.getValue() instanceof Number) {
Number value = (Number) compileTimeConstant.getValue();
String referencedName = ((JetSimpleNameExpression) selectorExpression).getReferencedName();
if(numberConversions.contains(referencedName)) {
if("dbl".equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new DoubleValue(value.doubleValue()));
}
else if("flt".equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new FloatValue(value.floatValue()));
}
else if("lng".equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new LongValue(value.longValue()));
}
else if("sht".equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ShortValue(value.shortValue()));
}
else if("byt".equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ByteValue(value.byteValue()));
}
else if("byt".equals(referencedName)) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new IntValue(value.intValue()));
}
}
}
}
if (receiverType == null) return null;
// Clean resolution: no autocasts
@@ -0,0 +1,29 @@
class A() {
var xi = 0
var xin : Int? = 0
var xinn : Int? = null
var xl = 0.lng
var xln : Long? = 0.lng
var xlnn : Long? = null
var xb = 0.byt
var xbn : Long? = 0.byt
var xbnn : Long? = null
var xf = 0.flt
var xfn : Float? = 0.flt
var xfnn : Float? = null
var xd = 0.dbl
var xdn : Double? = 0.dbl
var xdnn : Double? = null
var xs = 0.sht
var xsn : Short? = 0.sht
var xsnn : Short? = null
}
fun box() : String {
return "OK"
}
@@ -172,4 +172,9 @@ public class ClassGenTest extends CodegenTestCase {
public void testKt249() throws Exception {
blackBoxFile("regressions/kt249.jet");
}
public void testKt48 () throws Exception {
blackBoxFile("regressions/kt48.jet");
System.out.println(generateToText());
}
}