Record special name lookup when trying use interface as a SAM
It was already working in JPS, because it see our synthetic classes as subclasses for SAM's, but with non-JPS build we have to manually tracking places that should be recompiled after SAM members are changed
This commit is contained in:
@@ -32,6 +32,9 @@ class JavaSyntheticScopes(
|
||||
): SyntheticScopes {
|
||||
override val scopes = listOf(
|
||||
JavaSyntheticPropertiesScope(storageManager, lookupTracker),
|
||||
SamAdapterFunctionsScope(storageManager, languageVersionSettings, samConventionResolver, deprecationResolver)
|
||||
SamAdapterFunctionsScope(
|
||||
storageManager, languageVersionSettings, samConventionResolver, deprecationResolver,
|
||||
lookupTracker
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
+30
-4
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.record
|
||||
import org.jetbrains.kotlin.load.java.components.SamConversionResolver
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
@@ -48,11 +50,14 @@ interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, SyntheticM
|
||||
override val baseDescriptorForSynthetic: FunctionDescriptor
|
||||
}
|
||||
|
||||
val SAM_LOOKUP_NAME = Name.special("<SAM-CONSTRUCTOR>")
|
||||
|
||||
class SamAdapterFunctionsScope(
|
||||
storageManager: StorageManager,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val samResolver: SamConversionResolver,
|
||||
private val deprecationResolver: DeprecationResolver
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val lookupTracker: LookupTracker
|
||||
) : SyntheticScope {
|
||||
private val extensionForFunction = storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
|
||||
extensionForFunctionNotCached(function)
|
||||
@@ -94,6 +99,7 @@ class SamAdapterFunctionsScope(
|
||||
for (function in type.memberScope.getContributedFunctions(name, location)) {
|
||||
val extension = extensionForFunction(function.original)?.substituteForReceiverType(type)
|
||||
if (extension != null) {
|
||||
recordSamLookupsForParameters(function, location)
|
||||
if (result == null) {
|
||||
result = SmartList()
|
||||
}
|
||||
@@ -108,6 +114,12 @@ class SamAdapterFunctionsScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun recordSamLookupsForParameters(function: FunctionDescriptor, location: LookupLocation) {
|
||||
for (valueParameter in function.valueParameters) {
|
||||
recordSamLookupsToClassifier(valueParameter.type.constructor.declarationDescriptor ?: continue, location)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.substituteForReceiverType(receiverType: KotlinType): FunctionDescriptor? {
|
||||
val containingClass = containingDeclaration as? ClassDescriptor ?: return null
|
||||
val correspondingSupertype = findCorrespondingSupertype(receiverType, containingClass.defaultType) ?: return null
|
||||
@@ -135,16 +147,25 @@ class SamAdapterFunctionsScope(
|
||||
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> = emptyList()
|
||||
|
||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
return getSamFunctions(scope.getContributedFunctions(name, location))
|
||||
return getSamFunctions(scope.getContributedFunctions(name, location), location)
|
||||
}
|
||||
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList()
|
||||
recordSamLookupsToClassifier(classifier, location)
|
||||
return getAllSamConstructors(classifier)
|
||||
}
|
||||
|
||||
private fun recordSamLookupsToClassifier(classifier: ClassifierDescriptor, location: LookupLocation) {
|
||||
if (classifier !is JavaClassDescriptor || classifier.kind != ClassKind.INTERFACE) return
|
||||
// TODO: We should also record SAM lookups even when the interface is not SAM
|
||||
if (!SingleAbstractMethodUtils.isSamType(classifier.defaultType)) return
|
||||
|
||||
lookupTracker.record(location, classifier, SAM_LOOKUP_NAME)
|
||||
}
|
||||
|
||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
||||
return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS))
|
||||
return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS), location = null)
|
||||
}
|
||||
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
||||
@@ -172,12 +193,17 @@ class SamAdapterFunctionsScope(
|
||||
return samConstructorForJavaConstructor(constructor)
|
||||
}
|
||||
|
||||
private fun getSamFunctions(functions: Collection<DeclarationDescriptor>): List<SamAdapterDescriptor<JavaMethodDescriptor>> {
|
||||
private fun getSamFunctions(
|
||||
functions: Collection<DeclarationDescriptor>,
|
||||
location: LookupLocation?
|
||||
): List<SamAdapterDescriptor<JavaMethodDescriptor>> {
|
||||
return functions.mapNotNull { function ->
|
||||
if (function !is JavaMethodDescriptor) return@mapNotNull null
|
||||
if (function.dispatchReceiverParameter != null) return@mapNotNull null // consider only statics
|
||||
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return@mapNotNull null
|
||||
|
||||
location?.let { recordSamLookupsForParameters(function, it) }
|
||||
|
||||
samAdapterForStaticFunction(function)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user