Add JavaToKotlinClassMap#isJavaPlatformClass
Use it instead of mapPlatformClass where we only need to check emptiness because mapPlatformClass requires built-ins and it's not always easy to come up with the correct instance of built-ins. In KotlinEvaluationBuilder, use the nullable function findClassAcrossModuleDependencies instead of mapPlatformClass which uses the throwing resolveClassByFqName. This is necessary because DefaultBuiltIns, which are used there, are not always able to find classes mapped by a _Java_ to Kotlin class map. (The correct solution would be not to use DefaultBuiltIns at all, instead obtaining the correct instance of built-ins, which are almost certainly going to be JvmBuiltIns, from the project configuration.)
This commit is contained in:
+4
-4
@@ -154,11 +154,11 @@ class JavaTypeResolver(
|
||||
attr.flexibility == FLEXIBLE_LOWER_BOUND -> MEMBER_SIGNATURE_COVARIANT
|
||||
attr.flexibility == FLEXIBLE_UPPER_BOUND -> MEMBER_SIGNATURE_CONTRAVARIANT
|
||||
|
||||
// This case has to be checked before isMarkedReadOnly/isMarkedMutable, because those two are slow
|
||||
// not mapped, we don't care about being marked mutable/read-only
|
||||
javaToKotlin.mapPlatformClass(fqName, c.module.builtIns).isEmpty() -> attr.howThisTypeIsUsed
|
||||
// This case has to be checked before isMarkedReadOnly/isMarkedMutable, because those two are slow
|
||||
// not mapped, we don't care about being marked mutable/read-only
|
||||
!javaToKotlin.isJavaPlatformClass(fqName) -> attr.howThisTypeIsUsed
|
||||
|
||||
// Read (possibly external) annotations
|
||||
// Read (possibly external) annotations
|
||||
else -> attr.howThisTypeIsUsedAccordingToAnnotations
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -172,6 +172,10 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
|
||||
: classId(outer).createNestedClassId(Name.identifier(clazz.getSimpleName()));
|
||||
}
|
||||
|
||||
public boolean isJavaPlatformClass(@NotNull FqName fqName) {
|
||||
return mapJavaToKotlin(fqName) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ClassDescriptor> mapPlatformClass(@NotNull FqName fqName, @NotNull KotlinBuiltIns builtIns) {
|
||||
ClassDescriptor kotlinAnalog = mapJavaToKotlin(fqName, builtIns);
|
||||
|
||||
@@ -93,4 +93,4 @@ class ImportableFqNameClassifier(private val file: KtFile) {
|
||||
}
|
||||
|
||||
fun isJavaClassNotToBeUsedInKotlin(fqName: FqName): Boolean
|
||||
= JavaToKotlinClassMap.INSTANCE.mapPlatformClass(fqName, DefaultBuiltIns.Instance).isNotEmpty() || JavaAnnotationMapper.javaToKotlinNameMap[fqName] != null
|
||||
= JavaToKotlinClassMap.INSTANCE.isJavaPlatformClass(fqName) || JavaAnnotationMapper.javaToKotlinNameMap[fqName] != null
|
||||
|
||||
@@ -20,11 +20,13 @@ import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.psi.psiUtil.allChildren
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import java.util.*
|
||||
|
||||
data class DataForConversion private constructor(
|
||||
val elementsAndTexts: Collection<Any> /* list consisting of PsiElement's to convert and plain String's */,
|
||||
@@ -243,9 +245,7 @@ data class DataForConversion private constructor(
|
||||
else {
|
||||
val fqName = FqNameUnsafe(qualifiedName)
|
||||
// skip explicit imports of platform classes mapped into Kotlin classes
|
||||
if (fqName.isSafe
|
||||
&& JavaToKotlinClassMap.INSTANCE.mapPlatformClass(
|
||||
fqName.toSafe(), DefaultBuiltIns.Instance).isNotEmpty()) continue
|
||||
if (fqName.isSafe && JavaToKotlinClassMap.INSTANCE.isJavaPlatformClass(fqName.toSafe())) continue
|
||||
append("import $qualifiedName\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ASM5
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -549,8 +550,10 @@ fun Type.getClassDescriptor(scope: GlobalSearchScope): ClassDescriptor? {
|
||||
|
||||
val jvmName = JvmClassName.byInternalName(internalName).fqNameForClassNameWithoutDollars
|
||||
|
||||
val platformClasses = JavaToKotlinClassMap.INSTANCE.mapPlatformClass(jvmName, DefaultBuiltIns.Instance)
|
||||
if (platformClasses.isNotEmpty()) return platformClasses.first()
|
||||
// TODO: use the correct built-ins from the module instead of DefaultBuiltIns here
|
||||
JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(jvmName)?.let(
|
||||
DefaultBuiltIns.Instance.builtInsModule::findClassAcrossModuleDependencies
|
||||
)?.let { return it }
|
||||
|
||||
return runReadAction {
|
||||
val classes = JavaPsiFacade.getInstance(scope.project).findClasses(jvmName.asString(), scope)
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.j2k.ast.Import
|
||||
import org.jetbrains.kotlin.j2k.ast.ImportList
|
||||
@@ -60,7 +59,7 @@ private fun Converter.convertImport(fqName: FqName, ref: PsiJavaCodeReferenceEle
|
||||
if (annotationConverter.isImportNotRequired(fqName)) return emptyList()
|
||||
|
||||
// If imported class has a kotlin analog, drop the import
|
||||
if (!JavaToKotlinClassMap.INSTANCE.mapPlatformClass(fqName, DefaultBuiltIns.Instance).isEmpty()) return emptyList()
|
||||
if (JavaToKotlinClassMap.INSTANCE.isJavaPlatformClass(fqName)) return emptyList()
|
||||
}
|
||||
|
||||
//TODO: how to detect compiled Kotlin here?
|
||||
|
||||
Reference in New Issue
Block a user