No members&extensions after non-qualified "::" because it will be soon unsupported by the compiler
This commit is contained in:
+17
-34
@@ -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)
|
||||
|
||||
+8
-8
@@ -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: "" }
|
||||
|
||||
Vendored
+4
-4
@@ -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
|
||||
|
||||
-31
@@ -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" }
|
||||
-10
@@ -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())" }
|
||||
+3
-5
@@ -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(){}
|
||||
|
||||
+1
-2
@@ -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>
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
class C {
|
||||
val prop: Int = 0
|
||||
val prop: Int = 0
|
||||
|
||||
class C {
|
||||
fun foo() {
|
||||
val v = ::prop<caret>
|
||||
}
|
||||
|
||||
+2
-4
@@ -1,7 +1,5 @@
|
||||
package dependency
|
||||
|
||||
fun String.extFun(){}
|
||||
fun String.wrongExtFun(p: Int){}
|
||||
|
||||
fun topLevelFun(){}
|
||||
fun wrongTopLevelFun(p: Int){}
|
||||
|
||||
fun String.extFun(){}
|
||||
|
||||
+1
-3
@@ -7,7 +7,5 @@ fun bar(p: String.() -> Unit) { }
|
||||
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: extFun
|
||||
// EXIST: topLevelFun
|
||||
// ABSENT: wrongExtFun
|
||||
// ABSENT: wrongTopLevelFun
|
||||
// ABSENT: extFun
|
||||
|
||||
-12
@@ -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")
|
||||
|
||||
-12
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user