Correct completion of nested/inner classes after dot
#KT-1889 Fixed
This commit is contained in:
@@ -110,6 +110,9 @@ public class DescriptorKindFilter(
|
||||
public fun withoutKinds(kinds: Int): DescriptorKindFilter
|
||||
= DescriptorKindFilter(kindMask and kinds.inv(), excludes)
|
||||
|
||||
public fun withKinds(kinds: Int): DescriptorKindFilter
|
||||
= DescriptorKindFilter(kindMask or kinds, excludes)
|
||||
|
||||
public fun restrictedToKinds(kinds: Int): DescriptorKindFilter? {
|
||||
val mask = kindMask and kinds
|
||||
if (mask == 0) return null
|
||||
|
||||
+12
-2
@@ -102,9 +102,19 @@ public class ReferenceVariantsHelper(
|
||||
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
|
||||
val dataFlowInfo = context.getDataFlowInfo(expression)
|
||||
|
||||
val mask = kindFilter.withoutKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK).exclude(DescriptorKindExclude.Extensions)
|
||||
var memberFilter = kindFilter exclude DescriptorKindExclude.Extensions
|
||||
for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, dataFlowInfo)) {
|
||||
variant.getMemberScope().getDescriptorsFiltered(mask, nameFilter).filterTo(descriptors) { callType.canCall(it) }
|
||||
val members = variant.getMemberScope().getDescriptorsFiltered(DescriptorKindFilter.ALL, nameFilter) // filter by kind later because of constructors
|
||||
for (member in members) {
|
||||
if (member is ClassDescriptor) {
|
||||
if (member.isInner()) {
|
||||
member.getConstructors().filterTo(descriptors) { callType.canCall(it) && memberFilter.accepts(it) }
|
||||
}
|
||||
}
|
||||
else if (callType.canCall(member) && memberFilter.accepts(member)) {
|
||||
descriptors.add(member)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
descriptors.addCallableExtensions(resolutionScope, receiverValue, dataFlowInfo, callType, kindFilter, nameFilter)
|
||||
|
||||
@@ -144,7 +144,11 @@ public class LookupElementFactory(
|
||||
}
|
||||
|
||||
|
||||
var element = LookupElementBuilder.create(DeclarationDescriptorLookupObject(descriptor, resolutionFacade, declaration), descriptor.getName().asString())
|
||||
val name = if (descriptor is ConstructorDescriptor)
|
||||
descriptor.getContainingDeclaration().getName().asString()
|
||||
else
|
||||
descriptor.getName().asString()
|
||||
var element = LookupElementBuilder.create(DeclarationDescriptorLookupObject(descriptor, resolutionFacade, declaration), name)
|
||||
.withIcon(JetDescriptorIconProvider.getIcon(descriptor, declaration, Iconable.ICON_FLAG_VISIBILITY))
|
||||
|
||||
when (descriptor) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class C {
|
||||
class Nested
|
||||
inner class Inner
|
||||
inner class Inner1
|
||||
inner class Inner2(s: String)
|
||||
}
|
||||
|
||||
fun foo(c: C) {
|
||||
@@ -8,4 +9,5 @@ fun foo(c: C) {
|
||||
}
|
||||
|
||||
// ABSENT: Nested
|
||||
// ABSENT: Inner
|
||||
// EXIST: { lookupString: "Inner1", itemText: "Inner1", tailText: "()", typeText: "C.Inner1" }
|
||||
// EXIST: { lookupString: "Inner2", itemText: "Inner2", tailText: "(s: String)", typeText: "C.Inner2" }
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
inner class Inner(s: String)
|
||||
}
|
||||
|
||||
fun foo(c: C) {
|
||||
c.<caret>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
inner class Inner(s: String)
|
||||
}
|
||||
|
||||
fun foo(c: C) {
|
||||
c.Inner(<caret>)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
trait T
|
||||
|
||||
class C {
|
||||
inner class Inner1(s: String) : T
|
||||
inner class Inner2 : T
|
||||
inner class Inner3
|
||||
class Nested: T
|
||||
}
|
||||
|
||||
fun foo(c: C): T {
|
||||
return c.<caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "Inner1", itemText: "Inner1", tailText: "(s: String)", typeText: "C.Inner1" }
|
||||
// EXIST: { lookupString: "Inner2", itemText: "Inner2", tailText: "()", typeText: "C.Inner2" }
|
||||
// ABSENT: Inner3
|
||||
// ABSENT: Nested
|
||||
// NUMBER: 2
|
||||
@@ -444,6 +444,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClass.kt")
|
||||
public void testInnerClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/InnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InsideIdentifier.kt")
|
||||
public void testInsideIdentifier() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/InsideIdentifier.kt");
|
||||
|
||||
@@ -168,4 +168,6 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
|
||||
fun testInfixCallOnSpace() = doTest(1, "to", null, null, ' ')
|
||||
|
||||
fun testImportedEnumMember() { doTest(1, "AAA", null, null, '\n') }
|
||||
|
||||
fun testInnerClass() { doTest(1, "Inner", null, null, '\n') }
|
||||
}
|
||||
Reference in New Issue
Block a user