Fix loading default Java annotation values in actual typealias from binary classes
#KT-22704 Fixed
This commit is contained in:
+13
-6
@@ -16,14 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java.structure.impl;
|
||||
|
||||
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||
import com.intellij.psi.PsiAnnotationMethod;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaMethod;
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaType;
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter;
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.load.java.structure.*;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
|
||||
import java.util.List;
|
||||
@@ -57,9 +56,17 @@ public class JavaMethodImpl extends JavaMemberImpl<PsiMethod> implements JavaMet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getHasAnnotationParameterDefaultValue() {
|
||||
@Nullable
|
||||
public JavaAnnotationArgument getAnnotationParameterDefaultValue() {
|
||||
PsiMethod psiMethod = getPsi();
|
||||
return psiMethod instanceof PsiAnnotationMethod && ((PsiAnnotationMethod) psiMethod).getDefaultValue() != null;
|
||||
if (psiMethod instanceof PsiAnnotationMethod) {
|
||||
PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod) psiMethod).getDefaultValue();
|
||||
if (defaultValue != null) {
|
||||
return JavaAnnotationArgumentImpl.Factory.create(defaultValue, null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+18
-13
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import java.lang.reflect.Array
|
||||
@@ -37,11 +36,10 @@ internal class AnnotationsAndParameterCollectorMethodVisitor(
|
||||
private var visibleAnnotableParameterCount = parametersCountInMethodDesc
|
||||
private var invisibleAnnotableParameterCount = parametersCountInMethodDesc
|
||||
|
||||
override fun visitAnnotationDefault(): AnnotationVisitor? {
|
||||
member.safeAs<BinaryJavaMethod>()?.hasAnnotationParameterDefaultValue = true
|
||||
// We don't store default value in Java model
|
||||
return null
|
||||
}
|
||||
override fun visitAnnotationDefault(): AnnotationVisitor? =
|
||||
BinaryJavaAnnotationVisitor(context, signatureParser) {
|
||||
member.safeAs<BinaryJavaMethod>()?.annotationParameterDefaultValue = it
|
||||
}
|
||||
|
||||
override fun visitParameter(name: String?, access: Int) {
|
||||
if (name != null) {
|
||||
@@ -165,19 +163,26 @@ class BinaryJavaAnnotation private constructor(
|
||||
}
|
||||
|
||||
class BinaryJavaAnnotationVisitor(
|
||||
private val context: ClassifierResolutionContext,
|
||||
private val signatureParser: BinaryClassSignatureParser,
|
||||
private val arguments: MutableCollection<JavaAnnotationArgument>
|
||||
private val context: ClassifierResolutionContext,
|
||||
private val signatureParser: BinaryClassSignatureParser,
|
||||
private val sink: (JavaAnnotationArgument) -> Unit
|
||||
) : AnnotationVisitor(ASM_API_VERSION_FOR_CLASS_READING) {
|
||||
constructor(
|
||||
context: ClassifierResolutionContext,
|
||||
signatureParser: BinaryClassSignatureParser,
|
||||
arguments: MutableCollection<JavaAnnotationArgument>
|
||||
) : this(context, signatureParser, { arguments.add(it) })
|
||||
|
||||
private fun addArgument(argument: JavaAnnotationArgument?) {
|
||||
arguments.addIfNotNull(argument)
|
||||
if (argument != null) {
|
||||
sink(argument)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnnotation(name: String?, desc: String): AnnotationVisitor {
|
||||
val (annotation, visitor) =
|
||||
BinaryJavaAnnotation.createAnnotationAndVisitor(desc, context, signatureParser)
|
||||
val (annotation, visitor) = BinaryJavaAnnotation.createAnnotationAndVisitor(desc, context, signatureParser)
|
||||
|
||||
arguments.add(PlainJavaAnnotationAsAnnotationArgument(name, annotation))
|
||||
sink(PlainJavaAnnotationAsAnnotationArgument(name, annotation))
|
||||
|
||||
return visitor
|
||||
}
|
||||
|
||||
+9
-1
@@ -169,7 +169,15 @@ class BinaryJavaMethod(
|
||||
) : BinaryJavaMethodBase(
|
||||
flags, containingClass, valueParameters, typeParameters, name
|
||||
), JavaMethod {
|
||||
override var hasAnnotationParameterDefaultValue: Boolean = false
|
||||
override var annotationParameterDefaultValue: JavaAnnotationArgument? = null
|
||||
internal set(value) {
|
||||
if (field != null) {
|
||||
throw AssertionError(
|
||||
"Annotation method cannot have two default values: $this (old=$field, new=$value)"
|
||||
)
|
||||
}
|
||||
field = value
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryJavaConstructor(
|
||||
|
||||
+6
-8
@@ -5,13 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.multiplatform
|
||||
|
||||
import com.intellij.psi.PsiAnnotationMethod
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluatorImpl
|
||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaAnnotationArgumentImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
@@ -23,11 +22,10 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
class JavaActualAnnotationArgumentExtractor : ExpectedActualDeclarationChecker.ActualAnnotationArgumentExtractor {
|
||||
override fun extractActualValue(argument: PsiElement, expectedType: KotlinType): ConstantValue<*>? =
|
||||
(argument as? PsiAnnotationMethod)
|
||||
?.defaultValue
|
||||
?.let { JavaAnnotationArgumentImpl.create(it, null) }
|
||||
?.convert(expectedType)
|
||||
override fun extractDefaultValue(parameter: ValueParameterDescriptor, expectedType: KotlinType): ConstantValue<*>? {
|
||||
val element = (parameter.source as? JavaSourceElement)?.javaElement
|
||||
return (element as? JavaMethod)?.annotationParameterDefaultValue?.convert(expectedType)
|
||||
}
|
||||
|
||||
// This code is similar to LazyJavaAnnotationDescriptor.resolveAnnotationArgument, but cannot be reused until
|
||||
// KClassValue/AnnotationValue are untied from descriptors/types, because here we do not have an instance of LazyJavaResolverContext.
|
||||
|
||||
+11
-11
@@ -43,7 +43,7 @@ import java.io.File
|
||||
|
||||
class ExpectedActualDeclarationChecker(val argumentExtractors: List<ActualAnnotationArgumentExtractor> = emptyList()) : DeclarationChecker {
|
||||
interface ActualAnnotationArgumentExtractor {
|
||||
fun extractActualValue(argument: PsiElement, expectedType: KotlinType): ConstantValue<*>?
|
||||
fun extractDefaultValue(parameter: ValueParameterDescriptor, expectedType: KotlinType): ConstantValue<*>?
|
||||
}
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
@@ -233,14 +233,15 @@ class ExpectedActualDeclarationChecker(val argumentExtractors: List<ActualAnnota
|
||||
if (expectedParameterDescriptor.declaresDefaultValue() && actualParameterDescriptor.declaresDefaultValue()) {
|
||||
val expectedParameter =
|
||||
DescriptorToSourceUtils.descriptorToDeclaration(expectedParameterDescriptor) as? KtParameter ?: continue
|
||||
val actualParameter = DescriptorToSourceUtils.descriptorToDeclaration(actualParameterDescriptor)
|
||||
|
||||
val expectedValue = trace.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expectedParameter.defaultValue)
|
||||
?.toConstantValue(expectedParameterDescriptor.type)
|
||||
|
||||
val actualValue = getActualAnnotationParameterValue(actualParameter, trace.bindingContext, expectedParameterDescriptor.type)
|
||||
val actualValue =
|
||||
getActualAnnotationParameterValue(actualParameterDescriptor, trace.bindingContext, expectedParameterDescriptor.type)
|
||||
if (expectedValue != actualValue) {
|
||||
val target = (actualParameter as? KtParameter)?.defaultValue ?: (reportOn as? KtTypeAlias)?.nameIdentifier ?: reportOn
|
||||
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(actualParameterDescriptor)
|
||||
val target = (ktParameter as? KtParameter)?.defaultValue ?: (reportOn as? KtTypeAlias)?.nameIdentifier ?: reportOn
|
||||
trace.report(Errors.ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE.on(target, actualParameterDescriptor))
|
||||
}
|
||||
}
|
||||
@@ -248,16 +249,15 @@ class ExpectedActualDeclarationChecker(val argumentExtractors: List<ActualAnnota
|
||||
}
|
||||
|
||||
private fun getActualAnnotationParameterValue(
|
||||
actualParameter: PsiElement?, bindingContext: BindingContext, expectedType: KotlinType
|
||||
actualParameter: ValueParameterDescriptor, bindingContext: BindingContext, expectedType: KotlinType
|
||||
): ConstantValue<*>? {
|
||||
if (actualParameter is KtParameter) {
|
||||
return bindingContext.get(BindingContext.COMPILE_TIME_VALUE, actualParameter.defaultValue)?.toConstantValue(expectedType)
|
||||
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(actualParameter)
|
||||
if (declaration is KtParameter) {
|
||||
return bindingContext.get(BindingContext.COMPILE_TIME_VALUE, declaration.defaultValue)?.toConstantValue(expectedType)
|
||||
}
|
||||
|
||||
if (actualParameter != null) {
|
||||
for (extractor in argumentExtractors) {
|
||||
extractor.extractActualValue(actualParameter, expectedType)?.let { return it }
|
||||
}
|
||||
for (extractor in argumentExtractors) {
|
||||
extractor.extractDefaultValue(actualParameter, expectedType)?.let { return it }
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
+6
-3
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.javac.wrappers.symbols
|
||||
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import javax.lang.model.element.ExecutableElement
|
||||
|
||||
class SymbolBasedMethod(
|
||||
@@ -35,7 +36,9 @@ class SymbolBasedMethod(
|
||||
override val returnType: JavaType
|
||||
get() = SymbolBasedType.create(element.returnType, javac)
|
||||
|
||||
override val hasAnnotationParameterDefaultValue: Boolean
|
||||
get() = element.defaultValue != null
|
||||
|
||||
// TODO: allow nullable names in Symbol-based annotation arguments and pass null instead of a synthetic name
|
||||
override val annotationParameterDefaultValue: JavaAnnotationArgument?
|
||||
get() = element.defaultValue?.let { defaultValue ->
|
||||
SymbolBasedAnnotationArgument.create(defaultValue, Name.identifier("value"), javac)
|
||||
}
|
||||
}
|
||||
|
||||
+39
-35
@@ -100,46 +100,50 @@ class TreeBasedAnnotationAsAnnotationArgument(private val annotation: JCTree.JCA
|
||||
|
||||
}
|
||||
|
||||
private fun createAnnotationArguments(annotation: TreeBasedAnnotation,
|
||||
javac: JavacWrapper,
|
||||
onElement: JavaElement): Collection<JavaAnnotationArgument> =
|
||||
private fun createAnnotationArguments(
|
||||
annotation: TreeBasedAnnotation, javac: JavacWrapper, onElement: JavaElement
|
||||
): Collection<JavaAnnotationArgument> =
|
||||
annotation.annotation.arguments.mapNotNull {
|
||||
val name = if (it is JCTree.JCAssign) Name.identifier(it.lhs.toString()) else Name.identifier("value")
|
||||
createAnnotationArgument(it, name, annotation.compilationUnit, javac, annotation, onElement)
|
||||
createAnnotationArgument(it, name, annotation.compilationUnit, javac, annotation.resolve(), onElement)
|
||||
}
|
||||
|
||||
private fun createAnnotationArgument(argument: JCTree.JCExpression,
|
||||
name: Name,
|
||||
compilationUnit: CompilationUnitTree,
|
||||
javac: JavacWrapper,
|
||||
annotation: TreeBasedAnnotation,
|
||||
onElement: JavaElement): JavaAnnotationArgument? =
|
||||
when (argument) {
|
||||
is JCTree.JCLiteral -> TreeBasedLiteralAnnotationArgument(name, argument.value, javac)
|
||||
is JCTree.JCFieldAccess -> {
|
||||
if (argument.name.contentEquals("class")) {
|
||||
TreeBasedJavaClassObjectAnnotationArgument(argument.selected, name, compilationUnit, javac, onElement)
|
||||
}
|
||||
else {
|
||||
TreeBasedReferenceAnnotationArgument(name, compilationUnit, argument, javac, onElement)
|
||||
}
|
||||
internal fun createAnnotationArgument(
|
||||
argument: JCTree.JCExpression,
|
||||
name: Name,
|
||||
compilationUnit: CompilationUnitTree,
|
||||
javac: JavacWrapper,
|
||||
containingClass: JavaClass?,
|
||||
onElement: JavaElement
|
||||
): JavaAnnotationArgument? =
|
||||
when (argument) {
|
||||
is JCTree.JCLiteral -> TreeBasedLiteralAnnotationArgument(name, argument.value, javac)
|
||||
is JCTree.JCFieldAccess -> {
|
||||
if (argument.name.contentEquals("class")) {
|
||||
TreeBasedJavaClassObjectAnnotationArgument(argument.selected, name, compilationUnit, javac, onElement)
|
||||
} else {
|
||||
TreeBasedReferenceAnnotationArgument(name, compilationUnit, argument, javac, onElement)
|
||||
}
|
||||
is JCTree.JCAssign -> createAnnotationArgument(argument.rhs, name, compilationUnit, javac, annotation, onElement)
|
||||
is JCTree.JCNewArray -> TreeBasedArrayAnnotationArgument(argument.elems.mapNotNull { createAnnotationArgument(it, name, compilationUnit, javac, annotation, onElement) }, name, javac)
|
||||
is JCTree.JCAnnotation -> TreeBasedAnnotationAsAnnotationArgument(argument, name, compilationUnit, javac, onElement)
|
||||
is JCTree.JCParens -> createAnnotationArgument(argument.expr, name, compilationUnit, javac, annotation, onElement)
|
||||
is JCTree.JCBinary -> resolveArgumentValue(argument, annotation, name, compilationUnit, javac)
|
||||
is JCTree.JCUnary -> resolveArgumentValue(argument, annotation, name, compilationUnit, javac)
|
||||
else -> throw UnsupportedOperationException("Unknown annotation argument $argument")
|
||||
}
|
||||
is JCTree.JCAssign -> createAnnotationArgument(argument.rhs, name, compilationUnit, javac, containingClass, onElement)
|
||||
is JCTree.JCNewArray -> TreeBasedArrayAnnotationArgument(argument.elems.mapNotNull {
|
||||
createAnnotationArgument(it, name, compilationUnit, javac, containingClass, onElement)
|
||||
}, name, javac)
|
||||
is JCTree.JCAnnotation -> TreeBasedAnnotationAsAnnotationArgument(argument, name, compilationUnit, javac, onElement)
|
||||
is JCTree.JCParens -> createAnnotationArgument(argument.expr, name, compilationUnit, javac, containingClass, onElement)
|
||||
is JCTree.JCBinary -> resolveArgumentValue(argument, containingClass, name, compilationUnit, javac)
|
||||
is JCTree.JCUnary -> resolveArgumentValue(argument, containingClass, name, compilationUnit, javac)
|
||||
else -> throw UnsupportedOperationException("Unknown annotation argument $argument")
|
||||
}
|
||||
|
||||
private fun resolveArgumentValue(argument: JCTree.JCExpression,
|
||||
annotation: TreeBasedAnnotation,
|
||||
name: Name,
|
||||
compilationUnit: CompilationUnitTree,
|
||||
javac: JavacWrapper): JavaAnnotationArgument? {
|
||||
val containingAnnotation = annotation.resolve() ?: return null
|
||||
val evaluator = ConstantEvaluator(containingAnnotation, javac, compilationUnit)
|
||||
|
||||
private fun resolveArgumentValue(
|
||||
argument: JCTree.JCExpression,
|
||||
containingClass: JavaClass?,
|
||||
name: Name,
|
||||
compilationUnit: CompilationUnitTree,
|
||||
javac: JavacWrapper
|
||||
): JavaAnnotationArgument? {
|
||||
if (containingClass == null) return null
|
||||
val evaluator = ConstantEvaluator(containingClass, javac, compilationUnit)
|
||||
return evaluator.getValue(argument)?.let { TreeBasedLiteralAnnotationArgument(name, it, javac) }
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -55,6 +55,9 @@ class TreeBasedMethod(
|
||||
override val returnType: JavaType
|
||||
get() = TreeBasedType.create(tree.returnType, compilationUnit, javac, annotations, this)
|
||||
|
||||
override val hasAnnotationParameterDefaultValue: Boolean
|
||||
get() = tree.defaultValue != null
|
||||
}
|
||||
// TODO: allow nullable names in Tree-based annotation arguments and pass null instead of a synthetic name
|
||||
override val annotationParameterDefaultValue: JavaAnnotationArgument?
|
||||
get() = tree.defaultValue?.let { defaultValue ->
|
||||
createAnnotationArgument(defaultValue, Name.identifier("value"), compilationUnit, javac, containingClass, this)
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// WITH_REFLECT
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: main.kt
|
||||
|
||||
// See compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt
|
||||
|
||||
// This test checks the same behavior but against the Java implementation compiled to the .class file (as opposed to a .java source file).
|
||||
// Enum annotation argument is commented below, because to be able to resolve E in Jnno.java we have to have a multi-module test where
|
||||
// one of the modules also contains Java files, and that is too complicated for our test infrastructure at the moment.
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
expect annotation class Anno(
|
||||
val b: Byte = 1.toByte(),
|
||||
val c: Char = 'x',
|
||||
val d: Double = 3.14,
|
||||
val f: Float = -2.72f,
|
||||
val i: Int = 42424242,
|
||||
val i2: Int = 53535353,
|
||||
val j: Long = 239239239239239L,
|
||||
val j2: Long = 239239L,
|
||||
val s: Short = 42.toShort(),
|
||||
val z: Boolean = true,
|
||||
val ba: ByteArray = [(-1).toByte()],
|
||||
val ca: CharArray = ['y'],
|
||||
val da: DoubleArray = [-3.14159],
|
||||
val fa: FloatArray = [2.7218f],
|
||||
val ia: IntArray = [424242],
|
||||
val ja: LongArray = [239239239239L, 239239L],
|
||||
val sa: ShortArray = [(-43).toShort()],
|
||||
val za: BooleanArray = [false, true],
|
||||
val str: String = "fizz",
|
||||
val k: KClass<*> = Number::class,
|
||||
// val e: E = E.E1,
|
||||
// TODO: val a: A = A("1"),
|
||||
val stra: Array<String> = ["bu", "zz"],
|
||||
val ka: Array<KClass<*>> = [Double::class, String::class, LongArray::class, Array<Array<Array<Int>>>::class, Unit::class]
|
||||
// val ea: Array<E> = [E.E2, E.E3],
|
||||
// TODO: val aa: Array<A> = [A("2"), A("3")]
|
||||
)
|
||||
|
||||
// enum class E { E1, E2, E3 }
|
||||
|
||||
annotation class A(val value: String)
|
||||
|
||||
@Anno
|
||||
fun test() {}
|
||||
|
||||
actual typealias Anno = Jnno
|
||||
|
||||
fun box(): String {
|
||||
// We don't need to check the contents, just check that there are no anomalities in the bytecode by loading annotations
|
||||
::test.annotations.toString()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: Jnno.java
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Jnno {
|
||||
byte b() default 1;
|
||||
char c() default 'x';
|
||||
double d() default 3.14;
|
||||
float f() default -2.72f;
|
||||
int i() default 42424242;
|
||||
int i2() default 21212121 + 32323232;
|
||||
long j() default 239239239239239L;
|
||||
long j2() default 239239;
|
||||
short s() default 42;
|
||||
boolean z() default true;
|
||||
byte[] ba() default {-1};
|
||||
char[] ca() default {'y'};
|
||||
double[] da() default {-3.14159};
|
||||
float[] fa() default {2.7218f};
|
||||
int[] ia() default {424242};
|
||||
long[] ja() default {239239239239L, 239239};
|
||||
short[] sa() default {-43};
|
||||
boolean[] za() default {false, true};
|
||||
String str() default "fi" + "zz";
|
||||
Class<?> k() default Number.class;
|
||||
// E e() default E.E1;
|
||||
// TODO: A a() default @A("1");
|
||||
String[] stra() default {"bu", "zz"};
|
||||
Class<?>[] ka() default {double.class, String.class, long[].class, Integer[][][].class, void.class};
|
||||
// E[] ea() default {E.E2, E.E3};
|
||||
// TODO: A[] aa() default {@A("2"), @A("3")};
|
||||
}
|
||||
compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt
Vendored
+2
@@ -2,6 +2,8 @@
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
// See also compiler/testData/codegen/boxAgainstJava/multiplatform/annotationsViaActualTypeAliasFromBinary.kt
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
expect annotation class Anno(
|
||||
|
||||
+18
@@ -407,6 +407,24 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxAgainstJava/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Multiplatform extends AbstractBlackBoxAgainstJavaCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/multiplatform"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsViaActualTypeAliasFromBinary.kt")
|
||||
public void testAnnotationsViaActualTypeAliasFromBinary() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxAgainstJava/multiplatform/annotationsViaActualTypeAliasFromBinary.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxAgainstJava/notNullAssertions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Generated
+18
@@ -407,6 +407,24 @@ public class IrBlackBoxAgainstJavaCodegenTestGenerated extends AbstractIrBlackBo
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxAgainstJava/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Multiplatform extends AbstractIrBlackBoxAgainstJavaCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/multiplatform"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsViaActualTypeAliasFromBinary.kt")
|
||||
public void testAnnotationsViaActualTypeAliasFromBinary() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxAgainstJava/multiplatform/annotationsViaActualTypeAliasFromBinary.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxAgainstJava/notNullAssertions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+1
-1
@@ -675,7 +675,7 @@ class LazyJavaClassMemberScope(
|
||||
method.name,
|
||||
// Parameters of annotation constructors in Java are never nullable
|
||||
TypeUtils.makeNotNullable(returnType),
|
||||
method.hasAnnotationParameterDefaultValue,
|
||||
method.annotationParameterDefaultValue != null,
|
||||
/* isCrossinline = */ false,
|
||||
/* isNoinline = */ false,
|
||||
// Nulls are not allowed in annotation arguments in Java
|
||||
|
||||
@@ -105,7 +105,7 @@ interface JavaMethod : JavaMember, JavaTypeParameterListOwner {
|
||||
val valueParameters: List<JavaValueParameter>
|
||||
val returnType: JavaType
|
||||
|
||||
val hasAnnotationParameterDefaultValue: Boolean
|
||||
val annotationParameterDefaultValue: JavaAnnotationArgument?
|
||||
}
|
||||
|
||||
interface JavaField : JavaMember {
|
||||
|
||||
+3
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package kotlin.reflect.jvm.internal.structure
|
||||
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationArgument
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaMethod
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||
import java.lang.reflect.Method
|
||||
@@ -27,8 +28,8 @@ class ReflectJavaMethod(override val member: Method) : ReflectJavaMember(), Java
|
||||
override val returnType: ReflectJavaType
|
||||
get() = ReflectJavaType.create(member.genericReturnType)
|
||||
|
||||
override val hasAnnotationParameterDefaultValue: Boolean
|
||||
get() = member.defaultValue != null
|
||||
override val annotationParameterDefaultValue: JavaAnnotationArgument?
|
||||
get() = member.defaultValue?.let { ReflectJavaAnnotationArgument.create(it, null) }
|
||||
|
||||
override val typeParameters: List<ReflectJavaTypeParameter>
|
||||
get() = member.typeParameters.map(::ReflectJavaTypeParameter)
|
||||
|
||||
Reference in New Issue
Block a user