PSI2IR: ignore enum annotation arguments of error type

Similar to references to error type, this may happen if library A uses
an entity from library B annotated with an annotation from C, but A is
compiled without C on the classpath.
This commit is contained in:
pyos
2019-12-16 16:20:24 +01:00
committed by Dmitry Petrov
parent a9848305a3
commit e54ef3bdb8
6 changed files with 44 additions and 2 deletions
@@ -77,8 +77,8 @@ class ConstantValueGenerator(
startOffset, endOffset, startOffset, endOffset,
constantType, constantType,
arrayElementType.toIrType(), arrayElementType.toIrType(),
constantValue.value.map { constantValue.value.mapNotNull {
generateConstantValueAsExpression(startOffset, endOffset, it, null) generateConstantOrAnnotationValueAsExpression(startOffset, endOffset, it, null)
} }
) )
} }
@@ -90,6 +90,14 @@ class ConstantValueGenerator(
if (enumEntryDescriptor !is ClassDescriptor) { if (enumEntryDescriptor !is ClassDescriptor) {
throw AssertionError("Enum entry $enumEntryDescriptor should be a ClassDescriptor") throw AssertionError("Enum entry $enumEntryDescriptor should be a ClassDescriptor")
} }
if (!DescriptorUtils.isEnumEntry(enumEntryDescriptor)) {
// Error class descriptor for an unresolved entry.
// TODO this `null` may actually reach codegen if the annotation is on an interface member's default implementation,
// as any bridge generated in an implementation of that interface will have a copy of the annotation. See
// `missingEnumReferencedInAnnotationArgumentIr` in `testData/compileKotlinAgainstCustomBinaries`: replace
// `open class B` with `interface B` and watch things break. (`KClassValue` below likely has a similar problem.)
return null
}
IrGetEnumValueImpl( IrGetEnumValueImpl(
startOffset, endOffset, startOffset, endOffset,
constantType, constantType,
@@ -115,6 +123,8 @@ class ConstantValueGenerator(
} }
} }
is ErrorValue -> null
else -> TODO("Unexpected constant value: ${constantValue.javaClass.simpleName} $constantValue") else -> TODO("Unexpected constant value: ${constantValue.javaClass.simpleName} $constantValue")
} }
} }
@@ -0,0 +1,9 @@
package a
enum class E { ENTRY }
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE_PARAMETER)
annotation class Anno(val e: E)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE_PARAMETER)
annotation class Anno2(val e: Array<E>)
@@ -0,0 +1,11 @@
package b
import a.*
@Anno(E.ENTRY)
@Anno2(arrayOf(E.ENTRY))
open class B {
@Anno(E.ENTRY)
@Anno2(arrayOf(E.ENTRY))
fun <@Anno(E.ENTRY) @Anno2(arrayOf(E.ENTRY)) T> foo(t: T) = t
}
@@ -0,0 +1,7 @@
package c
import b.B
class C : B() {
fun bar() = foo("")
}
@@ -172,6 +172,10 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestWithTxt(copyJarFileWithoutEntry(compileLibrary("library"), "test/E.class")) doTestWithTxt(copyJarFileWithoutEntry(compileLibrary("library"), "test/E.class"))
} }
fun testMissingEnumReferencedInAnnotationArgumentIr() {
doTestBrokenLibrary("library", "a/E.class", additionalOptions = listOf("-Xuse-ir"))
}
fun testNoWarningsOnJavaKotlinInheritance() { fun testNoWarningsOnJavaKotlinInheritance() {
// This test checks that there are no PARAMETER_NAME_CHANGED_ON_OVERRIDE or DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES // This test checks that there are no PARAMETER_NAME_CHANGED_ON_OVERRIDE or DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES
// warnings when subclassing in Kotlin from Java binaries (in case when no parameter names are available for Java classes) // warnings when subclassing in Kotlin from Java binaries (in case when no parameter names are available for Java classes)