diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index 1cf1039e048..803ada27acc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -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> 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() { @@ -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; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 4baf77a8307..96405ff81d9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -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 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 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); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 25ae7010291..40447f75aee 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -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); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 96c2d21ee49..cf2d29e50c7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -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; } } diff --git a/compiler/testData/codegen/boxWithStdlib/evaluate/unaryMinus.kt b/compiler/testData/codegen/boxWithStdlib/evaluate/unaryMinus.kt new file mode 100644 index 00000000000..663e88c7276 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/evaluate/unaryMinus.kt @@ -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().getAnnotation(javaClass())!! + 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" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 0ca5a4b9b92..0bbb5ad1190 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -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());