Minor. Remove class ClassifierQualifier and create special ClassValueReceiver

This commit is contained in:
Stanislav Erokhin
2016-02-22 19:10:12 +03:00
parent 2f0ae6f176
commit 8c5339cccf
8 changed files with 68 additions and 74 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,9 +22,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classValueDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueTypeDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.hasCompanionObject
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassifierQualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.PackageQualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.TypeParameterQualifier
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
@@ -73,8 +73,8 @@ private fun resolveQualifierReferenceTarget(
context: ExpressionTypingContext,
symbolUsageValidator: SymbolUsageValidator
): DeclarationDescriptor {
if (qualifier is ClassifierQualifier && qualifier.classifier is TypeParameterDescriptor) {
return qualifier.classifier
if (qualifier is TypeParameterQualifier) {
return qualifier.descriptor
}
val selectorContainer = when (selector) {
@@ -93,7 +93,7 @@ private fun resolveQualifierReferenceTarget(
// TODO make decisions about short reference to companion object somewhere else
if (qualifier is ClassQualifier) {
val classifier = qualifier.classifier
val classifier = qualifier.descriptor
val selectorIsCallable = selector is CallableDescriptor &&
(selector.dispatchReceiverParameter != null || selector.extensionReceiverParameter != null)
// TODO simplify this code.
@@ -583,7 +583,8 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
val qualifier =
when (descriptor) {
is PackageViewDescriptor -> PackageQualifier(referenceExpression, descriptor)
is ClassifierDescriptor -> createClassifierQualifier(referenceExpression, descriptor, trace.bindingContext)
is ClassDescriptor -> ClassQualifier(referenceExpression, descriptor)
is TypeParameterDescriptor -> TypeParameterQualifier(referenceExpression, descriptor)
else -> return null
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,17 +20,26 @@ import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.bindingContextUtil.*
import org.jetbrains.kotlin.resolve.calls.callUtil.*
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordDataFlowInfo
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.NAME_NOT_FOUND
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
@@ -43,21 +52,15 @@ import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.*
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
import javax.inject.Inject
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.NAME_NOT_FOUND
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
class CallExpressionResolver(
private val callResolver: CallResolver,
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
@@ -481,7 +484,7 @@ class CallExpressionResolver(
assert(expressionQualifier is ClassQualifier) { "Only class can (package cannot) be accessed by instance reference: " + expressionQualifier }
context.trace.report(NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE.on(
selectorExpression,
(expressionQualifier as ClassQualifier).classifier))
(expressionQualifier as ClassQualifier).descriptor))
}
}
}
@@ -16,16 +16,19 @@
package org.jetbrains.kotlin.resolve.scopes.receivers
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope
import org.jetbrains.kotlin.resolve.scopes.FilteringScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.ScopeUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
@@ -65,79 +68,66 @@ class PackageQualifier(
override fun toString() = "Package{$packageView}"
}
abstract class ClassifierQualifier(referenceExpression: KtSimpleNameExpression) : QualifierReceiver(referenceExpression) {
abstract val classifier: ClassifierDescriptor
override val descriptor: DeclarationDescriptor
get() = classifier
}
class ClassifierQualifierWithEmptyScope(
class TypeParameterQualifier(
referenceExpression: KtSimpleNameExpression,
override val classifier: ClassifierDescriptor
) : ClassifierQualifier(referenceExpression) {
override val descriptor: DeclarationDescriptor
) : QualifierReceiver(referenceExpression) {
override fun getNestedClassesAndPackageMembersScope(): MemberScope = MemberScope.Empty
override val scope: MemberScope = MemberScope.Empty
override val scope: MemberScope get() = MemberScope.Empty
}
class ClassQualifier(
referenceExpression: KtSimpleNameExpression,
override val classifier: ClassDescriptor,
val classValueReceiver: ReceiverValue?
) : ClassifierQualifier(referenceExpression) {
override val descriptor: ClassDescriptor
) : QualifierReceiver(referenceExpression) {
val classValueReceiver: ClassValueReceiver? = descriptor.classValueType?.let {
ClassValueReceiver(this, it)
}
override val scope: MemberScope get() {
if (classifier !is ClassDescriptor) {
if (descriptor !is ClassDescriptor) {
return MemberScope.Empty
}
val scopes = ArrayList<MemberScope>(3)
val classObjectTypeScope = classifier.classValueType?.memberScope?.let {
val classObjectTypeScope = descriptor.classValueType?.memberScope?.let {
FilteringScope(it) { it !is ClassDescriptor }
}
scopes.addIfNotNull(classObjectTypeScope)
scopes.add(classifier.staticScope)
scopes.add(descriptor.staticScope)
if (classifier.kind != ClassKind.ENUM_ENTRY) {
scopes.add(classifier.unsubstitutedInnerClassesScope)
if (descriptor.kind != ClassKind.ENUM_ENTRY) {
scopes.add(descriptor.unsubstitutedInnerClassesScope)
}
return ChainedMemberScope("Member scope for ${classifier.name} as class or object", scopes)
return ChainedMemberScope("Member scope for ${descriptor.name} as class or object", scopes)
}
override fun getNestedClassesAndPackageMembersScope(): MemberScope {
if (classifier !is ClassDescriptor) {
if (descriptor !is ClassDescriptor) {
return MemberScope.Empty
}
val scopes = ArrayList<MemberScope>(2)
scopes.add(classifier.staticScope)
scopes.add(descriptor.staticScope)
if (classifier.kind != ClassKind.ENUM_ENTRY) {
scopes.add(ScopeUtils.getStaticNestedClassesScope(classifier))
if (descriptor.kind != ClassKind.ENUM_ENTRY) {
scopes.add(ScopeUtils.getStaticNestedClassesScope(descriptor))
}
return ChainedMemberScope("Static scope for ${classifier.name} as class or object", scopes)
return ChainedMemberScope("Static scope for ${descriptor.name} as class or object", scopes)
}
override fun toString() = "Class{$classifier}"
override fun toString() = "Class{$descriptor}"
}
fun createClassifierQualifier(
referenceExpression: KtSimpleNameExpression,
classifier: ClassifierDescriptor,
bindingContext: BindingContext
): ClassifierQualifier {
val companionObjectReceiver = (classifier as? ClassDescriptor)?.classValueType?.let {
ExpressionReceiver.create(referenceExpression, it, bindingContext)
}
return if (classifier is ClassDescriptor)
ClassQualifier(referenceExpression, classifier, companionObjectReceiver)
else
ClassifierQualifierWithEmptyScope(referenceExpression, classifier)
class ClassValueReceiver(val classQualifier: ClassQualifier, private val type: KotlinType) : ExpressionReceiver {
override fun getType() = type
override val expression: KtExpression
get() = classQualifier.expression
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -252,7 +252,7 @@ fun CallTypeAndReceiver<*, *>.receiverTypes(
val receiverType =
bindingContext.getType(receiverExpression) ?:
(bindingContext.get(BindingContext.QUALIFIER, receiverExpression) as? ClassQualifier)?.let {
it.classifier.classValueType
it.descriptor.classValueType
} ?:
return emptyList()
listOf(ExpressionReceiver.create(receiverExpression, receiverType, bindingContext))
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -85,7 +85,7 @@ public class CodeInsightUtils {
Qualifier qualifier = context.get(BindingContext.QUALIFIER, expression);
if (qualifier != null) {
if (!(qualifier instanceof ClassQualifier)) return null;
ClassifierDescriptor classifier = ((ClassQualifier) qualifier).getClassifier();
ClassifierDescriptor classifier = ((ClassQualifier) qualifier).getDescriptor();
if (!(classifier instanceof ClassDescriptor) || ((ClassDescriptor) classifier).getKind() != ClassKind.OBJECT) {
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.conversion.copy.range
@@ -33,7 +32,7 @@ import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassifierQualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
class ImportAllMembersIntention : SelfTargetingIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
@@ -73,8 +72,9 @@ class ImportAllMembersIntention : SelfTargetingIntention<KtDotQualifiedExpressio
private fun target(expression: KtDotQualifiedExpression): DeclarationDescriptor? {
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL)
val qualifier = bindingContext[BindingContext.QUALIFIER, expression.receiverExpression] as? ClassifierQualifier ?: return null
if (qualifier.descriptor !is ClassDescriptor) return null
if (bindingContext[BindingContext.QUALIFIER, expression.receiverExpression] !is ClassQualifier) {
return null
}
val selector = expression.getQualifiedElementSelector() as? KtNameReferenceExpression ?: return null
return selector.mainReference.resolveToDescriptors(bindingContext).firstOrNull()
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.refactoring.canRefactor
import org.jetbrains.kotlin.idea.refactoring.getExtractionContainers
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.psi.*
@@ -115,10 +115,10 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
if (qualifierType != null) return TypeInfo(qualifierType, Variance.IN_VARIANCE)
if (receiver !is ClassQualifier) return null
val classifierType = receiver.classifier.classValueType
val classifierType = receiver.descriptor.classValueType
if (classifierType != null) return TypeInfo(classifierType, Variance.IN_VARIANCE)
val javaClassifier = receiver.classifier as? JavaClassDescriptor ?: return null
val javaClassifier = receiver.descriptor as? JavaClassDescriptor ?: return null
val javaClass = DescriptorToSourceUtilsIde.getAnyDeclaration(project, javaClassifier) as? PsiClass
if (javaClass == null || !javaClass.canRefactor()) return null
TypeInfo.StaticContextRequired(TypeInfo(javaClassifier.defaultType, Variance.IN_VARIANCE))