Psi2ir: ignore unresolved annotations

Note that the test is an exact copy of an existing test
missingDependencyNestedAnnotation, but with -Xuse-ir
This commit is contained in:
Alexander Udalov
2019-06-27 20:27:53 +02:00
parent 9062f4229b
commit 385366384c
12 changed files with 53 additions and 17 deletions

View File

@@ -40,7 +40,7 @@ class AnnotationGenerator(context: GeneratorContext) : IrElementVisitorVoid {
declaration.descriptor.backingField
else declaration.descriptor
annotatedDescriptor?.annotations?.mapTo(declaration.annotations) {
annotatedDescriptor?.annotations?.mapNotNullTo(declaration.annotations) {
constantValueGenerator.generateAnnotationConstructorCall(it)
}
}

View File

@@ -73,7 +73,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
for (ktAnnotationEntry in ktFile.annotationEntries) {
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
irFile.annotations.add(constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor))
irFile.annotations.addIfNotNull(constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor))
}
for (ktDeclaration in ktFile.declarations) {

View File

@@ -48,9 +48,7 @@ abstract class IrLazyDeclarationBase(
}
override val annotations: MutableList<IrConstructorCall> by lazy {
descriptor.annotations.map {
typeTranslator.constantValueGenerator.generateAnnotationConstructorCall(it)
}.toMutableList()
descriptor.annotations.mapNotNull(typeTranslator.constantValueGenerator::generateAnnotationConstructorCall).toMutableList()
}
override var metadata: Nothing?

View File

@@ -7,10 +7,10 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.NotFoundClasses
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.*
@@ -38,7 +38,19 @@ class ConstantValueGenerator(
endOffset: Int,
constantValue: ConstantValue<*>,
varargElementType: KotlinType? = null
): IrExpression {
): IrExpression =
// Assertion is safe here because annotation calls are not allowed in constant initializers
generateConstantOrAnnotationValueAsExpression(startOffset, endOffset, constantValue, varargElementType)!!
/**
* @return null if the constant value is an unresolved annotation
*/
private fun generateConstantOrAnnotationValueAsExpression(
startOffset: Int,
endOffset: Int,
constantValue: ConstantValue<*>,
varargElementType: KotlinType? = null
): IrExpression? {
val constantKtType = constantValue.getType(moduleDescriptor)
val constantType = constantKtType.toIrType()
@@ -103,10 +115,11 @@ class ConstantValueGenerator(
}
}
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor): IrConstructorCall {
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor): IrConstructorCall? {
val annotationType = annotationDescriptor.type
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor as? ClassDescriptor
?: throw AssertionError("No declaration descriptor for annotation $annotationDescriptor")
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor
if (annotationClassDescriptor !is ClassDescriptor) return null
if (annotationClassDescriptor is NotFoundClasses.MockClassDescriptor) return null
assert(DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) {
"Annotation class expected: $annotationClassDescriptor"
@@ -143,4 +156,4 @@ class ConstantValueGenerator(
}
private fun KotlinType.getArrayElementType() = builtIns.getArrayElementType(this)
}
}

View File

@@ -130,9 +130,8 @@ class TypeTranslator(
}
private fun translateTypeAnnotations(annotations: Annotations): List<IrConstructorCall> =
annotations.map(constantValueGenerator::generateAnnotationConstructorCall)
annotations.mapNotNull(constantValueGenerator::generateAnnotationConstructorCall)
private fun translateTypeArguments(arguments: List<TypeProjection>) =
arguments.map {

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
public object SomeObject {

View File

@@ -0,0 +1,6 @@
package a
interface A {
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE_PARAMETER)
annotation class Anno(val value: String)
}

View File

@@ -0,0 +1,9 @@
package b
import a.A
@A.Anno("B")
interface B {
@A.Anno("foo")
fun <@A.Anno("T") T> foo(t: T) = t
}

View File

@@ -0,0 +1,8 @@
package c
import b.B
// There should be _no_ error despite the fact that B and B#foo are annotated with an annotation which cannot be resolved
fun bar(b: B) {
b.foo("")
}

View File

@@ -77,11 +77,11 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> =
DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope)
private fun doTestBrokenLibrary(libraryName: String, vararg pathsToDelete: String) {
private fun doTestBrokenLibrary(libraryName: String, vararg pathsToDelete: String, additionalOptions: List<String> = emptyList()) {
// This function compiles a library, then deletes one class file and attempts to compile a Kotlin source against
// this broken library. The expected result is an error message from the compiler
val library = copyJarFileWithoutEntry(compileLibrary(libraryName), *pathsToDelete)
compileKotlin("source.kt", tmpdir, listOf(library))
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = additionalOptions)
}
private fun doTestKotlinLibraryWithWrongMetadataVersion(
@@ -215,6 +215,10 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestBrokenLibrary("library", "a/A\$Anno.class")
}
fun testMissingDependencyNestedAnnotationIr() {
doTestBrokenLibrary("library", "a/A\$Anno.class", additionalOptions = listOf("-Xuse-ir"))
}
fun testMissingDependencyConflictingLibraries() {
val library1 = copyJarFileWithoutEntry(
compileLibrary("library1"),