Support IntegerValueTypeConstant in java backend

This commit is contained in:
Natalia Ukhorskaya
2013-12-02 15:05:51 +04:00
parent f329e245ad
commit cbcca6c08e
6 changed files with 82 additions and 11 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
import org.jetbrains.jet.lang.psi.JetAnnotationEntry;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetModifierList;
@@ -136,9 +137,9 @@ public abstract class AnnotationCodegen {
return KotlinBuiltIns.getInstance().getVolatileAnnotationClass().equals(classDescriptor);
}
public void generateAnnotationDefaultValue(CompileTimeConstant value) {
public void generateAnnotationDefaultValue(@NotNull CompileTimeConstant value, @NotNull JetType expectedType) {
AnnotationVisitor visitor = visitAnnotation(null, false); // Parameters are unimportant
genCompileTimeValue(null, value, visitor);
genCompileTimeValue(null, value, expectedType, visitor);
visitor.visitEnd();
}
@@ -164,13 +165,14 @@ public abstract class AnnotationCodegen {
for (Map.Entry<ValueParameterDescriptor, CompileTimeConstant<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
ValueParameterDescriptor descriptor = entry.getKey();
String name = descriptor.getName().asString();
genCompileTimeValue(name, entry.getValue(), annotationVisitor);
genCompileTimeValue(name, entry.getValue(), descriptor.getType(), annotationVisitor);
}
}
private void genCompileTimeValue(
@Nullable final String name,
@NotNull CompileTimeConstant<?> value,
@NotNull final JetType expectedType,
@NotNull final AnnotationVisitor annotationVisitor
) {
AnnotationArgumentVisitor argumentVisitor = new AnnotationArgumentVisitor<Void, Void>() {
@@ -230,7 +232,7 @@ public abstract class AnnotationCodegen {
public Void visitArrayValue(ArrayValue value, Void data) {
AnnotationVisitor visitor = annotationVisitor.visitArray(name);
for (CompileTimeConstant<?> argument : value.getValue()) {
genCompileTimeValue(null, argument, visitor);
genCompileTimeValue(null, argument, value.getType(KotlinBuiltIns.getInstance()), visitor);
}
visitor.visitEnd();
return null;
@@ -251,6 +253,16 @@ public abstract class AnnotationCodegen {
return null;
}
@Override
public Void visitNumberTypeValue(NumberValueTypeConstant value, Void data) {
NumberValueTypeConstructor typeConstructor = value.getValue();
Object numberType = EvaluatePackage.getValueForNumberType(typeConstructor, expectedType);
if (numberType != null) {
annotationVisitor.visit(name, numberType);
}
return null;
}
private Void visitSimpleValue(CompileTimeConstant value) {
annotationVisitor.visit(name, value.getValue());
return null;
@@ -42,6 +42,7 @@ import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
@@ -50,6 +51,8 @@ import org.jetbrains.jet.lang.resolve.calls.model.*;
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.NumberValueTypeConstant;
import org.jetbrains.jet.lang.resolve.constants.NumberValueTypeConstructor;
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;
@@ -1232,11 +1235,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitConstantExpression(@NotNull JetConstantExpression expression, StackValue receiver) {
CompileTimeConstant<?> compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression);
CompileTimeConstant<?> compileTimeValue = getCompileTimeConstant(expression, bindingContext);
assert compileTimeValue != null;
return StackValue.constant(compileTimeValue.getValue(), expressionType(expression));
}
@Nullable
public static CompileTimeConstant getCompileTimeConstant(@NotNull JetExpression expression, @NotNull BindingContext bindingContext) {
CompileTimeConstant<?> compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression);
if (compileTimeValue instanceof NumberValueTypeConstant) {
JetType expectedType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
return EvaluatePackage.getCompileTimeConstantForNumberType((NumberValueTypeConstructor) compileTimeValue.getValue(), expectedType);
}
return compileTimeValue;
}
@Override
public StackValue visitStringTemplateExpression(@NotNull JetStringTemplateExpression expression, StackValue receiver) {
StringBuilder constantValue = new StringBuilder("");
@@ -2793,7 +2806,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private boolean isIntZero(JetExpression expr, Type exprType) {
CompileTimeConstant<?> exprValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr);
CompileTimeConstant<?> exprValue = getCompileTimeConstant(expr, bindingContext);
return isIntPrimitive(exprType) && exprValue != null && exprValue.getValue().equals(0);
}
@@ -1726,7 +1726,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
JetExpression initializer = property.getDelegateExpressionOrInitializer();
if (initializer == null) return false;
CompileTimeConstant<?> compileTimeValue = typeMapper.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer);
CompileTimeConstant<?> compileTimeValue = ExpressionCodegen.getCompileTimeConstant(initializer, typeMapper.getBindingContext());
if (compileTimeValue == null) return true;
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) typeMapper.getBindingContext().get(BindingContext.VARIABLE, property);
@@ -121,10 +121,10 @@ public class PropertyCodegen extends GenerationStateAware {
MethodVisitor visitor = v.newMethod(p, ACC_PUBLIC | ACC_ABSTRACT, name, "()" + type.getDescriptor(), null, null);
JetExpression defaultValue = p.getDefaultValue();
if (defaultValue != null) {
CompileTimeConstant<?> constant = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, defaultValue);
CompileTimeConstant<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, state.getBindingContext());
assert constant != null : "Default value for annotation parameter should be compile time value: " + defaultValue.getText();
AnnotationCodegen annotationCodegen = AnnotationCodegen.forAnnotationDefaultValue(visitor, typeMapper);
annotationCodegen.generateAnnotationDefaultValue(constant);
annotationCodegen.generateAnnotationDefaultValue(constant, descriptor.getType());
}
}
@@ -240,7 +240,7 @@ public class PropertyCodegen extends GenerationStateAware {
if (ImplementationBodyCodegen.shouldWriteFieldInitializer(propertyDescriptor, typeMapper)) {
JetExpression initializer = p instanceof JetProperty ? ((JetProperty) p).getInitializer() : null;
if (initializer != null) {
CompileTimeConstant<?> compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, initializer);
CompileTimeConstant<?> compileTimeValue = ExpressionCodegen.getCompileTimeConstant(initializer, bindingContext);
value = compileTimeValue != null ? compileTimeValue.getValue() : null;
}
}
@@ -0,0 +1,32 @@
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
Retention(RetentionPolicy.RUNTIME)
annotation class Ann(
val b1: Byte,
val b2: Short,
val b3: Int,
val b4: Long,
val b5: Double,
val b6: Float
)
val b1: Byte = -1
val b2: Short = -1
val b3: Int = -1
val b4: Long = -1
val b5: Double = -1.0
val b6: Float = -1.0.toFloat()
Ann(b1, b2, b3, b4, b5, b6) class MyClass
fun box(): String {
val annotation = javaClass<MyClass>().getAnnotation(javaClass<Ann>())!!
if (annotation.b1 != b1) return "fail 1"
if (annotation.b2 != b2) return "fail 2"
if (annotation.b3 != b3) return "fail 3"
if (annotation.b4 != b4) return "fail 4"
if (annotation.b5 != b5) return "fail 5"
if (annotation.b6 != b6) return "fail 6"
return "OK"
}
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/boxWithStdlib")
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class})
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class})
public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBoxWithStdlib() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -391,6 +391,19 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
}
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/evaluate")
public static class Evaluate extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInEvaluate() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib/evaluate"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("unaryMinus.kt")
public void testUnaryMinus() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/evaluate/unaryMinus.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/fullJdk")
public static class FullJdk extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInFullJdk() throws Exception {
@@ -975,6 +988,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
suite.addTestSuite(Arrays.class);
suite.addTestSuite(Casts.class);
suite.addTest(DataClasses.innerSuite());
suite.addTestSuite(Evaluate.class);
suite.addTestSuite(FullJdk.class);
suite.addTestSuite(JdkAnnotations.class);
suite.addTest(Ranges.innerSuite());