Remove StorageComponentContainerContributor::onContainerComposed

Rename addDeclarations -> registerModuleComponents
Use it to provide SamWithReceiverResolver extensions instead

Post construction on container composition can be achieved
    but manually inserting injections where it seems appropriate
    is bug prone
This fixes a bug where SamWithReceiverPlugin extension was not registered
    for some containers in IDE which led to incorrect highlighting in IDE
Add IDE test for applying SamWithReceiver plugin

 #KT-18062 Fixed
This commit is contained in:
Pavel V. Talanov
2017-08-17 17:33:03 +03:00
parent 6f180416b1
commit 6424b6760f
26 changed files with 199 additions and 75 deletions
@@ -29,11 +29,11 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.frontend.di.configureModule
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.java.*
import org.jetbrains.kotlin.load.java.AbstractJavaClassFinder
import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
import org.jetbrains.kotlin.load.java.components.*
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
import org.jetbrains.kotlin.load.java.sam.SamConversionResolverImpl
import org.jetbrains.kotlin.load.java.sam.SamWithReceiverResolver
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
import org.jetbrains.kotlin.platform.JvmBuiltIns
@@ -64,8 +64,6 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis(
useImpl<SignaturePropagatorImpl>()
useImpl<TraceBasedErrorReporter>()
useImpl<PsiBasedExternalAnnotationResolver>()
useInstance(SamWithReceiverResolver())
useImpl<SamConversionResolverImpl>()
useInstance(InternalFlexibleTypeTransformer)
useImpl<CompilerDeserializationConfiguration>()
@@ -21,13 +21,16 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.SimpleType
class SamConversionResolverImpl(val storageManager: StorageManager, val samWithReceiverResolver: SamWithReceiverResolver): SamConversionResolver {
class SamConversionResolverImpl(
storageManager: StorageManager,
private val samWithReceiverResolvers: Iterable<SamWithReceiverResolver>
): SamConversionResolver {
private val functionTypesForSamInterfaces = storageManager.createCacheWithNullableValues<JavaClassDescriptor, SimpleType>()
override fun resolveFunctionTypeIfSamInterface(classDescriptor: JavaClassDescriptor): SimpleType? {
return functionTypesForSamInterfaces.computeIfAbsent(classDescriptor) {
val abstractMethod = SingleAbstractMethodUtils.getSingleAbstractMethodOrNull(classDescriptor) ?: return@computeIfAbsent null
val shouldConvertFirstParameterToDescriptor = samWithReceiverResolver.shouldConvertFirstSamParameterToReceiver(abstractMethod)
val shouldConvertFirstParameterToDescriptor = samWithReceiverResolvers.any { it.shouldConvertFirstSamParameterToReceiver(abstractMethod) }
SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod, shouldConvertFirstParameterToDescriptor)
}
}
@@ -18,18 +18,6 @@ package org.jetbrains.kotlin.load.java.sam
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
class SamWithReceiverResolver {
private val extensions = mutableListOf<Extension>()
fun registerExtension(extension: Extension) {
extensions += extension
}
fun shouldConvertFirstSamParameterToReceiver(function: FunctionDescriptor): Boolean {
return extensions.any { it.shouldConvertFirstSamParameterToReceiver(function) }
}
interface Extension {
fun shouldConvertFirstSamParameterToReceiver(function: FunctionDescriptor): Boolean
}
interface SamWithReceiverResolver {
fun shouldConvertFirstSamParameterToReceiver(function: FunctionDescriptor): Boolean
}
@@ -100,8 +100,6 @@ object JvmAnalyzerFacade : AnalyzerFacade() {
useBuiltInsProvider = false // TODO: load built-ins from module dependencies in IDE
)
StorageComponentContainerContributor.getInstances(project).forEach { it.onContainerComposed(container, moduleInfo) }
val resolveSession = container.get<ResolveSession>()
val javaDescriptorResolver = container.get<JavaDescriptorResolver>()
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.jvm.platform
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.load.java.sam.SamConversionResolverImpl
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.PlatformConfigurator
import org.jetbrains.kotlin.resolve.calls.checkers.ReifiedTypeParameterSubstitutionChecker
@@ -83,6 +84,7 @@ object JvmPlatformConfigurator : PlatformConfigurator(
override fun configureModuleComponents(container: StorageComponentContainer) {
container.useImpl<JvmReflectionAPICallChecker>()
container.useImpl<JavaSyntheticScopes>()
container.useImpl<SamConversionResolverImpl>()
container.useImpl<InterfaceDefaultMethodCallChecker>()
container.useImpl<InlinePlatformCompatibilityChecker>()
container.useImpl<JvmModuleAccessibilityChecker>()