Fixes for IDE tests after qualifier modifications:
- CallType should look into QUALIFIER, so that completion works for (companion) object qualifiers. - Record type and reference target for object qualifiers (not only for companions). - "Create (function/...)" should understand ClassQualifier as possible receiver. - Cleanup after rebase on master.
This commit is contained in:
+13
-13
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classObjectType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassObjectType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.companionObjectType
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassifierQualifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.PackageQualifier
|
||||
@@ -94,19 +94,19 @@ private fun resolveQualifierReferenceTarget(
|
||||
// TODO make decisions about short reference to companion object somewhere else
|
||||
if (qualifier is ClassQualifier) {
|
||||
val classifier = qualifier.classifier
|
||||
if (selector is CallableDescriptor &&
|
||||
(selector.dispatchReceiverParameter != null || selector.extensionReceiverParameter != null) &&
|
||||
classifier is ClassDescriptor &&
|
||||
classifier.hasClassObjectType
|
||||
) {
|
||||
val companionObjectDescriptor = classifier.companionObjectDescriptor
|
||||
if (companionObjectDescriptor != null) {
|
||||
context.trace.record(BindingContext.REFERENCE_TARGET, qualifier.referenceExpression, companionObjectDescriptor)
|
||||
val selectorIsCallable = selector is CallableDescriptor &&
|
||||
(selector.dispatchReceiverParameter != null || selector.extensionReceiverParameter != null)
|
||||
val referenceTarget = classifier.classValueDescriptor
|
||||
if (selectorIsCallable && referenceTarget != null) {
|
||||
val classObjectType = classifier.companionObjectType!!
|
||||
val classObjectDescriptor = DescriptorUtils.getClassDescriptorForType(classObjectType)
|
||||
context.trace.record(BindingContext.REFERENCE_TARGET, qualifier.referenceExpression, referenceTarget)
|
||||
context.trace.recordType(qualifier.expression, classObjectType)
|
||||
if (classifier.companionObjectDescriptor != null) {
|
||||
context.trace.record(BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, qualifier.referenceExpression, classifier)
|
||||
context.trace.recordType(qualifier.expression, classifier.classObjectType)
|
||||
symbolUsageValidator.validateTypeUsage(companionObjectDescriptor, context.trace, qualifier.referenceExpression)
|
||||
return companionObjectDescriptor
|
||||
symbolUsageValidator.validateTypeUsage(referenceTarget, context.trace, qualifier.referenceExpression)
|
||||
}
|
||||
return classObjectDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -137,13 +137,6 @@ public class CallExpressionResolver {
|
||||
}
|
||||
}
|
||||
|
||||
//// Generate some diagnostics for qualifier in unexpected position
|
||||
//DeclarationDescriptor qualifierDescriptor =
|
||||
// QualifiedExpressionResolveUtilKt.getQualifierDescriptorOrNull(nameExpression, receiver, context);
|
||||
//if (qualifierDescriptor != null) {
|
||||
// QualifiedExpressionResolveUtilKt.checkQualifierAsStandaloneExpression(qualifierDescriptor, nameExpression, context);
|
||||
//}
|
||||
|
||||
temporaryForVariable.commit();
|
||||
result[0] = !resolutionResult.isNothing();
|
||||
return resolutionResult.isSingleResult() ? resolutionResult.getResultingDescriptor().getReturnType() : null;
|
||||
|
||||
+2
-1
@@ -169,6 +169,7 @@ private object VariableCollector : CallableDescriptorCollector<VariableDescripto
|
||||
override fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
val result = SmartList<VariableDescriptor>()
|
||||
result.addIfNotNull(lexicalScope.findLocalVariable(name))
|
||||
// Although local objects are prohibited, we'll include objects declared in current scope so that their usages are still resolved.
|
||||
result.addIfNotNull(getContributedFakeDescriptorForObject(lexicalScope, name, location))
|
||||
return result
|
||||
}
|
||||
@@ -186,7 +187,7 @@ private object VariableCollector : CallableDescriptorCollector<VariableDescripto
|
||||
|
||||
private fun getContributedFakeDescriptorForObject(scope: LexicalScope, name: Name, location: LookupLocation): VariableDescriptor? {
|
||||
val classifier = scope.getContributedClassifier(name, location)
|
||||
if (classifier !is ClassDescriptor || !classifier.hasClassObjectType) return null
|
||||
if (classifier !is ClassDescriptor || !classifier.hasCompanionObject) return null
|
||||
return FakeCallableDescriptorForObject(classifier)
|
||||
}
|
||||
|
||||
|
||||
@@ -99,15 +99,15 @@ public class TaskPrioritizer(
|
||||
taskPrioritizerContext: TaskPrioritizerContext<D, F>
|
||||
) {
|
||||
if (qualifier is ClassQualifier) {
|
||||
val companionObject = qualifierReceiver.companionObjectReceiver ?: return
|
||||
val classifierDescriptor = qualifierReceiver.classifier
|
||||
val companionObject = qualifier.companionObjectReceiver ?: return
|
||||
val classifierDescriptor = qualifier.classifier
|
||||
doComputeTasks(companionObject, taskPrioritizerContext.filterCollectors {
|
||||
when {
|
||||
classifierDescriptor is ClassDescriptor && classifierDescriptor.getCompanionObjectDescriptor() != null -> {
|
||||
// nested classes and objects should not be accessible via short reference to companion object
|
||||
it !is ConstructorDescriptor && it !is FakeCallableDescriptorForObject
|
||||
}
|
||||
classifierDescriptor != null && DescriptorUtils.isEnumEntry(classifierDescriptor) -> {
|
||||
DescriptorUtils.isEnumEntry(classifierDescriptor) -> {
|
||||
// objects nested in enum should not be accessible via enum entries reference
|
||||
it !is FakeCallableDescriptorForObject
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.resolve.scopes.receivers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
@@ -32,10 +31,6 @@ import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.FilteringScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findPackage
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
@@ -78,9 +73,6 @@ class PackageQualifier(
|
||||
override fun getNestedClassesAndPackageMembersScope(): MemberScope = packageView.memberScope
|
||||
|
||||
override fun toString() = "Package{$packageView}"
|
||||
|
||||
override val companionObjectReceiver: ReceiverValue?
|
||||
get() = null
|
||||
}
|
||||
|
||||
abstract class ClassifierQualifier(referenceExpression: KtSimpleNameExpression) : QualifierReceiver(referenceExpression) {
|
||||
@@ -143,9 +135,6 @@ class ClassQualifier(
|
||||
return ChainedScope("Static scope for $name as class or object", *scopes.toTypedArray())
|
||||
}
|
||||
|
||||
fun getClassObjectReceiver(): ReceiverValue =
|
||||
classifier.classObjectType?.let { ExpressionReceiver(referenceExpression, it) } ?: ReceiverValue.NO_RECEIVER
|
||||
|
||||
override fun toString() = "Class{$classifier}"
|
||||
}
|
||||
|
||||
@@ -157,5 +146,8 @@ fun createClassifierQualifier(
|
||||
val companionObjectReceiver = (classifier as? ClassDescriptor)?.companionObjectType?.let {
|
||||
ExpressionReceiver.create(referenceExpression, it, bindingContext)
|
||||
}
|
||||
return ClassQualifier(referenceExpression, classifier, companionObjectReceiver)
|
||||
return if (classifier is ClassDescriptor)
|
||||
ClassQualifier(referenceExpression, classifier, companionObjectReceiver)
|
||||
else
|
||||
ClassifierQualifierWithEmptyScope(referenceExpression, classifier)
|
||||
}
|
||||
@@ -73,21 +73,24 @@ public val ClassDescriptor.classId: ClassId
|
||||
|
||||
public val ClassDescriptor.hasCompanionObject: Boolean get() = companionObjectType != null
|
||||
|
||||
public val ClassDescriptor.classValueDescriptor: ClassDescriptor?
|
||||
get() = if (kind.isSingleton) this else companionObjectDescriptor
|
||||
|
||||
public val ClassDescriptor.classValueTypeDescriptor: ClassDescriptor?
|
||||
get() = when (kind) {
|
||||
OBJECT -> this
|
||||
ENUM_ENTRY -> {
|
||||
// enum entry has the type of enum class
|
||||
val container = this.containingDeclaration
|
||||
assert(container is ClassDescriptor && container.getKind() == ENUM_CLASS)
|
||||
container as ClassDescriptor
|
||||
}
|
||||
else -> companionObjectDescriptor
|
||||
}
|
||||
|
||||
/** If a literal of this class can be used as a value, returns the type of this value */
|
||||
public val ClassDescriptor.companionObjectType: KotlinType?
|
||||
get() {
|
||||
val correspondingDescriptor = when (this.getKind()) {
|
||||
OBJECT -> this
|
||||
// enum entry has the type of enum class
|
||||
ENUM_ENTRY -> {
|
||||
val container = this.getContainingDeclaration()
|
||||
assert(container is ClassDescriptor && container.getKind() == ENUM_CLASS)
|
||||
container as ClassDescriptor
|
||||
}
|
||||
else -> getCompanionObjectDescriptor()
|
||||
}
|
||||
return correspondingDescriptor?.getDefaultType()
|
||||
}
|
||||
get() = classValueTypeDescriptor?.getDefaultType()
|
||||
|
||||
public val DeclarationDescriptorWithVisibility.isEffectivelyPublicApi: Boolean
|
||||
get() {
|
||||
|
||||
@@ -28,9 +28,11 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.companionObjectType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.supertypesWithAny
|
||||
@@ -247,8 +249,13 @@ public fun CallTypeAndReceiver<*, *>.receiverTypes(
|
||||
}
|
||||
|
||||
val receiverValues = if (receiverExpression != null) {
|
||||
val expressionType = bindingContext.getType(receiverExpression)
|
||||
expressionType?.let { listOf(ExpressionReceiver.create(receiverExpression, expressionType, bindingContext)) } ?: return emptyList()
|
||||
val receiverType =
|
||||
bindingContext.getType(receiverExpression) ?:
|
||||
(bindingContext.get(BindingContext.QUALIFIER, receiverExpression) as? ClassQualifier)?.let {
|
||||
it.classifier.companionObjectType
|
||||
} ?:
|
||||
return emptyList()
|
||||
listOf(ExpressionReceiver.create(receiverExpression, receiverType, bindingContext))
|
||||
}
|
||||
else {
|
||||
val resolutionScope = contextElement.getResolutionScope(bindingContext, resolutionFacade)
|
||||
|
||||
+8
-3
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.companionObjectType
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
|
||||
@@ -111,11 +112,15 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
|
||||
receiver is Qualifier -> {
|
||||
val qualifierType = context.getType(receiver.expression)
|
||||
if (qualifierType != null) return TypeInfo(qualifierType, Variance.IN_VARIANCE)
|
||||
|
||||
if (receiver !is ClassQualifier) return null
|
||||
val classifier = receiver.classifier as? JavaClassDescriptor ?: return null
|
||||
val javaClass = DescriptorToSourceUtilsIde.getAnyDeclaration(project, classifier) as? PsiClass
|
||||
val classifierType = receiver.classifier.companionObjectType
|
||||
if (classifierType != null) return TypeInfo(classifierType, Variance.IN_VARIANCE)
|
||||
|
||||
val javaClassifier = receiver.classifier as? JavaClassDescriptor ?: return null
|
||||
val javaClass = DescriptorToSourceUtilsIde.getAnyDeclaration(project, javaClassifier) as? PsiClass
|
||||
if (javaClass == null || !javaClass.canRefactor()) return null
|
||||
TypeInfo.StaticContextRequired(TypeInfo(classifier.defaultType, Variance.IN_VARIANCE))
|
||||
TypeInfo.StaticContextRequired(TypeInfo(javaClassifier.defaultType, Variance.IN_VARIANCE))
|
||||
}
|
||||
receiver is ReceiverValue -> TypeInfo(receiver.type, Variance.IN_VARIANCE)
|
||||
else -> throw AssertionError("Unexpected receiver: $receiver")
|
||||
|
||||
Reference in New Issue
Block a user