Add receiver to Visibility#isVisible

This commit is contained in:
Stanislav Erokhin
2014-11-18 17:27:52 +03:00
parent d997a6cb35
commit b3f3b3946e
5 changed files with 44 additions and 18 deletions
@@ -93,7 +93,7 @@ public class CandidateResolver {
DeclarationDescriptorWithVisibility invisibleMember = DeclarationDescriptorWithVisibility invisibleMember =
Visibilities.findInvisibleMember(candidate, context.scope.getContainingDeclaration()); Visibilities.findInvisibleMember(ReceiverValue.IRRELEVANT_RECEIVER, candidate, context.scope.getContainingDeclaration());
if (invisibleMember != null) { if (invisibleMember != null) {
candidateCall.addStatus(OTHER_ERROR); candidateCall.addStatus(OTHER_ERROR);
context.tracing.invisibleMember(context.trace, invisibleMember); context.tracing.invisibleMember(context.trace, invisibleMember);
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
public class JavaVisibilities { public class JavaVisibilities {
private JavaVisibilities() { private JavaVisibilities() {
@@ -26,7 +27,7 @@ public class JavaVisibilities {
public static final Visibility PACKAGE_VISIBILITY = new Visibility("package", false) { public static final Visibility PACKAGE_VISIBILITY = new Visibility("package", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return areInSamePackage(what, from); return areInSamePackage(what, from);
} }
@@ -51,7 +52,7 @@ public class JavaVisibilities {
public static final Visibility PROTECTED_STATIC_VISIBILITY = new Visibility("protected_static", false) { public static final Visibility PROTECTED_STATIC_VISIBILITY = new Visibility("protected_static", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (areInSamePackage(what, from)) { if (areInSamePackage(what, from)) {
return true; return true;
} }
@@ -66,7 +67,7 @@ public class JavaVisibilities {
if (DescriptorUtils.isSubclass(fromClass, whatClass)) { if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
return true; return true;
} }
return isVisible(what, fromClass.getContainingDeclaration()); return isVisible(receiver, what, fromClass.getContainingDeclaration());
} }
@Override @Override
@@ -83,7 +84,7 @@ public class JavaVisibilities {
public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", false) { public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (areInSamePackage(what, from)) { if (areInSamePackage(what, from)) {
return true; return true;
} }
@@ -97,7 +98,7 @@ public class JavaVisibilities {
if (DescriptorUtils.isSubclass(fromClass, whatClass)) { if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
return true; return true;
} }
return isVisible(what, fromClass.getContainingDeclaration()); return isVisible(receiver, what, fromClass.getContainingDeclaration());
} }
@Override @Override
@@ -20,6 +20,7 @@ import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.utils.UtilsPackage; import org.jetbrains.jet.utils.UtilsPackage;
import java.util.Collections; import java.util.Collections;
@@ -29,7 +30,7 @@ import java.util.Set;
public class Visibilities { public class Visibilities {
public static final Visibility PRIVATE = new Visibility("private", false) { public static final Visibility PRIVATE = new Visibility("private", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
DeclarationDescriptor parent = what; DeclarationDescriptor parent = what;
while (parent != null) { while (parent != null) {
parent = parent.getContainingDeclaration(); parent = parent.getContainingDeclaration();
@@ -61,7 +62,7 @@ public class Visibilities {
public static final Visibility PROTECTED = new Visibility("protected", true) { public static final Visibility PROTECTED = new Visibility("protected", true) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
ClassDescriptor classDescriptor = DescriptorUtils.getParentOfType(what, ClassDescriptor.class); ClassDescriptor classDescriptor = DescriptorUtils.getParentOfType(what, ClassDescriptor.class);
if (DescriptorUtils.isClassObject(classDescriptor)) { if (DescriptorUtils.isClassObject(classDescriptor)) {
classDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class); classDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
@@ -73,35 +74,35 @@ public class Visibilities {
if (DescriptorUtils.isSubclass(fromClass, classDescriptor)) { if (DescriptorUtils.isSubclass(fromClass, classDescriptor)) {
return true; return true;
} }
return isVisible(what, fromClass.getContainingDeclaration()); return isVisible(receiver, what, fromClass.getContainingDeclaration());
} }
}; };
public static final Visibility INTERNAL = new Visibility("internal", false) { public static final Visibility INTERNAL = new Visibility("internal", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
//NOTE: supposedly temporarily //NOTE: supposedly temporarily
return PUBLIC.isVisible(what, from); return PUBLIC.isVisible(receiver, what, from);
} }
}; };
public static final Visibility PUBLIC = new Visibility("public", true) { public static final Visibility PUBLIC = new Visibility("public", true) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return true; return true;
} }
}; };
public static final Visibility LOCAL = new Visibility("local", false) { public static final Visibility LOCAL = new Visibility("local", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
throw new IllegalStateException(); //This method shouldn't be invoked for LOCAL visibility throw new IllegalStateException(); //This method shouldn't be invoked for LOCAL visibility
} }
}; };
public static final Visibility INHERITED = new Visibility("inherited", false) { public static final Visibility INHERITED = new Visibility("inherited", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
throw new IllegalStateException("Visibility is unknown yet"); //This method shouldn't be invoked for INHERITED visibility throw new IllegalStateException("Visibility is unknown yet"); //This method shouldn't be invoked for INHERITED visibility
} }
}; };
@@ -109,7 +110,7 @@ public class Visibilities {
/* Visibility for fake override invisible members (they are created for better error reporting) */ /* Visibility for fake override invisible members (they are created for better error reporting) */
public static final Visibility INVISIBLE_FAKE = new Visibility("invisible_fake", false) { public static final Visibility INVISIBLE_FAKE = new Visibility("invisible_fake", false) {
@Override @Override
protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { protected boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return false; return false;
} }
}; };
@@ -121,7 +122,11 @@ public class Visibilities {
} }
public static boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public static boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return findInvisibleMember(what, from) == null; return isVisible(ReceiverValue.IRRELEVANT_RECEIVER, what, from);
}
public static boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return findInvisibleMember(receiver, what, from) == null;
} }
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
@@ -131,12 +136,13 @@ public class Visibilities {
@Nullable @Nullable
public static DeclarationDescriptorWithVisibility findInvisibleMember( public static DeclarationDescriptorWithVisibility findInvisibleMember(
@NotNull ReceiverValue receiver,
@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptorWithVisibility what,
@NotNull DeclarationDescriptor from @NotNull DeclarationDescriptor from
) { ) {
DeclarationDescriptorWithVisibility parent = what; DeclarationDescriptorWithVisibility parent = what;
while (parent != null && parent.getVisibility() != LOCAL) { while (parent != null && parent.getVisibility() != LOCAL) {
if (!parent.getVisibility().isVisible(parent, from)) { if (!parent.getVisibility().isVisible(receiver, parent, from)) {
return parent; return parent;
} }
parent = DescriptorUtils.getParentOfType(parent, DeclarationDescriptorWithVisibility.class); parent = DescriptorUtils.getParentOfType(parent, DeclarationDescriptorWithVisibility.class);
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.descriptors; package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
public abstract class Visibility { public abstract class Visibility {
private final boolean isPublicAPI; private final boolean isPublicAPI;
@@ -48,5 +49,5 @@ public abstract class Visibility {
return this; return this;
} }
protected abstract boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from); protected abstract boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from);
} }
@@ -38,6 +38,24 @@ public interface ReceiverValue {
} }
}; };
ReceiverValue IRRELEVANT_RECEIVER = new ReceiverValue() {
@NotNull
@Override
public JetType getType() {
throw new UnsupportedOperationException("IRRELEVANT_RECEIVER.getType()");
}
@Override
public boolean exists() {
return false;
}
@Override
public String toString() {
return "IRRELEVANT_RECEIVER";
}
};
@NotNull @NotNull
JetType getType(); JetType getType();