Fix UOE when using Java annotation with infinity/NaN as default value
The root problem is the fact that ConstantExpressionEvaluator returns
null for values such as infinity and NaN loaded from cls psi (see
IDEA-207252). This commit simply reverts a part of 8ab9226805 where we
started to compute default values more often than needed. In
LazyJavaClassMemberScope, we only need to check whether or not there
_is_ a default value, not compute its value.
#KT-29792 Fixed
This commit is contained in:
+6
@@ -69,6 +69,12 @@ public class JavaMethodImpl extends JavaMemberImpl<PsiMethod> implements JavaMet
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getHasAnnotationParameterDefaultValue() {
|
||||||
|
PsiMethod psiMethod = getPsi();
|
||||||
|
return psiMethod instanceof PsiAnnotationMethod && ((PsiAnnotationMethod) psiMethod).getDefaultValue() != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JavaType getReturnType() {
|
public JavaType getReturnType() {
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: -JVM.USE_FAST_CLASS_FILES_READING
|
||||||
|
// FILE: J.java
|
||||||
|
|
||||||
|
public @interface J {
|
||||||
|
double minusInf() default Double.NEGATIVE_INFINITY;
|
||||||
|
double plusInf() default Double.POSITIVE_INFINITY;
|
||||||
|
double nan() default Double.NaN;
|
||||||
|
double divisionByZero() default 1.0 / 0.0;
|
||||||
|
|
||||||
|
float minusInfFloat() default Float.NEGATIVE_INFINITY;
|
||||||
|
float plusInfFloat() default Float.POSITIVE_INFINITY;
|
||||||
|
float nanFloat() default Float.NaN;
|
||||||
|
float divisionByZeroFloat() default 1.0f / 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
// Only check that the compiler loads the class for J
|
||||||
|
J::class
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
-1
@@ -33,7 +33,11 @@ abstract class AbstractBlackBoxAgainstJavaCodegenTest : AbstractBlackBoxCodegenT
|
|||||||
|
|
||||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||||
configuration.addJvmClasspathRoot(javaClassesOutputDirectory)
|
configuration.addJvmClasspathRoot(javaClassesOutputDirectory)
|
||||||
configuration.put(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING, true)
|
|
||||||
|
if (configuration.get(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING) == null) {
|
||||||
|
// By default (unless disabled in the test with a directive), use the fast class reading mode
|
||||||
|
configuration.put(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun extractConfigurationKind(files: MutableList<TestFile>): ConfigurationKind {
|
override fun extractConfigurationKind(files: MutableList<TestFile>): ConfigurationKind {
|
||||||
|
|||||||
+5
@@ -41,6 +41,11 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/annotations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/annotations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("divisionByZeroInJava.kt")
|
||||||
|
public void testDivisionByZeroInJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxAgainstJava/annotations/divisionByZeroInJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaAnnotationArrayValueDefault.kt")
|
@TestMetadata("javaAnnotationArrayValueDefault.kt")
|
||||||
public void testJavaAnnotationArrayValueDefault() throws Exception {
|
public void testJavaAnnotationArrayValueDefault() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxAgainstJava/annotations/javaAnnotationArrayValueDefault.kt");
|
runTest("compiler/testData/codegen/boxAgainstJava/annotations/javaAnnotationArrayValueDefault.kt");
|
||||||
|
|||||||
Generated
+5
@@ -41,6 +41,11 @@ public class IrBlackBoxAgainstJavaCodegenTestGenerated extends AbstractIrBlackBo
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/annotations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/annotations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("divisionByZeroInJava.kt")
|
||||||
|
public void testDivisionByZeroInJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxAgainstJava/annotations/divisionByZeroInJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaAnnotationArrayValueDefault.kt")
|
@TestMetadata("javaAnnotationArrayValueDefault.kt")
|
||||||
public void testJavaAnnotationArrayValueDefault() throws Exception {
|
public void testJavaAnnotationArrayValueDefault() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxAgainstJava/annotations/javaAnnotationArrayValueDefault.kt");
|
runTest("compiler/testData/codegen/boxAgainstJava/annotations/javaAnnotationArrayValueDefault.kt");
|
||||||
|
|||||||
+1
-1
@@ -675,7 +675,7 @@ class LazyJavaClassMemberScope(
|
|||||||
method.name,
|
method.name,
|
||||||
// Parameters of annotation constructors in Java are never nullable
|
// Parameters of annotation constructors in Java are never nullable
|
||||||
TypeUtils.makeNotNullable(returnType),
|
TypeUtils.makeNotNullable(returnType),
|
||||||
method.annotationParameterDefaultValue != null,
|
method.hasAnnotationParameterDefaultValue,
|
||||||
/* isCrossinline = */ false,
|
/* isCrossinline = */ false,
|
||||||
/* isNoinline = */ false,
|
/* isNoinline = */ false,
|
||||||
// Nulls are not allowed in annotation arguments in Java
|
// Nulls are not allowed in annotation arguments in Java
|
||||||
|
|||||||
@@ -105,7 +105,12 @@ interface JavaMethod : JavaMember, JavaTypeParameterListOwner {
|
|||||||
val valueParameters: List<JavaValueParameter>
|
val valueParameters: List<JavaValueParameter>
|
||||||
val returnType: JavaType
|
val returnType: JavaType
|
||||||
|
|
||||||
|
// WARNING: computing the default value may lead to an exception in the compiler because of IDEA-207252.
|
||||||
|
// If you only need to check default value presence, use `hasAnnotationParameterDefaultValue` instead.
|
||||||
val annotationParameterDefaultValue: JavaAnnotationArgument?
|
val annotationParameterDefaultValue: JavaAnnotationArgument?
|
||||||
|
|
||||||
|
val hasAnnotationParameterDefaultValue: Boolean
|
||||||
|
get() = annotationParameterDefaultValue != null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JavaField : JavaMember {
|
interface JavaField : JavaMember {
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import dependency.*
|
||||||
|
|
||||||
|
@<caret>J
|
||||||
|
fun test() {}
|
||||||
|
|
||||||
|
// REF: (dependency).J
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package dependency;
|
||||||
|
|
||||||
|
public @interface J {
|
||||||
|
double minusInf() default Double.NEGATIVE_INFINITY;
|
||||||
|
double plusInf() default Double.POSITIVE_INFINITY;
|
||||||
|
double nan() default Double.NaN;
|
||||||
|
double divisionByZero() default 1.0 / 0.0;
|
||||||
|
|
||||||
|
float minusInfFloat() default Float.NEGATIVE_INFINITY;
|
||||||
|
float plusInfFloat() default Float.POSITIVE_INFINITY;
|
||||||
|
float nanFloat() default Float.NaN;
|
||||||
|
float divisionByZeroFloat() default 1.0f / 0.0f;
|
||||||
|
}
|
||||||
+5
@@ -44,6 +44,11 @@ public class ReferenceResolveWithLibTestGenerated extends AbstractReferenceResol
|
|||||||
runTest("idea/testData/resolve/referenceWithLib/fakeOverride2.kt");
|
runTest("idea/testData/resolve/referenceWithLib/fakeOverride2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("infinityAndNanInJavaAnnotation.kt")
|
||||||
|
public void testInfinityAndNanInJavaAnnotation() throws Exception {
|
||||||
|
runTest("idea/testData/resolve/referenceWithLib/infinityAndNanInJavaAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("innerClassFromLib.kt")
|
@TestMetadata("innerClassFromLib.kt")
|
||||||
public void testInnerClassFromLib() throws Exception {
|
public void testInnerClassFromLib() throws Exception {
|
||||||
runTest("idea/testData/resolve/referenceWithLib/innerClassFromLib.kt");
|
runTest("idea/testData/resolve/referenceWithLib/innerClassFromLib.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user