Fix completion for private_to_this.

This commit is contained in:
Stanislav Erokhin
2014-10-31 14:07:32 +03:00
parent f9afdf7540
commit d334f3b31c
18 changed files with 320 additions and 61 deletions
@@ -42,6 +42,7 @@ import kotlin.properties.Delegates
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
import org.jetbrains.jet.plugin.util.makeNotNullable
import org.jetbrains.jet.plugin.util.CallType
import org.jetbrains.jet.plugin.completion.isVisible
class CompletionSessionConfiguration(
val completeNonImportedDeclarations: Boolean,
@@ -111,7 +112,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
if (configuration.completeNonAccessibleDeclarations) return true
if (descriptor is DeclarationDescriptorWithVisibility && inDescriptor != null) {
return Visibilities.isVisible(descriptor, inDescriptor)
return descriptor.isVisible(inDescriptor, bindingContext, jetReference?.expression)
}
return true
@@ -36,6 +36,14 @@ import com.intellij.codeInsight.completion.InsertionContext
import org.jetbrains.jet.plugin.completion.handlers.CastReceiverInsertHandler
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
import org.jetbrains.jet.lang.descriptors.Visibilities
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils
enum class ItemPriority {
MULTIPLE_ARGUMENTS_ITEM
@@ -134,3 +142,31 @@ fun descriptorsEqualWithSubstitution(descriptor1: DeclarationDescriptor?, descri
}
return true
}
fun DeclarationDescriptorWithVisibility.isVisible(
from: DeclarationDescriptor,
bindingContext: BindingContext? = null,
element: JetSimpleNameExpression? = null
): Boolean {
if (Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, this, from)) return true
if (bindingContext == null || element == null) return false
val receiver = element.getReceiverExpression()
val type = receiver?.let { bindingContext.get(BindingContext.EXPRESSION_TYPE, it) }
val explicitReceiver = type?.let { ExpressionReceiver(receiver, it) }
if (explicitReceiver != null) {
val normalizeReceiver = ExpressionTypingUtils.normalizeReceiverValueForVisibility(explicitReceiver, bindingContext)
return Visibilities.isVisible(normalizeReceiver, this, from)
}
val jetScope = bindingContext[BindingContext.RESOLUTION_SCOPE, element]
val implicitReceivers = jetScope?.getImplicitReceiversHierarchy()
if (implicitReceivers != null) {
for (implicitReceiver in implicitReceivers) {
val normalizeReceiver = ExpressionTypingUtils.normalizeReceiverValueForVisibility(implicitReceiver.getValue(), bindingContext)
if (Visibilities.isVisible(normalizeReceiver, this, from)) return true
}
}
return false
}
@@ -19,14 +19,12 @@ package org.jetbrains.jet.plugin.completion.smart
import com.intellij.codeInsight.lookup.LookupElement
import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.codeInsight.lookup.LookupElementPresentation
import org.jetbrains.jet.renderer.DescriptorRenderer
import com.intellij.codeInsight.completion.InsertionContext
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.psi.JetExpression
import org.jetbrains.jet.plugin.completion.ExpectedInfo
import org.jetbrains.jet.plugin.completion.qualifiedNameForSourceCode
import org.jetbrains.jet.lang.resolve.descriptorUtil.isExtension
@@ -35,6 +33,8 @@ import org.jetbrains.jet.plugin.caches.resolve.ResolutionFacade
import org.jetbrains.jet.plugin.completion.LookupElementFactory
import org.jetbrains.jet.lang.types.TypeSubstitutor
import org.jetbrains.jet.plugin.util.fuzzyReturnType
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
import org.jetbrains.jet.plugin.completion.isVisible
// adds java static members, enum members and members from class object
class StaticMembers(
@@ -44,15 +44,13 @@ class StaticMembers(
) {
public fun addToCollection(collection: MutableCollection<LookupElement>,
expectedInfos: Collection<ExpectedInfo>,
context: JetExpression,
context: JetSimpleNameExpression,
enumEntriesToSkip: Set<DeclarationDescriptor>) {
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return
val expectedInfosByClass = expectedInfos.groupBy { TypeUtils.getClassDescriptor(it.type) }
for ((classDescriptor, expectedInfosForClass) in expectedInfosByClass) {
if (classDescriptor != null && !classDescriptor.getName().isSpecial()) {
addToCollection(collection, classDescriptor, expectedInfosForClass, scope, enumEntriesToSkip)
addToCollection(collection, classDescriptor, expectedInfosForClass, context, enumEntriesToSkip)
}
}
}
@@ -61,11 +59,13 @@ class StaticMembers(
collection: MutableCollection<LookupElement>,
classDescriptor: ClassDescriptor,
expectedInfos: Collection<ExpectedInfo>,
scope: JetScope,
context: JetSimpleNameExpression,
enumEntriesToSkip: Set<DeclarationDescriptor>) {
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return
fun processMember(descriptor: DeclarationDescriptor) {
if (descriptor is DeclarationDescriptorWithVisibility && !Visibilities.isVisible(descriptor, scope.getContainingDeclaration())) return
if (descriptor is DeclarationDescriptorWithVisibility && !descriptor.isVisible(scope.getContainingDeclaration(), bindingContext, context)) return
val classifier: (ExpectedInfo) -> ExpectedInfoClassification
if (descriptor is CallableDescriptor) {
@@ -51,10 +51,10 @@ import org.jetbrains.jet.plugin.util.ProjectRootsUtil
import org.jetbrains.jet.asJava.unwrapped
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.jet.lang.descriptors.Visibilities
import org.jetbrains.jet.lang.diagnostics.Errors
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.jet.utils.CachedValueProperty
import org.jetbrains.jet.plugin.completion.isVisible
/**
* Check possibility and perform fix for unresolved references.
@@ -130,7 +130,7 @@ public class AutoImportFix(element: JetSimpleNameExpression) : JetHintAction<Jet
fun isVisible(descriptor: DeclarationDescriptor): Boolean {
if (descriptor is DeclarationDescriptorWithVisibility && containingDescriptor != null) {
return Visibilities.isVisible(descriptor, containingDescriptor)
return descriptor.isVisible(containingDescriptor, bindingContext, element)
}
return true
@@ -0,0 +1,13 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
fun test() {
<caret>
}
}
// INVOCATION_COUNT: 1
// EXIST: bar, foo
@@ -0,0 +1,12 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
{
<caret>
}
}
// INVOCATION_COUNT: 1
// EXIST: bar, foo
@@ -0,0 +1,12 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
{
this.<caret>
}
}
// INVOCATION_COUNT: 1
// EXIST: bar, foo
@@ -0,0 +1,15 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
fun test() {
with(A()) {
<caret>
}
}
}
// INVOCATION_COUNT: 1
// EXIST: bar, foo
@@ -0,0 +1,13 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
fun test(a: A<Int>) {
a.<caret>
}
}
// INVOCATION_COUNT: 1
// ABSENT: bar, foo
@@ -0,0 +1,13 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
fun test(a: A<Int>) {
a.<caret>
}
}
// INVOCATION_COUNT: 2
// EXIST: bar, foo
@@ -0,0 +1,15 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
fun test() {
with(A()) {
this@A.<caret>
}
}
}
// INVOCATION_COUNT: 1
// EXIST: bar, foo
@@ -0,0 +1,15 @@
class A<in I> {
private val bar: I
private fun foo(): I = null!!
fun test() {
with(A()) {
this.<caret>
}
}
}
// INVOCATION_COUNT: 1
// ABSENT: bar, foo
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTest {
@TestMetadata("idea/testData/completion/basic/common")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({Common.Extensions.class, Common.NamedParameters.class})
@InnerTestClasses({Common.Extensions.class, Common.NamedParameters.class, Common.Visibility.class})
@RunWith(JUnit3RunnerWithInners.class)
public static class Common extends AbstractJSBasicCompletionTest {
@TestMetadata("AfterFloatOnNewLine.kt")
@@ -850,30 +850,6 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
doTest(fileName);
}
@TestMetadata("VisibilityClassMembersFromExternal.kt")
public void testVisibilityClassMembersFromExternal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityClassMembersFromExternal.kt");
doTest(fileName);
}
@TestMetadata("VisibilityClassMembersFromExternalForce.kt")
public void testVisibilityClassMembersFromExternalForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityClassMembersFromExternalForce.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclass.kt")
public void testVisibilityInSubclass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityInSubclass.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclassForce.kt")
public void testVisibilityInSubclassForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityInSubclassForce.kt");
doTest(fileName);
}
@TestMetadata("idea/testData/completion/basic/common/extensions")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1047,6 +1023,87 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
doTest(fileName);
}
}
@TestMetadata("idea/testData/completion/basic/common/visibility")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Visibility extends AbstractJSBasicCompletionTest {
public void testAllFilesPresentInVisibility() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/basic/common/visibility"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("VisibilityClassMembersFromExternal.kt")
public void testVisibilityClassMembersFromExternal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityClassMembersFromExternal.kt");
doTest(fileName);
}
@TestMetadata("VisibilityClassMembersFromExternalForce.kt")
public void testVisibilityClassMembersFromExternalForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityClassMembersFromExternalForce.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclass.kt")
public void testVisibilityInSubclass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityInSubclass.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclassForce.kt")
public void testVisibilityInSubclassForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityInSubclassForce.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThis.kt")
public void testVisibilityPrivateToThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThis.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisInConstructor.kt")
public void testVisibilityPrivateToThisInConstructor() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisInConstructor.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisInConstructorWithThis.kt")
public void testVisibilityPrivateToThisInConstructorWithThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisInConstructorWithThis.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisInSpecialScope.kt")
public void testVisibilityPrivateToThisInSpecialScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisInSpecialScope.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithReceiver.kt")
public void testVisibilityPrivateToThisWithReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithReceiver.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithReceiver2.kt")
public void testVisibilityPrivateToThisWithReceiver2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithReceiver2.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithThis.kt")
public void testVisibilityPrivateToThisWithThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithThis.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithWrongThis.kt")
public void testVisibilityPrivateToThisWithWrongThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithWrongThis.kt");
doTest(fileName);
}
}
}
@TestMetadata("idea/testData/completion/basic/js")
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionTest {
@TestMetadata("idea/testData/completion/basic/common")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({Common.Extensions.class, Common.NamedParameters.class})
@InnerTestClasses({Common.Extensions.class, Common.NamedParameters.class, Common.Visibility.class})
@RunWith(JUnit3RunnerWithInners.class)
public static class Common extends AbstractJvmBasicCompletionTest {
@TestMetadata("AfterFloatOnNewLine.kt")
@@ -850,30 +850,6 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
doTest(fileName);
}
@TestMetadata("VisibilityClassMembersFromExternal.kt")
public void testVisibilityClassMembersFromExternal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityClassMembersFromExternal.kt");
doTest(fileName);
}
@TestMetadata("VisibilityClassMembersFromExternalForce.kt")
public void testVisibilityClassMembersFromExternalForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityClassMembersFromExternalForce.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclass.kt")
public void testVisibilityInSubclass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityInSubclass.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclassForce.kt")
public void testVisibilityInSubclassForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/VisibilityInSubclassForce.kt");
doTest(fileName);
}
@TestMetadata("idea/testData/completion/basic/common/extensions")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1047,6 +1023,87 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
doTest(fileName);
}
}
@TestMetadata("idea/testData/completion/basic/common/visibility")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Visibility extends AbstractJvmBasicCompletionTest {
public void testAllFilesPresentInVisibility() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/basic/common/visibility"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("VisibilityClassMembersFromExternal.kt")
public void testVisibilityClassMembersFromExternal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityClassMembersFromExternal.kt");
doTest(fileName);
}
@TestMetadata("VisibilityClassMembersFromExternalForce.kt")
public void testVisibilityClassMembersFromExternalForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityClassMembersFromExternalForce.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclass.kt")
public void testVisibilityInSubclass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityInSubclass.kt");
doTest(fileName);
}
@TestMetadata("VisibilityInSubclassForce.kt")
public void testVisibilityInSubclassForce() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityInSubclassForce.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThis.kt")
public void testVisibilityPrivateToThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThis.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisInConstructor.kt")
public void testVisibilityPrivateToThisInConstructor() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisInConstructor.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisInConstructorWithThis.kt")
public void testVisibilityPrivateToThisInConstructorWithThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisInConstructorWithThis.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisInSpecialScope.kt")
public void testVisibilityPrivateToThisInSpecialScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisInSpecialScope.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithReceiver.kt")
public void testVisibilityPrivateToThisWithReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithReceiver.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithReceiver2.kt")
public void testVisibilityPrivateToThisWithReceiver2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithReceiver2.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithThis.kt")
public void testVisibilityPrivateToThisWithThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithThis.kt");
doTest(fileName);
}
@TestMetadata("VisibilityPrivateToThisWithWrongThis.kt")
public void testVisibilityPrivateToThisWithWrongThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/visibility/VisibilityPrivateToThisWithWrongThis.kt");
doTest(fileName);
}
}
}
@TestMetadata("idea/testData/completion/basic/java")