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:
Dmitry Petrov
2015-11-16 19:29:24 +03:00
parent 9856af48ca
commit ba8372cc11
8 changed files with 55 additions and 54 deletions
@@ -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;
@@ -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)
}