Use Visibilities.isVisible with ReceiverValue.

This commit is contained in:
Stanislav Erokhin
2014-10-16 16:30:13 +04:00
parent f640f82ed0
commit f9afdf7540
18 changed files with 305 additions and 13 deletions
@@ -53,6 +53,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage;
import org.jetbrains.jet.lang.resolve.calls.TailRecursionKind;
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
@@ -414,8 +415,16 @@ public class JetFlowInformationProvider {
if (variableDescriptor.isVar() && variableDescriptor instanceof PropertyDescriptor) {
DeclarationDescriptor descriptor = BindingContextUtils.getEnclosingDescriptor(trace.getBindingContext(), expression);
PropertySetterDescriptor setterDescriptor = ((PropertyDescriptor) variableDescriptor).getSetter();
if (Visibilities.isVisible(variableDescriptor, descriptor) && setterDescriptor != null
&& !Visibilities.isVisible(setterDescriptor, descriptor)) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilPackage.getResolvedCall(expression, trace.getBindingContext());
ReceiverValue receiverValue = ReceiverValue.IRRELEVANT_RECEIVER;
if (resolvedCall != null) {
receiverValue = ExpressionTypingUtils
.normalizeReceiverValueForVisibility(resolvedCall.getDispatchReceiver(), trace.getBindingContext());
}
if (Visibilities.isVisible(receiverValue, variableDescriptor, descriptor) && setterDescriptor != null
&& !Visibilities.isVisible(receiverValue, setterDescriptor, descriptor)) {
report(Errors.INVISIBLE_SETTER.on(expression, variableDescriptor, setterDescriptor.getVisibility(),
variableDescriptor.getContainingDeclaration()), ctxt);
return true;
@@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -821,7 +822,7 @@ public class OverrideResolver {
all.addAll((Collection) supertype.getMemberScope().getProperties(declared.getName()));
for (CallableMemberDescriptor fromSuper : all) {
if (OverridingUtil.DEFAULT.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) {
if (Visibilities.isVisible(fromSuper, declared)) {
if (Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSuper, declared)) {
throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
" and visible but does not appear in its getOverriddenDescriptors()");
}
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import java.util.Collection;
import java.util.Collections;
@@ -457,7 +458,7 @@ public class QualifiedExpressionResolver {
@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope scopeToCheckVisibility
) {
if (!Visibilities.isVisible(descriptor, scopeToCheckVisibility.getContainingDeclaration())) {
if (!Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, scopeToCheckVisibility.getContainingDeclaration())) {
//noinspection ConstantConditions
trace.report(INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.getVisibility(),
descriptor.getContainingDeclaration()));
@@ -91,8 +91,9 @@ public class CandidateResolver {
}
ReceiverValue receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(), context.trace.getBindingContext());
DeclarationDescriptorWithVisibility invisibleMember =
Visibilities.findInvisibleMember(ReceiverValue.IRRELEVANT_RECEIVER, candidate, context.scope.getContainingDeclaration());
Visibilities.findInvisibleMember(receiverValue, candidate, context.scope.getContainingDeclaration());
if (invisibleMember != null) {
candidateCall.addStatus(OTHER_ERROR);
context.tracing.invisibleMember(context.trace, invisibleMember);
@@ -413,7 +413,8 @@ public class TaskPrioritizer(private val storageManager: StorageManager) {
if (call == null) return false
val candidateDescriptor = call.getDescriptor()
if (ErrorUtils.isError(candidateDescriptor)) return true
return Visibilities.isVisible(candidateDescriptor, context.scope.getContainingDeclaration())
val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(call.getDispatchReceiver(), context.trace.getBindingContext())
return Visibilities.isVisible(receiverValue, candidateDescriptor, context.scope.getContainingDeclaration())
}
private fun isSynthesized(call: ResolutionCandidate<D>): Boolean {
@@ -41,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.ErrorUtils;
@@ -77,6 +78,28 @@ public class ExpressionTypingUtils {
this.builtIns = builtIns;
}
@NotNull
public static ReceiverValue normalizeReceiverValueForVisibility(@NotNull ReceiverValue receiverValue, @NotNull BindingContext trace) {
if (receiverValue instanceof ExpressionReceiver) {
JetExpression expression = ((ExpressionReceiver) receiverValue).getExpression();
JetReferenceExpression referenceExpression = null;
if (expression instanceof JetThisExpression) {
referenceExpression = ((JetThisExpression) expression).getInstanceReference();
}
else if (expression instanceof JetThisReferenceExpression) {
referenceExpression = (JetReferenceExpression) 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
protected static ExpressionReceiver getExpressionReceiver(@NotNull JetExpression expression, @Nullable JetType type) {
if (type == null) return null;