No members&extensions after non-qualified "::" because it will be soon unsupported by the compiler

This commit is contained in:
Valentin Kipyatkov
2015-10-01 23:11:52 +03:00
parent f58f5dd82a
commit 1bc132bc1a
14 changed files with 44 additions and 139 deletions
@@ -23,11 +23,13 @@ import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.JetCodeFragment
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import org.jetbrains.kotlin.psi.JetTypeReference
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotatedAsHidden
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
@@ -105,7 +107,10 @@ public class ReferenceVariantsHelper(
return getVariantsForUserType(callTypeAndReceiver.receiver, expression, kindFilter, nameFilter)
}
is CallTypeAndReceiver.CALLABLE_REFERENCE -> receiverExpression = null // handled below
is CallTypeAndReceiver.CALLABLE_REFERENCE -> {
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression.parent as JetExpression] ?: return emptyList()
return getVariantsForCallableReference(callTypeAndReceiver.receiver, resolutionScope, kindFilter, nameFilter)
}
is CallTypeAndReceiver.DEFAULT -> receiverExpression = null
is CallTypeAndReceiver.DOT -> receiverExpression = callTypeAndReceiver.receiver
@@ -116,8 +121,8 @@ public class ReferenceVariantsHelper(
else -> throw RuntimeException() //TODO: see KT-9394
}
val resolutionScope = resolutionScope(expression, context) ?: return emptyList()
val dataFlowInfo = dataFlowInfo(expression, context)
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return emptyList()
val dataFlowInfo = context.getDataFlowInfo(expression)
val containingDeclaration = resolutionScope.getContainingDeclaration()
val smartCastManager = resolutionFacade.frontendService<SmartCastManager>()
@@ -125,10 +130,6 @@ public class ReferenceVariantsHelper(
smartCastManager.getSmartCastVariantsWithLessSpecificExcluded(it.value, context, containingDeclaration, dataFlowInfo)
}.toSet()
if (callTypeAndReceiver is CallTypeAndReceiver.CALLABLE_REFERENCE) {
return getVariantsForCallableReference(callTypeAndReceiver.receiver, resolutionScope, implicitReceiverTypes, kindFilter, nameFilter)
}
val descriptors = LinkedHashSet<DeclarationDescriptor>()
if (receiverExpression != null) {
@@ -180,7 +181,6 @@ public class ReferenceVariantsHelper(
private fun getVariantsForCallableReference(
qualifierTypeRef: JetTypeReference?,
resolutionScope: JetScope,
implicitReceiverTypes: Collection<JetType>,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> {
@@ -188,17 +188,13 @@ public class ReferenceVariantsHelper(
if (qualifierTypeRef != null) {
val type = context[BindingContext.TYPE, qualifierTypeRef] ?: return emptyList()
descriptors.addNonExtensionMembers(listOf(type), kindFilter, nameFilter, constructorsForInnerClassesOnly = false)
descriptors.addNonExtensionMembers(listOf(type), kindFilter, nameFilter, constructorFilter = { true })
descriptors.addScopeAndSyntheticExtensions(resolutionScope, listOf(type), CallType.CALLABLE_REFERENCE, kindFilter, nameFilter)
}
else {
// process non-instance members and class constructors
descriptors.addNonExtensionCallablesAndConstructors(resolutionScope, kindFilter, nameFilter, constructorsForInnerClassesOnly = false)
descriptors.addNonExtensionMembers(implicitReceiverTypes, kindFilter, nameFilter, constructorsForInnerClassesOnly = true)
descriptors.addScopeAndSyntheticExtensions(resolutionScope, implicitReceiverTypes, CallType.CALLABLE_REFERENCE, kindFilter, nameFilter)
descriptors.addNonExtensionCallablesAndConstructors(resolutionScope, kindFilter, nameFilter, constructorFilter = { !it.isInner })
}
return descriptors
}
@@ -226,7 +222,7 @@ public class ReferenceVariantsHelper(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
) {
addNonExtensionMembers(receiverTypes, kindFilter, nameFilter, constructorsForInnerClassesOnly = true)
addNonExtensionMembers(receiverTypes, kindFilter, nameFilter, constructorFilter = { it.isInner })
addMemberExtensions(implicitReceiverTypes, receiverTypes, callType, kindFilter, nameFilter)
addScopeAndSyntheticExtensions(resolutionScope, receiverTypes, callType, kindFilter, nameFilter)
}
@@ -250,10 +246,10 @@ public class ReferenceVariantsHelper(
receiverTypes: Collection<JetType>,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean,
constructorsForInnerClassesOnly: Boolean
constructorFilter: (ClassDescriptor) -> Boolean
) {
for (receiverType in receiverTypes) {
addNonExtensionCallablesAndConstructors(receiverType.memberScope, kindFilter, nameFilter, constructorsForInnerClassesOnly)
addNonExtensionCallablesAndConstructors(receiverType.memberScope, kindFilter, nameFilter, constructorFilter)
}
}
@@ -261,7 +257,7 @@ public class ReferenceVariantsHelper(
scope: JetScope,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean,
constructorsForInnerClassesOnly: Boolean
constructorFilter: (ClassDescriptor) -> Boolean
) {
var filterToUse = DescriptorKindFilter(kindFilter.kindMask and DescriptorKindFilter.CALLABLES.kindMask).exclude(DescriptorKindExclude.Extensions)
@@ -272,8 +268,8 @@ public class ReferenceVariantsHelper(
for (descriptor in scope.getDescriptorsFiltered(filterToUse, nameFilter)) {
if (descriptor is ClassDescriptor) {
if (constructorsForInnerClassesOnly && !descriptor.isInner) continue
if (descriptor.modality == Modality.ABSTRACT || descriptor.modality == Modality.SEALED) continue
if (!constructorFilter(descriptor)) continue
descriptor.constructors.filterTo(this) { kindFilter.accepts(it) }
}
else if (kindFilter.accepts(descriptor)) {
@@ -333,17 +329,4 @@ public class ReferenceVariantsHelper(
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf()
return resolutionScope.getDescriptorsFiltered(DescriptorKindFilter.PACKAGES, nameFilter).filter(visibilityFilter)
}
companion object {
//TODO: drop these methods
public fun resolutionScope(expression: JetExpression, bindingContext: BindingContext): JetScope? {
val parent = expression.parent
return bindingContext[BindingContext.RESOLUTION_SCOPE, if (parent is JetCallableReferenceExpression) parent else expression]
}
public fun dataFlowInfo(expression: JetExpression, bindingContext: BindingContext): DataFlowInfo {
val parent = expression.parent
return bindingContext.getDataFlowInfo(if (parent is JetCallableReferenceExpression) parent else expression)
}
}
}
@@ -20,13 +20,13 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.psi.psiUtil.isImportDirectiveExpression
import org.jetbrains.kotlin.psi.psiUtil.isPackageDirectiveExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
@@ -158,13 +158,7 @@ public fun CallTypeAndReceiver<*, *>.receiverTypes(
val receiverExpression: JetExpression?
when (this) {
is CallTypeAndReceiver.CALLABLE_REFERENCE -> {
if (receiver != null) {
val type = bindingContext[BindingContext.TYPE, receiver]
return type.singletonOrEmptyList()
}
else {
receiverExpression = null
}
return receiver?.let { bindingContext[BindingContext.TYPE, it] }.singletonOrEmptyList()
}
is CallTypeAndReceiver.DEFAULT -> receiverExpression = null
@@ -187,11 +181,11 @@ public fun CallTypeAndReceiver<*, *>.receiverTypes(
expressionType?.let { listOf(ExpressionReceiver(receiverExpression, expressionType)) } ?: return emptyList()
}
else {
val resolutionScope = ReferenceVariantsHelper.resolutionScope(position, bindingContext) ?: return emptyList()
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, position] ?: return emptyList()
resolutionScope.getImplicitReceiversWithInstance().map { it.value }
}
val dataFlowInfo = ReferenceVariantsHelper.dataFlowInfo(position, bindingContext)
val dataFlowInfo = bindingContext.getDataFlowInfo(position)
return receiverValues.flatMap { receiverValue ->
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverValue, bindingContext, moduleDescriptor)
@@ -7,13 +7,13 @@ val String.extensionVal: Int
val globalVal = 1
var globalVar = 1
fun funWithFunctionParameter(p: () -> Unit) {}
class C {
fun memberFun(){}
val memberVal = 1
fun funWithFunctionParameter(p: () -> Unit) {}
class NestedClass
inner class InnerClass
@@ -38,16 +38,16 @@ abstract class AbstractClass
// EXIST: { itemText: "globalVar", attributes: "" }
// ABSENT: extensionFun
// ABSENT: extensionVal
// EXIST: { itemText: "memberFun", attributes: "bold" }
// EXIST: { itemText: "memberVal", attributes: "bold" }
// ABSENT: memberFun
// ABSENT: memberVal
// EXIST: { itemText: "localFun", attributes: "" }
// ABSENT: { itemText: "local", attributes: "" }
// EXIST: { itemText: "companionObjectFun", attributes: "bold" }
// ABSENT: local
// ABSENT: companionObjectFun
// EXIST: { itemText: "C", attributes: "" }
// EXIST: { itemText: "NestedClass", attributes: "" }
// EXIST: { itemText: "InnerClass", attributes: "bold" }
// ABSENT: InnerClass
// ABSENT: WithPrivateConstructor
// ABSENT: AbstractClass
// ABSENT: class
// ABSENT: class.java
// EXIST: { itemText: "funWithFunctionParameter", tailText: "(p: () -> Unit)", attributes: "bold" }
// EXIST: { itemText: "funWithFunctionParameter", tailText: "(p: () -> Unit) (<root>)", attributes: "" }
@@ -15,9 +15,9 @@ fun C.foo() {
val v = ::<caret>
}
// EXIST: { itemText: "memberFun", attributes: "bold" }
// EXIST: { itemText: "memberVal", attributes: "bold" }
// EXIST: { itemText: "hashCode", attributes: "" }
// ABSENT: memberFun
// ABSENT: memberVal
// ABSENT: hashCode
// ABSENT: companionObjectFun
// ABSENT: NestedClass
// EXIST: { itemText: "InnerClass", attributes: "bold" }
// ABSENT: InnerClass
@@ -1,31 +0,0 @@
interface I1 {
fun i1Member()
}
interface I2 {
fun i2Member()
}
fun I1.i1Extension(){}
fun I2.i2Extension(){}
fun Any.anyExtension(){}
fun String.stringExtension(){}
open class C {
fun cMember(){}
fun foo() {
if (this is I1 && this is I2) {
val v = ::<caret>
}
}
}
// EXIST: { itemText: "i1Extension", attributes: "bold" }
// EXIST: { itemText: "i2Extension", attributes: "bold" }
// EXIST: { itemText: "i1Member", attributes: "bold" }
// EXIST: { itemText: "i2Member", attributes: "bold" }
// EXIST: { itemText: "anyExtension", attributes: "" }
// EXIST: { itemText: "hashCode", attributes: "" }
// ABSENT: stringExtension
// EXIST: { itemText: "cMember", attributes: "bold" }
@@ -1,10 +0,0 @@
import java.io.File
class MyFile : File("") {
val v = ::<caret>
}
// EXIST_JAVA_ONLY: { itemText: "getFreeSpace", tailText: "()", attributes: "" }
// ABSENT: freeSpace
// EXIST_JAVA_ONLY: { itemText: "isFile", tailText: "()", attributes: "" }
// ABSENT: { itemText: "isFile", tailText: " (from isFile())" }
@@ -1,9 +1,7 @@
package dependency
fun CharSequence.extFun(){}
fun Int.wrongExtFun(){}
fun topLevelFun(){}
val topLevelVal: Int = 1
val topLevelVal: Int = 1
fun CharSequence.extFun(){}
@@ -3,7 +3,6 @@ fun String.foo() {
}
// INVOCATION_COUNT: 2
// EXIST: extFun
// EXIST: topLevelFun
// EXIST: topLevelVal
// ABSENT: wrongExtFun
// ABSENT: extFun
@@ -1,6 +1,6 @@
class C {
val prop: Int = 0
val prop: Int = 0
class C {
fun foo() {
val v = ::<caret>
}
@@ -1,6 +1,6 @@
class C {
val prop: Int = 0
val prop: Int = 0
class C {
fun foo() {
val v = ::prop<caret>
}
@@ -1,7 +1,5 @@
package dependency
fun String.extFun(){}
fun String.wrongExtFun(p: Int){}
fun topLevelFun(){}
fun wrongTopLevelFun(p: Int){}
fun String.extFun(){}
@@ -7,7 +7,5 @@ fun bar(p: String.() -> Unit) { }
// INVOCATION_COUNT: 2
// EXIST: extFun
// EXIST: topLevelFun
// ABSENT: wrongExtFun
// ABSENT: wrongTopLevelFun
// ABSENT: extFun
@@ -1098,23 +1098,11 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
doTest(fileName);
}
@TestMetadata("SmartCastThis.kt")
public void testSmartCastThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/callableReference/SmartCastThis.kt");
doTest(fileName);
}
@TestMetadata("SyntheticExtensions.kt")
public void testSyntheticExtensions() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/callableReference/SyntheticExtensions.kt");
doTest(fileName);
}
@TestMetadata("SyntheticExtensions2.kt")
public void testSyntheticExtensions2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/callableReference/SyntheticExtensions2.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/extensions")
@@ -1098,23 +1098,11 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
doTest(fileName);
}
@TestMetadata("SmartCastThis.kt")
public void testSmartCastThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/callableReference/SmartCastThis.kt");
doTest(fileName);
}
@TestMetadata("SyntheticExtensions.kt")
public void testSyntheticExtensions() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/callableReference/SyntheticExtensions.kt");
doTest(fileName);
}
@TestMetadata("SyntheticExtensions2.kt")
public void testSyntheticExtensions2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/callableReference/SyntheticExtensions2.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/extensions")