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:
+1
-1
@@ -40,7 +40,7 @@ class AnnotationGenerator(context: GeneratorContext) : IrElementVisitorVoid {
|
|||||||
declaration.descriptor.backingField
|
declaration.descriptor.backingField
|
||||||
else declaration.descriptor
|
else declaration.descriptor
|
||||||
|
|
||||||
annotatedDescriptor?.annotations?.mapTo(declaration.annotations) {
|
annotatedDescriptor?.annotations?.mapNotNullTo(declaration.annotations) {
|
||||||
constantValueGenerator.generateAnnotationConstructorCall(it)
|
constantValueGenerator.generateAnnotationConstructorCall(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
|
|
||||||
for (ktAnnotationEntry in ktFile.annotationEntries) {
|
for (ktAnnotationEntry in ktFile.annotationEntries) {
|
||||||
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
|
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
|
||||||
irFile.annotations.add(constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
irFile.annotations.addIfNotNull(constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ktDeclaration in ktFile.declarations) {
|
for (ktDeclaration in ktFile.declarations) {
|
||||||
|
|||||||
+1
-3
@@ -48,9 +48,7 @@ abstract class IrLazyDeclarationBase(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val annotations: MutableList<IrConstructorCall> by lazy {
|
override val annotations: MutableList<IrConstructorCall> by lazy {
|
||||||
descriptor.annotations.map {
|
descriptor.annotations.mapNotNull(typeTranslator.constantValueGenerator::generateAnnotationConstructorCall).toMutableList()
|
||||||
typeTranslator.constantValueGenerator.generateAnnotationConstructorCall(it)
|
|
||||||
}.toMutableList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override var metadata: Nothing?
|
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.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
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.IrConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
@@ -38,7 +38,19 @@ class ConstantValueGenerator(
|
|||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
constantValue: ConstantValue<*>,
|
constantValue: ConstantValue<*>,
|
||||||
varargElementType: KotlinType? = null
|
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 constantKtType = constantValue.getType(moduleDescriptor)
|
||||||
val constantType = constantKtType.toIrType()
|
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 annotationType = annotationDescriptor.type
|
||||||
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor as? ClassDescriptor
|
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor
|
||||||
?: throw AssertionError("No declaration descriptor for annotation $annotationDescriptor")
|
if (annotationClassDescriptor !is ClassDescriptor) return null
|
||||||
|
if (annotationClassDescriptor is NotFoundClasses.MockClassDescriptor) return null
|
||||||
|
|
||||||
assert(DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) {
|
assert(DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) {
|
||||||
"Annotation class expected: $annotationClassDescriptor"
|
"Annotation class expected: $annotationClassDescriptor"
|
||||||
@@ -143,4 +156,4 @@ class ConstantValueGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType.getArrayElementType() = builtIns.getArrayElementType(this)
|
private fun KotlinType.getArrayElementType() = builtIns.getArrayElementType(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,9 +130,8 @@ class TypeTranslator(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun translateTypeAnnotations(annotations: Annotations): List<IrConstructorCall> =
|
private fun translateTypeAnnotations(annotations: Annotations): List<IrConstructorCall> =
|
||||||
annotations.map(constantValueGenerator::generateAnnotationConstructorCall)
|
annotations.mapNotNull(constantValueGenerator::generateAnnotationConstructorCall)
|
||||||
|
|
||||||
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
||||||
arguments.map {
|
arguments.map {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
// IGNORE_BACKEND: JS, NATIVE
|
// IGNORE_BACKEND: JS, NATIVE
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
public object SomeObject {
|
public object SomeObject {
|
||||||
|
|||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
interface A {
|
||||||
|
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE_PARAMETER)
|
||||||
|
annotation class Anno(val value: String)
|
||||||
|
}
|
||||||
+9
@@ -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
|
||||||
|
}
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
OK
|
||||||
Vendored
+8
@@ -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("")
|
||||||
|
}
|
||||||
+6
-2
@@ -77,11 +77,11 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
|||||||
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> =
|
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> =
|
||||||
DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope)
|
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 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
|
// this broken library. The expected result is an error message from the compiler
|
||||||
val library = copyJarFileWithoutEntry(compileLibrary(libraryName), *pathsToDelete)
|
val library = copyJarFileWithoutEntry(compileLibrary(libraryName), *pathsToDelete)
|
||||||
compileKotlin("source.kt", tmpdir, listOf(library))
|
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = additionalOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doTestKotlinLibraryWithWrongMetadataVersion(
|
private fun doTestKotlinLibraryWithWrongMetadataVersion(
|
||||||
@@ -215,6 +215,10 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
|||||||
doTestBrokenLibrary("library", "a/A\$Anno.class")
|
doTestBrokenLibrary("library", "a/A\$Anno.class")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testMissingDependencyNestedAnnotationIr() {
|
||||||
|
doTestBrokenLibrary("library", "a/A\$Anno.class", additionalOptions = listOf("-Xuse-ir"))
|
||||||
|
}
|
||||||
|
|
||||||
fun testMissingDependencyConflictingLibraries() {
|
fun testMissingDependencyConflictingLibraries() {
|
||||||
val library1 = copyJarFileWithoutEntry(
|
val library1 = copyJarFileWithoutEntry(
|
||||||
compileLibrary("library1"),
|
compileLibrary("library1"),
|
||||||
|
|||||||
Reference in New Issue
Block a user