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:
Pavel V. Talanov
2015-10-27 15:29:43 +03:00
parent 4c70700943
commit dc791941d7
@@ -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)
} }