Synthetic properties: fixed completion and inspection for generic class

+ fixed KT-8539 No completion of generic extension function for <*> type arguments

 #KT-8539 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-07-17 19:57:01 +03:00
parent d2fb7381ce
commit e0e7044032
15 changed files with 103 additions and 31 deletions
@@ -30,15 +30,18 @@ import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.DescriptorSubstitutor
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.isBoolean
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeFirstWord
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart
import org.jetbrains.kotlin.utils.addIfNotNull
import java.beans.Introspector
import java.util.*
import java.util.ArrayList
import java.util.HashSet
interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
val getMethod: FunctionDescriptor
@@ -54,9 +57,10 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
val owner = getterOrSetter.getContainingDeclaration()
if (owner !is JavaClassDescriptor) return null
val originalGetterOrSetter = getterOrSetter.original
return resolutionScope.getSyntheticExtensionProperties(listOf(owner.getDefaultType()))
.filterIsInstance<SyntheticJavaPropertyDescriptor>()
.firstOrNull { getterOrSetter == it.getMethod || getterOrSetter == it.setMethod }
.firstOrNull { originalGetterOrSetter == it.getMethod || originalGetterOrSetter == it.setMethod }
}
fun propertyNameByGetMethodName(methodName: Name): Name?
@@ -90,18 +94,18 @@ class AdditionalScopesWithJavaSyntheticExtensions(storageManager: StorageManager
}
class JavaSyntheticExtensionsScope(storageManager: StorageManager) : JetScope by JetScope.Empty {
private val syntheticPropertyInClass = storageManager.createMemoizedFunctionWithNullableValues<Triple<JavaClassDescriptor, JetType, Name>, PropertyDescriptor> { triple ->
syntheticPropertyInClassNotCached(triple.first, triple.second, triple.third)
private val syntheticPropertyInClass = storageManager.createMemoizedFunctionWithNullableValues<Pair<JavaClassDescriptor, Name>, PropertyDescriptor> { pair ->
syntheticPropertyInClassNotCached(pair.first, pair.second)
}
private fun syntheticPropertyInClassNotCached(javaClass: JavaClassDescriptor, type: JetType, name: Name): PropertyDescriptor? {
private fun syntheticPropertyInClassNotCached(javaClass: JavaClassDescriptor, name: Name): PropertyDescriptor? {
if (name.isSpecial()) return null
val identifier = name.identifier
if (identifier.isEmpty()) return null
val firstChar = identifier[0]
if (!firstChar.isJavaIdentifierStart() || firstChar.isUpperCase()) return null
val memberScope = javaClass.getMemberScope(type.getArguments())
val memberScope = javaClass.getUnsubstitutedMemberScope()
val getMethod = possibleGetMethodNames(name)
.asSequence()
.flatMap { memberScope.getFunctions(it).asSequence() }
@@ -113,7 +117,7 @@ class JavaSyntheticExtensionsScope(storageManager: StorageManager) : JetScope by
val propertyType = getMethod.getReturnType() ?: return null
val setMethod = memberScope.getFunctions(setMethodName(getMethod.getName())).singleOrNull { isGoodSetMethod(it, propertyType) }
return MyPropertyDescriptor(javaClass, getMethod, setMethod, name, propertyType, type)
return MyPropertyDescriptor(javaClass, getMethod.original, setMethod?.original, name, propertyType)
}
private fun isGoodGetMethod(descriptor: FunctionDescriptor): Boolean {
@@ -157,7 +161,7 @@ class JavaSyntheticExtensionsScope(storageManager: StorageManager) : JetScope by
val typeConstructor = type.getConstructor()
val classifier = typeConstructor.getDeclarationDescriptor()
if (classifier is JavaClassDescriptor) {
result = result.add(syntheticPropertyInClass(Triple(classifier, type, name)))
result = result.add(syntheticPropertyInClass(Pair(classifier, name)))
}
typeConstructor.getSupertypes().forEach { result = collectSyntheticPropertiesByName(result, it, name, processedTypes) }
@@ -180,10 +184,10 @@ class JavaSyntheticExtensionsScope(storageManager: StorageManager) : JetScope by
val typeConstructor = type.getConstructor()
val classifier = typeConstructor.getDeclarationDescriptor()
if (classifier is JavaClassDescriptor) {
for (descriptor in classifier.getMemberScope(type.getArguments()).getDescriptors(DescriptorKindFilter.FUNCTIONS)) {
for (descriptor in classifier.getUnsubstitutedMemberScope().getDescriptors(DescriptorKindFilter.FUNCTIONS)) {
if (descriptor is FunctionDescriptor) {
val propertyName = SyntheticJavaPropertyDescriptor.propertyNameByGetMethodName(descriptor.getName()) ?: continue
addIfNotNull(syntheticPropertyInClass(Triple(classifier, type, propertyName)))
addIfNotNull(syntheticPropertyInClass(Pair(classifier, propertyName)))
}
}
}
@@ -232,8 +236,7 @@ class JavaSyntheticExtensionsScope(storageManager: StorageManager) : JetScope by
override val getMethod: FunctionDescriptor,
override val setMethod: FunctionDescriptor?,
name: Name,
type: JetType,
receiverType: JetType
type: JetType
) : SyntheticJavaPropertyDescriptor, PropertyDescriptorImpl(
DescriptorUtils.getContainingModule(javaClass)/* TODO:is it ok? */,
null,
@@ -246,7 +249,13 @@ class JavaSyntheticExtensionsScope(storageManager: StorageManager) : JetScope by
SourceElement.NO_SOURCE/*TODO?*/
) {
init {
setType(type, emptyList(), null, receiverType)
val classTypeParams = javaClass.typeConstructor.parameters
val typeParameters = ArrayList<TypeParameterDescriptor>(classTypeParams.size())
val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(classTypeParams, TypeSubstitutor.EMPTY, this, typeParameters)
val propertyType = typeSubstitutor.safeSubstitute(type, Variance.INVARIANT)
val receiverType = typeSubstitutor.safeSubstitute(javaClass.defaultType, Variance.INVARIANT)
setType(propertyType, typeParameters, null, receiverType)
val getter = PropertyGetterDescriptorImpl(this,
Annotations.EMPTY,