Moved logic for PRIVATE_TO_THIS visibility from ExpressionTypingUtils.normalizeReceiverValueForVisibility to ExpressionReceiver.create

This commit is contained in:
Stanislav Erokhin
2015-11-16 17:40:19 +03:00
parent 6b7bf63814
commit c7f7ba72b8
7 changed files with 37 additions and 43 deletions
@@ -420,8 +420,7 @@ public class JetFlowInformationProvider {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(expression, trace.getBindingContext()); ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(expression, trace.getBindingContext());
ReceiverValue receiverValue = ReceiverValue.IRRELEVANT_RECEIVER; ReceiverValue receiverValue = ReceiverValue.IRRELEVANT_RECEIVER;
if (resolvedCall != null) { if (resolvedCall != null) {
receiverValue = ExpressionTypingUtils receiverValue = resolvedCall.getDispatchReceiver();
.normalizeReceiverValueForVisibility(resolvedCall.getDispatchReceiver(), trace.getBindingContext());
} }
if (Visibilities.isVisible(receiverValue, variableDescriptor, descriptor) && setterDescriptor != null if (Visibilities.isVisible(receiverValue, variableDescriptor, descriptor) && setterDescriptor != null
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.noExpectedType import org.jetbrains.kotlin.types.TypeUtils.noExpectedType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import java.util.* import java.util.*
public class CandidateResolver( public class CandidateResolver(
@@ -169,9 +168,7 @@ public class CandidateResolver(
} }
private fun CallCandidateResolutionContext<*>.checkVisibility() = checkAndReport { private fun CallCandidateResolutionContext<*>.checkVisibility() = checkAndReport {
val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(), val invisibleMember = Visibilities.findInvisibleMember(candidateCall.dispatchReceiver, candidateDescriptor, scope.ownerDescriptor)
trace.getBindingContext())
val invisibleMember = Visibilities.findInvisibleMember(receiverValue, candidateDescriptor, scope.ownerDescriptor)
if (invisibleMember != null) { if (invisibleMember != null) {
tracing.invisibleMember(trace, invisibleMember) tracing.invisibleMember(trace, invisibleMember)
OTHER_ERROR OTHER_ERROR
@@ -235,7 +235,7 @@ public class TaskPrioritizer(
val dispatchReceiver = val dispatchReceiver =
if (explicitReceiver.value is ClassReceiver && type != explicitReceiver.value.type) { if (explicitReceiver.value is ClassReceiver && type != explicitReceiver.value.type) {
CastClassReceiver(explicitReceiver.value.declarationDescriptor, type) CastClassReceiver(explicitReceiver.value.classDescriptor, type)
} }
else { else {
explicitReceiver.value explicitReceiver.value
@@ -485,8 +485,7 @@ public class TaskPrioritizer(
if (candidate == null) return false if (candidate == null) return false
val candidateDescriptor = candidate.getDescriptor() val candidateDescriptor = candidate.getDescriptor()
if (ErrorUtils.isError(candidateDescriptor)) return true if (ErrorUtils.isError(candidateDescriptor)) return true
val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidate.getDispatchReceiver(), context.trace.getBindingContext()) return Visibilities.isVisible(candidate.dispatchReceiver, candidateDescriptor, context.scope.ownerDescriptor)
return Visibilities.isVisible(receiverValue, candidateDescriptor, context.scope.ownerDescriptor)
} }
private fun hasLowPriority(candidate: ResolutionCandidate<D>?): Boolean { private fun hasLowPriority(candidate: ResolutionCandidate<D>?): Boolean {
@@ -16,7 +16,11 @@
package org.jetbrains.kotlin.resolve.scopes.receivers package org.jetbrains.kotlin.resolve.scopes.receivers
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtReferenceExpression
import org.jetbrains.kotlin.psi.KtThisExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
@@ -24,17 +28,38 @@ interface ExpressionReceiver : ReceiverValue {
val expression: KtExpression val expression: KtExpression
companion object { companion object {
class ExpressionReceiverImpl( open class ExpressionReceiverImpl(
override val expression: KtExpression, type: KotlinType override val expression: KtExpression, type: KotlinType
): AbstractReceiverValue(type), ExpressionReceiver { ): AbstractReceiverValue(type), ExpressionReceiver {
override fun toString() = "$type {$expression: ${expression.text}}" override fun toString() = "$type {$expression: ${expression.text}}"
} }
private class ThisExpressionClassReceiver(
override val classDescriptor: ClassDescriptor,
expression: KtExpression,
type: KotlinType
) : ExpressionReceiverImpl(expression, type), ExpressionOrImplicitClassReceiver
fun create( fun create(
expression: KtExpression, expression: KtExpression,
type: KotlinType, type: KotlinType,
bindingContext: BindingContext bindingContext: BindingContext
): ExpressionReceiver { ): ExpressionReceiver {
var referenceExpression: KtReferenceExpression? = null
if (expression is KtThisExpression) {
referenceExpression = expression.instanceReference
}
else if (expression is KtConstructorDelegationReferenceExpression) { // todo check this
referenceExpression = expression
}
if (referenceExpression != null) {
val descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression)
if (descriptor is ClassDescriptor) {
return ThisExpressionClassReceiver(descriptor.original as ClassDescriptor, expression, type)
}
}
return ExpressionReceiverImpl(expression, type) return ExpressionReceiverImpl(expression, type)
} }
} }
@@ -31,12 +31,13 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*; import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.ObservableBindingTrace;
import org.jetbrains.kotlin.resolve.TraceBasedRedeclarationHandler;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope; import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt; import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt; import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
@@ -49,28 +50,6 @@ import static org.jetbrains.kotlin.resolve.BindingContext.PROCESSED;
public class ExpressionTypingUtils { public class ExpressionTypingUtils {
@NotNull
public static ReceiverValue normalizeReceiverValueForVisibility(@NotNull ReceiverValue receiverValue, @NotNull BindingContext trace) {
if (receiverValue instanceof ExpressionReceiver) {
KtExpression expression = ((ExpressionReceiver) receiverValue).getExpression();
KtReferenceExpression referenceExpression = null;
if (expression instanceof KtThisExpression) {
referenceExpression = ((KtThisExpression) expression).getInstanceReference();
}
else if (expression instanceof KtConstructorDelegationReferenceExpression) {
referenceExpression = (KtReferenceExpression) expression;
}
if (referenceExpression != null) {
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, referenceExpression);
if (descriptor instanceof ClassDescriptor) {
return new ClassReceiver((ClassDescriptor) descriptor.getOriginal());
}
}
}
return receiverValue;
}
@Nullable @Nullable
public static ExpressionReceiver getExpressionReceiver( public static ExpressionReceiver getExpressionReceiver(
@NotNull ExpressionTypingFacade facade, @NotNull ExpressionTypingFacade facade,
@@ -44,7 +44,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import java.util.* import java.util.*
@@ -136,8 +135,7 @@ public fun Call.resolveCandidates(
if (filterOutByVisibility) { if (filterOutByVisibility) {
candidates = candidates.filter { candidates = candidates.filter {
val thisReceiver = ExpressionTypingUtils.normalizeReceiverValueForVisibility(it.dispatchReceiver, bindingContext) Visibilities.isVisible(it.dispatchReceiver, it.resultingDescriptor, inDescriptor)
Visibilities.isVisible(thisReceiver, it.resultingDescriptor, inDescriptor)
} }
} }
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
fun DeclarationDescriptorWithVisibility.isVisible( fun DeclarationDescriptorWithVisibility.isVisible(
from: DeclarationDescriptor, from: DeclarationDescriptor,
@@ -47,15 +46,13 @@ fun DeclarationDescriptorWithVisibility.isVisible(
val explicitReceiver = type?.let { ExpressionReceiver.create(receiver!!, it, bindingContext) } val explicitReceiver = type?.let { ExpressionReceiver.create(receiver!!, it, bindingContext) }
if (explicitReceiver != null) { if (explicitReceiver != null) {
val normalizeReceiver = ExpressionTypingUtils.normalizeReceiverValueForVisibility(explicitReceiver, bindingContext) return Visibilities.isVisible(explicitReceiver, this, from)
return Visibilities.isVisible(normalizeReceiver, this, from)
} }
val resolutionScope = element.getResolutionScope(bindingContext, element.getResolutionFacade()) val resolutionScope = element.getResolutionScope(bindingContext, element.getResolutionFacade())
val implicitReceivers = resolutionScope.getImplicitReceiversHierarchy() val implicitReceivers = resolutionScope.getImplicitReceiversHierarchy()
for (implicitReceiver in implicitReceivers) { for (implicitReceiver in implicitReceivers) {
val normalizeReceiver = ExpressionTypingUtils.normalizeReceiverValueForVisibility(implicitReceiver.getValue(), bindingContext) if (Visibilities.isVisible(implicitReceiver.value, this, from)) return true
if (Visibilities.isVisible(normalizeReceiver, this, from)) return true
} }
return false return false
} }