diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index 402636cf70e..8109cecc0d7 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -68,7 +68,7 @@ internal fun FirTypeRef.toNotNullConeKotlinType(): ConeKotlinType = else -> ConeKotlinErrorType("Unexpected type reference in JavaClassUseSiteScope: ${this::class.java}") } -internal fun JavaType.toNotNullConeKotlinType(session: FirSession): ConeLookupTagBasedType { +internal fun JavaType?.toNotNullConeKotlinType(session: FirSession): ConeLookupTagBasedType { return toConeKotlinTypeWithNullability(session, isNullable = false) } @@ -85,7 +85,7 @@ internal fun JavaClassifierType.toFirResolvedTypeRef(session: FirSession): FirRe ) } -internal fun JavaType.toConeKotlinTypeWithNullability(session: FirSession, isNullable: Boolean): ConeLookupTagBasedType { +internal fun JavaType?.toConeKotlinTypeWithNullability(session: FirSession, isNullable: Boolean): ConeLookupTagBasedType { return when (this) { is JavaClassifierType -> { toConeKotlinTypeWithNullability(session, isNullable) @@ -118,6 +118,10 @@ internal fun JavaType.toConeKotlinTypeWithNullability(session: FirSession, isNul val classId = ClassId(FqName("kotlin"), FqName("Any"), false) classId.toConeKotlinType(emptyArray(), isNullable) } + null -> { + val classId = ClassId(FqName("kotlin"), FqName("Any"), false) + classId.toConeKotlinType(emptyArray(), isNullable) + } else -> error("Strange JavaType: ${this::class.java}") } } @@ -172,8 +176,9 @@ internal fun FirAbstractAnnotatedElement.addAnnotationsFrom(javaAnnotationOwner: } } -internal fun JavaType.toConeProjection(session: FirSession, boundTypeParameter: FirTypeParameter?): ConeKotlinTypeProjection { +internal fun JavaType?.toConeProjection(session: FirSession, boundTypeParameter: FirTypeParameter?): ConeKotlinTypeProjection { return when (this) { + null -> ConeStarProjection is JavaWildcardType -> { val bound = this.bound val argumentVariance = if (isExtends) OUT_VARIANCE else IN_VARIANCE diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt index 4e4a3d27783..842551803b9 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt @@ -95,8 +95,8 @@ internal class EnhancementSignatureParts( if (type is FirJavaTypeRef) { for (arg in type.type.typeArguments()) { - if (arg is JavaWildcardType) { - // TODO: wildcards + if (arg is JavaWildcardType || arg == null) { + // TODO: wildcards / raw types } else { add(arg.toFirJavaTypeRef(context.session)) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index df799889b55..1ef3b0d5e82 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -46,14 +46,14 @@ internal fun FirJavaTypeRef.enhance( // Example: for `A>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C, 3 - D, 4 - E`, // which corresponds to the left-to-right breadth-first walk of the tree representation of the type. // For flexible types, both bounds are indexed in the same way: `(A..C)` gives `0 - (A..C), 1 - B and D`. -private fun JavaType.enhancePossiblyFlexible( +private fun JavaType?.enhancePossiblyFlexible( session: FirSession, annotations: List, qualifiers: (Int) -> JavaTypeQualifiers, index: Int ): FirResolvedTypeRef { val type = this - val arguments = typeArguments() + val arguments = this?.typeArguments().orEmpty() return when (type) { is JavaClassifierType -> { val lowerResult = type.enhanceInflexibleType( @@ -76,9 +76,9 @@ private fun JavaType.enhancePossiblyFlexible( } } -private fun JavaType.subtreeSize(): Int { +private fun JavaType?.subtreeSize(): Int { if (this !is JavaClassifierType) return 1 - return 1 + typeArguments.sumBy { it.subtreeSize() } + return 1 + typeArguments.sumBy { it?.subtreeSize() ?: 0 } } private val KOTLIN_COLLECTIONS = FqName("kotlin.collections") @@ -102,7 +102,7 @@ private fun ClassId.mutableToReadOnly(): ClassId? { private fun JavaClassifierType.enhanceInflexibleType( session: FirSession, annotations: List, - arguments: List, + arguments: List, position: TypeComponentPosition, qualifiers: (Int) -> JavaTypeQualifiers, index: Int @@ -199,7 +199,7 @@ internal data class TypeAndDefaultQualifiers( internal fun FirTypeRef.typeArguments(): List = (this as? FirUserTypeRef)?.qualifier?.lastOrNull()?.typeArguments.orEmpty() -internal fun JavaType.typeArguments(): List = (this as? JavaClassifierType)?.typeArguments.orEmpty() +internal fun JavaType.typeArguments(): List = (this as? JavaClassifierType)?.typeArguments.orEmpty() fun FirValueParameter.getDefaultValueFromAnnotation(): AnnotationDefaultValue? { annotations.find { it.resolvedFqName == JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt index 3fc527bca09..4eff5e4eb6d 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt @@ -102,7 +102,7 @@ class JavaClassEnhancementScope( original: ConeFunctionSymbol, name: Name ): FirFunctionSymbol { - val firMethod = (original as FirBasedSymbol<*>).fir as? FirJavaMethod ?: error("Can't make enhancement for $original") + val firMethod = (original as FirFunctionSymbol).fir as? FirJavaMethod ?: return original val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firMethod.annotations) diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt index a737fc740be..914cd905217 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt @@ -136,7 +136,7 @@ sealed class TreeBasedClassifierType( override val presentableText: String get() = classifierQualifiedName - override val typeArguments: List + override val typeArguments: List get() { var tree: JCTree = tree if (tree is JCTree.JCTypeApply) { @@ -230,9 +230,9 @@ class TreeBasedGenericClassifierType( ?: super.annotations } - override val typeArguments: List + override val typeArguments: List get() = tree.arguments.map { create(it, compilationUnit, javac, emptyList(), containingElement) } - .toMutableList() + .toMutableList() .apply { addAll(super.typeArguments) } override val isRaw: Boolean diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt index 5eda0a53c74..946612c6d9b 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt @@ -42,7 +42,7 @@ class JavaTypeResolver( private val typeParameterResolver: TypeParameterResolver ) { - fun transformJavaType(javaType: JavaType, attr: JavaTypeAttributes): KotlinType { + fun transformJavaType(javaType: JavaType?, attr: JavaTypeAttributes): KotlinType { return when (javaType) { is JavaPrimitiveType -> { val primitiveType = javaType.type @@ -53,6 +53,7 @@ class JavaTypeResolver( is JavaArrayType -> transformArrayType(javaType, attr) // Top level type can be a wildcard only in case of broken Java code, but we should not fail with exceptions in such cases is JavaWildcardType -> javaType.bound?.let { transformJavaType(it, attr) } ?: c.module.builtIns.defaultBound + null -> c.module.builtIns.defaultBound else -> throw UnsupportedOperationException("Unsupported type: " + javaType) } } @@ -247,7 +248,7 @@ class JavaTypeResolver( } private fun transformToTypeProjection( - javaType: JavaType, + javaType: JavaType?, attr: JavaTypeAttributes, typeParameter: TypeParameterDescriptor ): TypeProjection { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/structure/javaTypes.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/structure/javaTypes.kt index f88c324030b..1e87b4edada 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/structure/javaTypes.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/structure/javaTypes.kt @@ -26,7 +26,7 @@ interface JavaArrayType : JavaType { interface JavaClassifierType : JavaType, JavaAnnotationOwner { val classifier: JavaClassifier? - val typeArguments: List + val typeArguments: List val isRaw: Boolean diff --git a/idea/testData/fir/multiModule/javaInheritsRawKotlin/extraDump.java.txt b/idea/testData/fir/multiModule/javaInheritsRawKotlin/extraDump.java.txt new file mode 100644 index 00000000000..8bbbf604a78 --- /dev/null +++ b/idea/testData/fir/multiModule/javaInheritsRawKotlin/extraDump.java.txt @@ -0,0 +1,4 @@ +public open class Some : R|java/lang/Object|, R|Strange<*>| { + public open operator function foo(): R|ft| + +} diff --git a/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Derived.kt b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Derived.kt new file mode 100644 index 00000000000..cf8bdc9b946 --- /dev/null +++ b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Derived.kt @@ -0,0 +1 @@ +class Derived : Some() \ No newline at end of file diff --git a/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Derived.txt b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Derived.txt new file mode 100644 index 00000000000..d092eac99b7 --- /dev/null +++ b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Derived.txt @@ -0,0 +1,5 @@ +FILE: Derived.kt + public final class Derived : R|Some| { + public constructor(): super() + + } diff --git a/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Some.java b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Some.java new file mode 100644 index 00000000000..be52d48d8d3 --- /dev/null +++ b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Some.java @@ -0,0 +1,5 @@ +public class Some implements Strange { + public Object foo() { + return ""; + } +} \ No newline at end of file diff --git a/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Strange.kt b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Strange.kt new file mode 100644 index 00000000000..58e08835710 --- /dev/null +++ b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Strange.kt @@ -0,0 +1,3 @@ +interface Strange { + fun foo(): T +} \ No newline at end of file diff --git a/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Strange.txt b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Strange.txt new file mode 100644 index 00000000000..c14eb7f9567 --- /dev/null +++ b/idea/testData/fir/multiModule/javaInheritsRawKotlin/jvm/Strange.txt @@ -0,0 +1,5 @@ +FILE: Strange.kt + public abstract interface Strange { + public abstract function foo(): R|T| + + } diff --git a/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java index cbbbee78362..62282f1d440 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java @@ -59,6 +59,11 @@ public class FirMultiModuleResolveTestGenerated extends AbstractFirMultiModuleRe runTest("idea/testData/fir/multiModule/basicWithPrimitiveJava/"); } + @TestMetadata("javaInheritsRawKotlin") + public void testJavaInheritsRawKotlin() throws Exception { + runTest("idea/testData/fir/multiModule/javaInheritsRawKotlin/"); + } + @TestMetadata("mppFakeOverrides") public void testMppFakeOverrides() throws Exception { runTest("idea/testData/fir/multiModule/mppFakeOverrides/");