mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-01 15:51:52 +00:00
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:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
public object SomeObject {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package a
|
||||
|
||||
interface A {
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE_PARAMETER)
|
||||
annotation class Anno(val value: String)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -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("")
|
||||
}
|
||||
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user