JvmAnalyzerFacade: Do not fail when java resolve api behaves in an unexpected way
Fixes a problem when java type from a library can be resolved to a class in source root
This commit is contained in:
@@ -16,18 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.jvm
|
package org.jetbrains.kotlin.resolve.jvm
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.analyzer.*
|
import org.jetbrains.kotlin.analyzer.*
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
import org.jetbrains.kotlin.context.ModuleContext
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleParameters
|
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.extensions.ExternalDeclarationsProvider
|
import org.jetbrains.kotlin.extensions.ExternalDeclarationsProvider
|
||||||
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
|
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
|
||||||
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
|
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
|
||||||
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
|
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
|
||||||
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.resolve.TargetPlatform
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
||||||
import java.util.ArrayList
|
import java.util.*
|
||||||
|
|
||||||
public class JvmPlatformParameters(
|
public class JvmPlatformParameters(
|
||||||
public val moduleByJavaClass: (JavaClass) -> ModuleInfo
|
public val moduleByJavaClass: (JavaClass) -> ModuleInfo
|
||||||
@@ -63,9 +63,20 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
|
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
|
||||||
val moduleInfo = platformParameters.moduleByJavaClass(javaClass)
|
val referencedClassModule = platformParameters.moduleByJavaClass(javaClass)
|
||||||
resolverForProject.resolverForModule(moduleInfo as M).componentProvider.get<JavaDescriptorResolver>()
|
// We don't have full control over idea resolve api so we allow for a situation which should not happen in Kotlin.
|
||||||
|
// For example, type in a java library can reference a class declared in a source root (is valid but rare case)
|
||||||
|
// Providing a fallback strategy in this case can hide future problems, so we should at least log to be able to diagnose those
|
||||||
|
val resolverForReferencedModule = resolverForProject.tryGetResolverForModule(referencedClassModule as M)
|
||||||
|
val resolverForModule = resolverForReferencedModule ?: run {
|
||||||
|
LOG.warn("Java referenced $referencedClassModule from $moduleInfo\nReferenced class was: $javaClass\n")
|
||||||
|
// in case referenced class lies outside of our resolver, resolve the class as if it is inside our module
|
||||||
|
// this leads to java class being resolved several times
|
||||||
|
resolverForProject.resolverForModule(moduleInfo)
|
||||||
|
}
|
||||||
|
resolverForModule.componentProvider.get<JavaDescriptorResolver>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val container = createContainerForLazyResolveWithJava(
|
val container = createContainerForLazyResolveWithJava(
|
||||||
moduleContext,
|
moduleContext,
|
||||||
CodeAnalyzerInitializer.getInstance(project).createTrace(),
|
CodeAnalyzerInitializer.getInstance(project).createTrace(),
|
||||||
@@ -93,4 +104,6 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
|||||||
|
|
||||||
override val targetPlatform: TargetPlatform
|
override val targetPlatform: TargetPlatform
|
||||||
get() = JvmPlatform
|
get() = JvmPlatform
|
||||||
|
|
||||||
|
private val LOG = Logger.getInstance(JvmAnalyzerFacade::class.java)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user