Fix TypeAliasConstructorDescriptor's to create only once when required

Some IDE features relates onto that same descriptors will remain same
between resolve calls
Fix it to be true for TypeAliasConstructorDescriptor's

 #KT-16265 fixed
This commit is contained in:
Simon Ogorodnik
2017-03-14 15:51:20 +03:00
parent 23cbb83c75
commit f56af41d1e
12 changed files with 113 additions and 46 deletions
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import java.util.*
@@ -68,7 +68,7 @@ class OverloadResolver(
for (typeAlias in c.typeAliases.values) {
val containingDeclaration = typeAlias.containingDeclaration
if (containingDeclaration is ClassDescriptor) {
constructorsByOuterClass.putValues(containingDeclaration, typeAlias.getTypeAliasConstructors())
constructorsByOuterClass.putValues(containingDeclaration, typeAlias.constructors)
}
}
@@ -104,7 +104,7 @@ class OverloadResolver(
else
functions
is TypeAliasDescriptor ->
functions + classifier.getTypeAliasConstructors()
functions + classifier.constructors
else ->
functions
}
@@ -21,6 +21,7 @@ import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
@@ -33,7 +34,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -210,7 +210,7 @@ fun createResolutionCandidatesForConstructors(
else
null
val constructors = typeAliasDescriptor?.getTypeAliasConstructors(withDispatchReceiver = true) ?: classWithConstructors.constructors
val constructors = typeAliasDescriptor?.constructors?.mapNotNull(TypeAliasConstructorDescriptor::withDispatchReceiver) ?: classWithConstructors.constructors
if (constructors.isEmpty()) return emptyList()
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtTypeAlias
@@ -27,13 +28,14 @@ import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.asSimpleType
class LazyTypeAliasDescriptor(
private val storageManager: StorageManager,
override val storageManager: StorageManager,
private val trace: BindingTrace,
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
@@ -42,6 +44,9 @@ class LazyTypeAliasDescriptor(
visibility: Visibility
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, sourceElement, visibility),
TypeAliasDescriptor {
override val constructors: Collection<TypeAliasConstructorDescriptor> by storageManager.createLazyValue {
getTypeAliasConstructors()
}
private lateinit var underlyingTypeImpl: NotNullLazyValue<SimpleType>
private lateinit var expandedTypeImpl: NotNullLazyValue<SimpleType>
@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
@@ -280,13 +278,12 @@ private fun ResolutionScope.getContributedFunctionsAndConstructors(
}
private fun ClassifierDescriptor.getCallableConstructors(): Collection<FunctionDescriptor> =
when (this) {
is TypeAliasDescriptor ->
getTypeAliasConstructors()
is ClassDescriptor ->
if (canHaveCallableConstructors) constructors else emptyList()
else -> emptyList()
}
when (this) {
is TypeAliasDescriptor -> if (canHaveCallableConstructors) constructors else emptyList()
is ClassDescriptor -> if (canHaveCallableConstructors) constructors else emptyList()
else -> emptyList()
}
private fun ResolutionScope.getContributedObjectVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
val objectDescriptor = getFakeDescriptorForObject(getContributedClassifier(name, location))
@@ -319,11 +316,5 @@ private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDe
private val ClassDescriptor.canHaveCallableConstructors: Boolean
get() = !ErrorUtils.isError(this) && !kind.isSingleton
fun TypeAliasDescriptor.getTypeAliasConstructors(withDispatchReceiver: Boolean = false): Collection<TypeAliasConstructorDescriptor> {
val classDescriptor = this.classDescriptor ?: return emptyList()
if (!classDescriptor.canHaveCallableConstructors) return emptyList()
return classDescriptor.constructors.mapNotNull {
TypeAliasConstructorDescriptorImpl.createIfAvailable(this, it, withDispatchReceiver)
}
}
private val TypeAliasDescriptor.canHaveCallableConstructors: Boolean
get() = classDescriptor != null && !ErrorUtils.isError(classDescriptor) && classDescriptor!!.canHaveCallableConstructors