Report INVISIBLE_MEMBER on private class object usage
This commit is contained in:
+16
-1
@@ -72,6 +72,7 @@ public class CallExpressionResolver {
|
|||||||
if (classObjectType != null) {
|
if (classObjectType != null) {
|
||||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||||
JetType result = getExtendedClassObjectType(classObjectType, referencedName, classifier, context);
|
JetType result = getExtendedClassObjectType(classObjectType, referencedName, classifier, context);
|
||||||
|
checkClassObjectVisibility(classifier, expression, context);
|
||||||
return DataFlowUtils.checkType(result, expression, context);
|
return DataFlowUtils.checkType(result, expression, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,8 +118,22 @@ public class CallExpressionResolver {
|
|||||||
return result[0];
|
return result[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkClassObjectVisibility(
|
||||||
|
@NotNull ClassifierDescriptor classifier,
|
||||||
|
@NotNull JetSimpleNameExpression expression,
|
||||||
|
@NotNull ResolutionContext context
|
||||||
|
) {
|
||||||
|
if (!(classifier instanceof ClassDescriptor)) return;
|
||||||
|
ClassDescriptor classObject = ((ClassDescriptor) classifier).getClassObjectDescriptor();
|
||||||
|
assert classObject != null : "This check should be done only for classes with class objects: " + classifier;
|
||||||
|
DeclarationDescriptor from = context.scope.getContainingDeclaration();
|
||||||
|
if (!Visibilities.isVisible(classObject, from)) {
|
||||||
|
context.trace.report(INVISIBLE_MEMBER.on(expression, classObject, classObject.getVisibility(), from));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JetType getExtendedClassObjectType(
|
private static JetType getExtendedClassObjectType(
|
||||||
@NotNull JetType classObjectType,
|
@NotNull JetType classObjectType,
|
||||||
@NotNull Name referencedName,
|
@NotNull Name referencedName,
|
||||||
@NotNull ClassifierDescriptor classifier,
|
@NotNull ClassifierDescriptor classifier,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package foo
|
|||||||
fun test() {
|
fun test() {
|
||||||
A.d
|
A.d
|
||||||
A.<!INVISIBLE_MEMBER!>f<!>
|
A.<!INVISIBLE_MEMBER!>f<!>
|
||||||
CCC.<!INVISIBLE_MEMBER!>classObjectVar<!>
|
<!INVISIBLE_MEMBER!>CCC<!>.<!INVISIBLE_MEMBER!>classObjectVar<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
class A() {
|
class A() {
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
//FILE:a.kt
|
||||||
|
package a
|
||||||
|
|
||||||
|
class A {
|
||||||
|
class object {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class B {
|
||||||
|
class object {
|
||||||
|
fun bar() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
private class object {
|
||||||
|
fun baz() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class D {
|
||||||
|
private class object {
|
||||||
|
fun quux() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//FILE:b.kt
|
||||||
|
package b
|
||||||
|
|
||||||
|
import a.A
|
||||||
|
import a.<!INVISIBLE_REFERENCE!>B<!>
|
||||||
|
import a.C
|
||||||
|
import a.<!INVISIBLE_REFERENCE!>D<!>
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
f(A)
|
||||||
|
f(<!INVISIBLE_MEMBER!>B<!>)
|
||||||
|
f(<!INVISIBLE_MEMBER!>C<!>)
|
||||||
|
f(<!INVISIBLE_MEMBER!>D<!>)
|
||||||
|
|
||||||
|
A.foo()
|
||||||
|
<!INVISIBLE_MEMBER!>B<!>.<!INVISIBLE_MEMBER!>bar<!>()
|
||||||
|
<!INVISIBLE_MEMBER!>C<!>.<!INVISIBLE_MEMBER!>baz<!>()
|
||||||
|
<!INVISIBLE_MEMBER!>D<!>.<!INVISIBLE_MEMBER!>quux<!>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f(<!UNUSED_PARAMETER!>unused<!>: Any) {}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class A {
|
||||||
|
private class object {
|
||||||
|
class B {
|
||||||
|
class C {
|
||||||
|
class object {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f1() = <!INVISIBLE_MEMBER!>A<!>.B.C
|
||||||
|
|
||||||
|
fun f2() = <!INVISIBLE_MEMBER!>A<!>.B.C.<!INVISIBLE_MEMBER!>foo<!>()
|
||||||
@@ -1374,6 +1374,16 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/classObjects/InnerClassClassObject.kt");
|
doTest("compiler/testData/diagnostics/tests/classObjects/InnerClassClassObject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("invisibleClassObjects.kt")
|
||||||
|
public void testInvisibleClassObjects() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/classObjects/invisibleClassObjects.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedClassInPrivateClassObject.kt")
|
||||||
|
public void testNestedClassInPrivateClassObject() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/classObjects/nestedClassInPrivateClassObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis")
|
@TestMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis")
|
||||||
|
|||||||
Reference in New Issue
Block a user