[MPP] Refine scope for synthetic Java properties

Unrefined member scopes might have missing Java supertypes and cause
false positive resolution errors for synthetic properties in IDE.

KTIJ-22345
This commit is contained in:
Pavel Kirpichenkov
2022-08-05 18:53:00 +03:00
committed by Space
parent 89e55139c6
commit 029bb55157
2 changed files with 16 additions and 10 deletions
@@ -22,11 +22,11 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.getRefinedUnsubstitutedMemberScopeIfPossible
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.possibleGetMethodNames
@@ -34,15 +34,16 @@ import org.jetbrains.kotlin.load.java.setMethodName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticExtensionProperties
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeFirstWord
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
import kotlin.properties.Delegates
fun canBePropertyAccessor(identifier: String): Boolean {
@@ -93,6 +94,7 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor, SyntheticPropert
class JavaSyntheticPropertiesScope(
storageManager: StorageManager,
private val lookupTracker: LookupTracker,
private val typeRefiner: KotlinTypeRefiner,
private val supportJavaRecords: Boolean,
) : SyntheticScope.Default() {
private val syntheticPropertyInClass =
@@ -149,7 +151,7 @@ class JavaSyntheticPropertiesScope(
val possibleGetMethodNames = possibleGetMethodNames(name)
if (possibleGetMethodNames.isEmpty()) return SyntheticPropertyHolder.EMPTY
val memberScope = ownerClass.unsubstitutedMemberScope
val memberScope = ownerClass.getRefinedUnsubstitutedMemberScopeIfPossible(typeRefiner)
val getMethod = possibleGetMethodNames
.flatMap { memberScope.getContributedFunctions(it, NoLookupLocation.FROM_SYNTHETIC_SCOPE) }
@@ -175,7 +177,7 @@ class JavaSyntheticPropertiesScope(
if (!supportJavaRecords) return null
val componentLikeMethod =
ownerClass.unsubstitutedMemberScope
ownerClass.getRefinedUnsubstitutedMemberScopeIfPossible(typeRefiner)
.getContributedFunctions(name, NoLookupLocation.FROM_SYNTHETIC_SCOPE)
.singleOrNull(this::isGoodGetMethod) ?: return null
@@ -280,7 +282,9 @@ class JavaSyntheticPropertiesScope(
val classifier = type.declarationDescriptor
if (classifier is ClassDescriptor) {
for (descriptor in classifier.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)) {
val unsubstitutedMemberScope = classifier.getRefinedUnsubstitutedMemberScopeIfPossible(typeRefiner)
for (descriptor in unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)) {
if (descriptor is FunctionDescriptor) {
val propertyName = SyntheticJavaPropertyDescriptor.propertyNameByGetMethodName(descriptor.getName())
if (propertyName != null) {
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.synthetic.FunInterfaceConstructorsSyntheticScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
class JavaSyntheticScopes(
private val project: Project,
@@ -38,7 +39,8 @@ class JavaSyntheticScopes(
languageVersionSettings: LanguageVersionSettings,
samConventionResolver: SamConversionResolver,
samConversionOracle: SamConversionOracle,
deprecationResolver: DeprecationResolver
deprecationResolver: DeprecationResolver,
kotlinTypeRefiner: KotlinTypeRefiner,
) : SyntheticScopes {
override val scopes: Collection<SyntheticScope>
@@ -54,7 +56,7 @@ class JavaSyntheticScopes(
val javaSyntheticPropertiesScope =
JavaSyntheticPropertiesScope(
storageManager, lookupTracker,
storageManager, lookupTracker, kotlinTypeRefiner,
supportJavaRecords = languageVersionSettings.supportsFeature(LanguageFeature.JvmRecordSupport)
)
val scopesFromExtensions = SyntheticScopeProviderExtension