diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibilities.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibilities.java index 28be6fac800..ceb9c7c2e48 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibilities.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibilities.java @@ -105,17 +105,21 @@ public class Visibilities { } public static boolean isVisible(@Nullable DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { + return findInvisibleMember(what, from) == null; + } + + public static DeclarationDescriptorWithVisibility findInvisibleMember( + @Nullable DeclarationDescriptorWithVisibility what, + @NotNull DeclarationDescriptor from + ) { DeclarationDescriptorWithVisibility parent = what; - while (parent != null) { - if (parent.getVisibility() == LOCAL) { - return true; - } + while (parent != null && parent.getVisibility() != LOCAL) { if (!parent.getVisibility().isVisible(parent, from)) { - return false; + return parent; } parent = DescriptorUtils.getParentOfType(parent, DeclarationDescriptorWithVisibility.class); } - return true; + return null; } private static final Map ORDERED_VISIBILITIES = Maps.newHashMap(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index cc5e29548c7..d79ca3fbbf1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -93,9 +93,12 @@ public class CandidateResolver { return; } - if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) { + + DeclarationDescriptorWithVisibility invisibleMember = + Visibilities.findInvisibleMember(candidate, context.scope.getContainingDeclaration()); + if (invisibleMember != null) { candidateCall.addStatus(OTHER_ERROR); - context.tracing.invisibleMember(context.trace, candidate); + context.tracing.invisibleMember(context.trace, invisibleMember); return; } diff --git a/idea/testData/diagnosticMessage/invisibleMember.kt b/idea/testData/diagnosticMessage/invisibleMember.kt new file mode 100644 index 00000000000..ef88596578b --- /dev/null +++ b/idea/testData/diagnosticMessage/invisibleMember.kt @@ -0,0 +1,15 @@ +package foo.bar + +class A { + private class B + public class C private() + + private fun bar() {} +} + +fun foo() { + A.B() // ERROR 1: Cannot access 'B': it is 'private' in 'A' + A.C() // ERROR 2: Cannot access '' : it is 'private' in 'C' + + A().bar() // ERROR 3: Cannot access 'bar' : it is 'private' in 'A' +} diff --git a/idea/testData/diagnosticMessage/invisibleMember1.txt b/idea/testData/diagnosticMessage/invisibleMember1.txt new file mode 100644 index 00000000000..a75f0462beb --- /dev/null +++ b/idea/testData/diagnosticMessage/invisibleMember1.txt @@ -0,0 +1,2 @@ + +Cannot access 'B': it is 'private' in 'A' \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/invisibleMember2.txt b/idea/testData/diagnosticMessage/invisibleMember2.txt new file mode 100644 index 00000000000..2b57c2382f8 --- /dev/null +++ b/idea/testData/diagnosticMessage/invisibleMember2.txt @@ -0,0 +1,2 @@ + +Cannot access '': it is 'private' in 'C' \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/invisibleMember3.txt b/idea/testData/diagnosticMessage/invisibleMember3.txt new file mode 100644 index 00000000000..47bf80a5bad --- /dev/null +++ b/idea/testData/diagnosticMessage/invisibleMember3.txt @@ -0,0 +1,2 @@ + +Cannot access 'bar': it is 'private' in 'A' \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java b/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java index 982af03f815..c9ea336c646 100644 --- a/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java @@ -34,7 +34,6 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.plugin.PluginTestCaseBase; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -110,4 +109,8 @@ public class DiagnosticMessageTest extends JetLiteFixture { public void testTypeMismatchWithNothing() throws Exception { doTest("typeMismatchWithNothing", 1, Errors.TYPE_MISMATCH); } + + public void testInvisibleMember() throws Exception { + doTest("invisibleMember", 3, Errors.INVISIBLE_MEMBER, Errors.INVISIBLE_MEMBER, Errors.INVISIBLE_MEMBER); + } }