Drop createQualifier.
NB: some regression in diagnostics for special cases, such as class or package used in expression position or in safe access; see next commit.
This commit is contained in:
+40
-47
@@ -23,65 +23,54 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassObjectType
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassifierQualifier
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassifierQualifier
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.PackageQualifier
|
import org.jetbrains.kotlin.resolve.scopes.receivers.PackageQualifier
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier
|
||||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||||
|
|
||||||
|
|
||||||
public fun resolveAsReceiverInQualifiedExpression(
|
public fun resolveQualifierAsReceiverInExpression(
|
||||||
qualifier: QualifierReceiver,
|
qualifier: Qualifier,
|
||||||
context: ExpressionTypingContext,
|
|
||||||
selector: DeclarationDescriptor?,
|
selector: DeclarationDescriptor?,
|
||||||
symbolUsageValidator: SymbolUsageValidator
|
|
||||||
) {
|
|
||||||
resolveAndRecordReferenceTarget(qualifier, context, selector, symbolUsageValidator)
|
|
||||||
|
|
||||||
if (qualifier is ClassifierQualifier) {
|
|
||||||
val classifier = qualifier.classifier
|
|
||||||
if (classifier is TypeParameterDescriptor) {
|
|
||||||
context.trace.report(Errors.TYPE_PARAMETER_ON_LHS_OF_DOT.on(qualifier.referenceExpression, classifier))
|
|
||||||
}
|
|
||||||
else if (classifier is ClassDescriptor && classifier.hasClassObjectType) {
|
|
||||||
context.trace.recordType(qualifier.expression, classifier.classObjectType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun resolveAsStandaloneExpression(
|
|
||||||
qualifier: QualifierReceiver,
|
|
||||||
context: ExpressionTypingContext,
|
context: ExpressionTypingContext,
|
||||||
symbolUsageValidator: SymbolUsageValidator
|
symbolUsageValidator: SymbolUsageValidator
|
||||||
) {
|
): DeclarationDescriptor {
|
||||||
resolveAndRecordReferenceTarget(qualifier, context, selector = null, symbolUsageValidator = symbolUsageValidator)
|
val referenceTarget = resolveQualifierReferenceTarget(qualifier, selector, context, symbolUsageValidator)
|
||||||
|
|
||||||
if (qualifier is ClassifierQualifier) {
|
if (referenceTarget is TypeParameterDescriptor) {
|
||||||
val classifier = qualifier.classifier
|
context.trace.report(Errors.TYPE_PARAMETER_ON_LHS_OF_DOT.on(qualifier.referenceExpression, referenceTarget))
|
||||||
if (classifier is TypeParameterDescriptor) {
|
|
||||||
context.trace.report(Errors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(qualifier.referenceExpression, classifier))
|
|
||||||
}
|
|
||||||
else if (classifier is ClassDescriptor && !classifier.hasClassObjectType) {
|
|
||||||
context.trace.report(Errors.NO_COMPANION_OBJECT.on(qualifier.referenceExpression, classifier))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (qualifier is PackageQualifier) {
|
|
||||||
context.trace.report(Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND.on(qualifier.referenceExpression))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return referenceTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveAndRecordReferenceTarget(
|
public fun resolveQualifierAsStandaloneExpression(
|
||||||
qualifier: QualifierReceiver,
|
qualifier: Qualifier,
|
||||||
context: ExpressionTypingContext,
|
context: ExpressionTypingContext,
|
||||||
selector: DeclarationDescriptor?,
|
|
||||||
symbolUsageValidator: SymbolUsageValidator
|
symbolUsageValidator: SymbolUsageValidator
|
||||||
) {
|
): DeclarationDescriptor {
|
||||||
val resultingDescriptor = resolveReferenceTarget(qualifier, context, selector, symbolUsageValidator)
|
val referenceTarget = resolveQualifierReferenceTarget(qualifier, null, context, symbolUsageValidator)
|
||||||
context.trace.record(BindingContext.REFERENCE_TARGET, qualifier.referenceExpression, resultingDescriptor)
|
|
||||||
|
when (referenceTarget) {
|
||||||
|
is TypeParameterDescriptor -> {
|
||||||
|
context.trace.report(Errors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(qualifier.referenceExpression, referenceTarget))
|
||||||
|
}
|
||||||
|
is ClassDescriptor -> {
|
||||||
|
if (!referenceTarget.kind.isSingleton) {
|
||||||
|
context.trace.report(Errors.NO_COMPANION_OBJECT.on(qualifier.referenceExpression, referenceTarget))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is PackageViewDescriptor -> {
|
||||||
|
context.trace.report(Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND.on(qualifier.referenceExpression))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return referenceTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveReferenceTarget(
|
private fun resolveQualifierReferenceTarget(
|
||||||
qualifier: QualifierReceiver,
|
qualifier: Qualifier,
|
||||||
context: ExpressionTypingContext,
|
|
||||||
selector: DeclarationDescriptor?,
|
selector: DeclarationDescriptor?,
|
||||||
|
context: ExpressionTypingContext,
|
||||||
symbolUsageValidator: SymbolUsageValidator
|
symbolUsageValidator: SymbolUsageValidator
|
||||||
): DeclarationDescriptor {
|
): DeclarationDescriptor {
|
||||||
if (qualifier is ClassifierQualifier && qualifier.classifier is TypeParameterDescriptor) {
|
if (qualifier is ClassifierQualifier && qualifier.classifier is TypeParameterDescriptor) {
|
||||||
@@ -102,15 +91,19 @@ private fun resolveReferenceTarget(
|
|||||||
return qualifier.packageView
|
return qualifier.packageView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO make decisions about short reference to companion object somewhere else
|
||||||
if (qualifier is ClassQualifier) {
|
if (qualifier is ClassQualifier) {
|
||||||
|
val classifier = qualifier.classifier
|
||||||
if (selector is CallableDescriptor &&
|
if (selector is CallableDescriptor &&
|
||||||
(selector.dispatchReceiverParameter != null || selector.extensionReceiverParameter != null) &&
|
(selector.dispatchReceiverParameter != null || selector.extensionReceiverParameter != null) &&
|
||||||
qualifier.classifier is ClassDescriptor &&
|
classifier is ClassDescriptor &&
|
||||||
qualifier.classifier.hasClassObjectType
|
classifier.hasClassObjectType
|
||||||
) {
|
) {
|
||||||
val companionObjectDescriptor = qualifier.classifier.companionObjectDescriptor
|
val companionObjectDescriptor = classifier.companionObjectDescriptor
|
||||||
if (companionObjectDescriptor != null) {
|
if (companionObjectDescriptor != null) {
|
||||||
context.trace.record(BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, qualifier.referenceExpression, qualifier.classifier)
|
context.trace.record(BindingContext.REFERENCE_TARGET, qualifier.referenceExpression, companionObjectDescriptor)
|
||||||
|
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)
|
symbolUsageValidator.validateTypeUsage(companionObjectDescriptor, context.trace, qualifier.referenceExpression)
|
||||||
return companionObjectDescriptor
|
return companionObjectDescriptor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,14 +28,11 @@ import org.jetbrains.kotlin.resolve.calls.unrollToLeftMostQualifiedExpression
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.PackageQualifier
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.utils.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.createClassifierQualifier
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
|
||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||||
|
|
||||||
@@ -392,6 +389,33 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
|||||||
return Pair(currentDescriptor, path.size)
|
return Pair(currentDescriptor, path.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun resolveNameExpressionAsQualifierForDiagnostics(
|
||||||
|
expression: KtSimpleNameExpression,
|
||||||
|
receiver: Receiver,
|
||||||
|
context: ExpressionTypingContext
|
||||||
|
): Qualifier? {
|
||||||
|
val name = expression.getReferencedNameAsName()
|
||||||
|
|
||||||
|
val qualifierDescriptor = when {
|
||||||
|
receiver is PackageQualifier -> {
|
||||||
|
val childPackageFQN = receiver.packageView.fqName.child(name)
|
||||||
|
val childPackageDescriptor = receiver.packageView.module.getPackage(childPackageFQN).check { !it.isEmpty() }
|
||||||
|
childPackageDescriptor ?: receiver.packageView.memberScope.getContributedClassifier(name, KotlinLookupLocation(expression))
|
||||||
|
}
|
||||||
|
receiver is ClassQualifier ->
|
||||||
|
receiver.scope.getContributedClassifier(name, KotlinLookupLocation(expression))
|
||||||
|
!receiver.exists() ->
|
||||||
|
context.scope.findClassifier(name, KotlinLookupLocation(expression)) ?:
|
||||||
|
context.scope.ownerDescriptor.module.getPackage(FqName.ROOT.child(name)).check { !it.isEmpty() }
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qualifierDescriptor != null) {
|
||||||
|
return storeResult(context.trace, expression, qualifierDescriptor, context.scope.ownerDescriptor, QualifierPosition.EXPRESSION)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
public fun resolveQualifierInExpressionAndUnroll(
|
public fun resolveQualifierInExpressionAndUnroll(
|
||||||
expression: KtQualifiedExpression,
|
expression: KtQualifiedExpression,
|
||||||
@@ -411,11 +435,11 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
|||||||
isValue = isValue
|
isValue = isValue
|
||||||
).second
|
).second
|
||||||
|
|
||||||
val firstExpressionAfterQualifierIndex =
|
val nextExpressionIndexAfterQualifier =
|
||||||
if (nextIndexAfterPrefix == 0) 0 else nextIndexAfterPrefix - 1
|
if (nextIndexAfterPrefix == 0) 0 else nextIndexAfterPrefix - 1
|
||||||
|
|
||||||
return qualifiedExpressions
|
return qualifiedExpressions
|
||||||
.subList(firstExpressionAfterQualifierIndex, qualifiedExpressions.size)
|
.subList(nextExpressionIndexAfterQualifier, qualifiedExpressions.size)
|
||||||
.map { CallExpressionElement(it) }
|
.map { CallExpressionElement(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,10 +544,10 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
|||||||
shouldBeVisibleFrom: DeclarationDescriptor?,
|
shouldBeVisibleFrom: DeclarationDescriptor?,
|
||||||
position: QualifierPosition,
|
position: QualifierPosition,
|
||||||
isQualifier: Boolean = true
|
isQualifier: Boolean = true
|
||||||
) {
|
): Qualifier? {
|
||||||
if (descriptor == null) {
|
if (descriptor == null) {
|
||||||
trace.report(Errors.UNRESOLVED_REFERENCE.on(referenceExpression, referenceExpression))
|
trace.report(Errors.UNRESOLVED_REFERENCE.on(referenceExpression, referenceExpression))
|
||||||
return
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptor)
|
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptor)
|
||||||
@@ -545,20 +569,20 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isQualifier) {
|
return if (isQualifier) storeQualifier(trace, referenceExpression, descriptor) else null
|
||||||
storeQualifier(trace, referenceExpression, descriptor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun storeQualifier(trace: BindingTrace, referenceExpression: KtSimpleNameExpression, descriptor: DeclarationDescriptor) {
|
private fun storeQualifier(trace: BindingTrace, referenceExpression: KtSimpleNameExpression, descriptor: DeclarationDescriptor): Qualifier? {
|
||||||
val qualifier =
|
val qualifier =
|
||||||
when (descriptor) {
|
when (descriptor) {
|
||||||
is PackageViewDescriptor -> PackageQualifier(referenceExpression, descriptor)
|
is PackageViewDescriptor -> PackageQualifier(referenceExpression, descriptor)
|
||||||
is ClassifierDescriptor -> createClassifierQualifier(referenceExpression, descriptor, trace.bindingContext)
|
is ClassifierDescriptor -> createClassifierQualifier(referenceExpression, descriptor, trace.bindingContext)
|
||||||
else -> return
|
else -> return null
|
||||||
}
|
}
|
||||||
|
|
||||||
trace.record(BindingContext.QUALIFIER, qualifier.expression, qualifier)
|
trace.record(BindingContext.QUALIFIER, qualifier.expression, qualifier)
|
||||||
|
|
||||||
|
return qualifier
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isVisible(
|
private fun isVisible(
|
||||||
|
|||||||
+23
-12
@@ -127,8 +127,9 @@ public class CallExpressionResolver {
|
|||||||
// if the expression is a receiver in a qualified expression, it should be resolved after the selector is resolved
|
// if the expression is a receiver in a qualified expression, it should be resolved after the selector is resolved
|
||||||
boolean isLHSOfDot = KtPsiUtil.isLHSOfDot(nameExpression);
|
boolean isLHSOfDot = KtPsiUtil.isLHSOfDot(nameExpression);
|
||||||
if (!resolutionResult.isNothing() && resolutionResult.getResultCode() != OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER) {
|
if (!resolutionResult.isNothing() && resolutionResult.getResultCode() != OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER) {
|
||||||
boolean isQualifier = isLHSOfDot && resolutionResult.isSingleResult()
|
boolean isQualifier = isLHSOfDot &&
|
||||||
&& resolutionResult.getResultingDescriptor() instanceof FakeCallableDescriptorForObject;
|
resolutionResult.isSingleResult() &&
|
||||||
|
resolutionResult.getResultingDescriptor() instanceof FakeCallableDescriptorForObject;
|
||||||
if (!isQualifier) {
|
if (!isQualifier) {
|
||||||
result[0] = true;
|
result[0] = true;
|
||||||
temporaryForVariable.commit();
|
temporaryForVariable.commit();
|
||||||
@@ -136,14 +137,13 @@ public class CallExpressionResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QualifierReceiver qualifier = QualifierKt.createQualifier(nameExpression, receiver, context);
|
//// Generate some diagnostics for qualifier in unexpected position
|
||||||
if (qualifier != null) {
|
//DeclarationDescriptor qualifierDescriptor =
|
||||||
result[0] = true;
|
// QualifiedExpressionResolveUtilKt.getQualifierDescriptorOrNull(nameExpression, receiver, context);
|
||||||
if (!isLHSOfDot) {
|
//if (qualifierDescriptor != null) {
|
||||||
QualifiedExpressionResolveUtilKt.resolveAsStandaloneExpression(qualifier, context, symbolUsageValidator);
|
// QualifiedExpressionResolveUtilKt.checkQualifierAsStandaloneExpression(qualifierDescriptor, nameExpression, context);
|
||||||
}
|
//}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
temporaryForVariable.commit();
|
temporaryForVariable.commit();
|
||||||
result[0] = !resolutionResult.isNothing();
|
result[0] = !resolutionResult.isNothing();
|
||||||
return resolutionResult.isSingleResult() ? resolutionResult.getResultingDescriptor().getReturnType() : null;
|
return resolutionResult.isSingleResult() ? resolutionResult.getResultingDescriptor().getReturnType() : null;
|
||||||
@@ -191,6 +191,15 @@ public class CallExpressionResolver {
|
|||||||
return TypeInfoFactoryKt.createTypeInfo(type, context);
|
return TypeInfoFactoryKt.createTypeInfo(type, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TemporaryTraceAndCache temporaryForQualifier = TemporaryTraceAndCache.create(context, "trace to resolve as qualifier", nameExpression);
|
||||||
|
ExpressionTypingContext contextForQualifier = context.replaceTraceAndCache(temporaryForQualifier);
|
||||||
|
Qualifier qualifier = qualifiedExpressionResolver.resolveNameExpressionAsQualifierForDiagnostics(nameExpression, receiver, contextForQualifier);
|
||||||
|
if (qualifier != null) {
|
||||||
|
QualifiedExpressionResolveUtilKt.resolveQualifierAsStandaloneExpression(qualifier, contextForQualifier, symbolUsageValidator);
|
||||||
|
temporaryForQualifier.commit();
|
||||||
|
return TypeInfoFactoryKt.createTypeInfo(null, context);
|
||||||
|
}
|
||||||
|
|
||||||
temporaryForVariable.commit();
|
temporaryForVariable.commit();
|
||||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||||
}
|
}
|
||||||
@@ -350,7 +359,9 @@ public class CallExpressionResolver {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !resolutionResult.isNothing();
|
OverloadResolutionResults.Code resultCode = resolutionResult.getResultCode();
|
||||||
|
return resultCode != OverloadResolutionResults.Code.NAME_NOT_FOUND &&
|
||||||
|
resultCode != OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
List<CallExpressionElement> elementChain =
|
List<CallExpressionElement> elementChain =
|
||||||
@@ -462,7 +473,7 @@ public class CallExpressionResolver {
|
|||||||
calleeExpression instanceof KtReferenceExpression
|
calleeExpression instanceof KtReferenceExpression
|
||||||
? context.trace.get(BindingContext.REFERENCE_TARGET, (KtReferenceExpression) calleeExpression) : null;
|
? context.trace.get(BindingContext.REFERENCE_TARGET, (KtReferenceExpression) calleeExpression) : null;
|
||||||
|
|
||||||
QualifiedExpressionResolveUtilKt.resolveAsReceiverInQualifiedExpression(qualifierReceiver, context, selectorDescriptor, symbolUsageValidator);
|
QualifiedExpressionResolveUtilKt.resolveQualifierAsReceiverInExpression(qualifierReceiver, selectorDescriptor, context, symbolUsageValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkNestedClassAccess(
|
private static void checkNestedClassAccess(
|
||||||
|
|||||||
+15
-4
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.tasks.collectors
|
package org.jetbrains.kotlin.resolve.calls.tasks.collectors
|
||||||
|
|
||||||
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -33,6 +34,7 @@ import org.jetbrains.kotlin.resolve.scopes.utils.*
|
|||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
public interface CallableDescriptorCollector<D : CallableDescriptor> {
|
public interface CallableDescriptorCollector<D : CallableDescriptor> {
|
||||||
|
|
||||||
@@ -165,7 +167,10 @@ private object FunctionCollector : CallableDescriptorCollector<FunctionDescripto
|
|||||||
|
|
||||||
private object VariableCollector : CallableDescriptorCollector<VariableDescriptor> {
|
private object VariableCollector : CallableDescriptorCollector<VariableDescriptor> {
|
||||||
override fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
override fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||||
return listOfNotNull(lexicalScope.findLocalVariable(name))
|
val result = SmartList<VariableDescriptor>()
|
||||||
|
result.addIfNotNull(lexicalScope.findLocalVariable(name))
|
||||||
|
result.addIfNotNull(getContributedFakeDescriptorForObject(lexicalScope, name, location))
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||||
@@ -179,7 +184,13 @@ private object VariableCollector : CallableDescriptorCollector<VariableDescripto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFakeDescriptorForObject(scope: HierarchicalScope, name: Name, location: LookupLocation): VariableDescriptor? {
|
private fun getContributedFakeDescriptorForObject(scope: LexicalScope, name: Name, location: LookupLocation): VariableDescriptor? {
|
||||||
|
val classifier = scope.getContributedClassifier(name, location)
|
||||||
|
if (classifier !is ClassDescriptor || !classifier.hasClassObjectType) return null
|
||||||
|
return FakeCallableDescriptorForObject(classifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findFakeDescriptorForObject(scope: HierarchicalScope, name: Name, location: LookupLocation): VariableDescriptor? {
|
||||||
val classifier = scope.findClassifier(name, location)
|
val classifier = scope.findClassifier(name, location)
|
||||||
if (classifier !is ClassDescriptor || !classifier.hasCompanionObject) return null
|
if (classifier !is ClassDescriptor || !classifier.hasCompanionObject) return null
|
||||||
|
|
||||||
@@ -188,14 +199,14 @@ private object VariableCollector : CallableDescriptorCollector<VariableDescripto
|
|||||||
|
|
||||||
override fun getNonExtensionsByName(scope: HierarchicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
override fun getNonExtensionsByName(scope: HierarchicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||||
val properties = scope.collectVariables(name, location).filter { it.extensionReceiverParameter == null }
|
val properties = scope.collectVariables(name, location).filter { it.extensionReceiverParameter == null }
|
||||||
val fakeDescriptor = getFakeDescriptorForObject(scope, name, location)
|
val fakeDescriptor = findFakeDescriptorForObject(scope, name, location)
|
||||||
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
|
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
override fun getMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||||
val memberScope = receiver.memberScope
|
val memberScope = receiver.memberScope
|
||||||
val properties = memberScope.getContributedVariables(name, location)
|
val properties = memberScope.getContributedVariables(name, location)
|
||||||
val fakeDescriptor = getFakeDescriptorForObject(memberScope.memberScopeAsImportingScope(), name, location)
|
val fakeDescriptor = findFakeDescriptorForObject(memberScope.memberScopeAsImportingScope(), name, location)
|
||||||
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
|
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,39 +149,6 @@ class ClassQualifier(
|
|||||||
override fun toString() = "Class{$classifier}"
|
override fun toString() = "Class{$classifier}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createQualifier(expression: KtSimpleNameExpression, receiver: Receiver, context: ExpressionTypingContext): QualifierReceiver? {
|
|
||||||
val receiverScope = when {
|
|
||||||
!receiver.exists() -> context.scope
|
|
||||||
receiver is QualifierReceiver -> receiver.scope.memberScopeAsImportingScope()
|
|
||||||
receiver is ReceiverValue -> receiver.type.memberScope.memberScopeAsImportingScope()
|
|
||||||
else -> throw IllegalArgumentException("Unexpected receiver kind: $receiver")
|
|
||||||
}
|
|
||||||
|
|
||||||
val name = expression.getReferencedNameAsName()
|
|
||||||
val packageViewDescriptor = receiverScope.findPackage(name)
|
|
||||||
val classifierDescriptor = receiverScope.findClassifier(name, KotlinLookupLocation(expression))
|
|
||||||
|
|
||||||
if (packageViewDescriptor == null && classifierDescriptor == null) return null
|
|
||||||
|
|
||||||
context.trace.recordScope(context.scope, expression)
|
|
||||||
|
|
||||||
val qualifier =
|
|
||||||
if (receiver is PackageQualifier) {
|
|
||||||
if (packageViewDescriptor != null)
|
|
||||||
PackageQualifier(expression, packageViewDescriptor)
|
|
||||||
else
|
|
||||||
createClassifierQualifier(expression, classifierDescriptor!!, context.trace.bindingContext)
|
|
||||||
else
|
|
||||||
if (classifierDescriptor != null)
|
|
||||||
createClassifierQualifier(expression, classifierDescriptor, context.trace.bindingContext)
|
|
||||||
else
|
|
||||||
PackageQualifier(expression, packageViewDescriptor!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
context.trace.record(QUALIFIER, qualifier.expression, qualifier)
|
|
||||||
return qualifier
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createClassifierQualifier(
|
fun createClassifierQualifier(
|
||||||
referenceExpression: KtSimpleNameExpression,
|
referenceExpression: KtSimpleNameExpression,
|
||||||
classifier: ClassifierDescriptor,
|
classifier: ClassifierDescriptor,
|
||||||
|
|||||||
Reference in New Issue
Block a user