Static members completion works in smart completion + fixed incorrect finding of java method descriptor that caused duplicated items
This commit is contained in:
+11
@@ -20,6 +20,7 @@ package org.jetbrains.kotlin.idea.caches.resolve
|
|||||||
|
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||||
@@ -47,6 +48,16 @@ fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiMethod.getJavaMethodDescriptor(resolutionFacade: ResolutionFacade): FunctionDescriptor? {
|
||||||
|
val method = originalElement as? PsiMethod ?: return null
|
||||||
|
if (method.containingClass == null || !Name.isValidIdentifier(method.name)) return null
|
||||||
|
val resolver = resolutionFacade.getFrontendService(method, JavaDescriptorResolver::class.java)
|
||||||
|
return when {
|
||||||
|
method.isConstructor -> resolver.resolveConstructor(JavaConstructorImpl(method))
|
||||||
|
else -> resolver.resolveMethod(JavaMethodImpl(method))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun PsiClass.getJavaClassDescriptor(): ClassDescriptor? {
|
fun PsiClass.getJavaClassDescriptor(): ClassDescriptor? {
|
||||||
val psiClass = originalElement as? PsiClass ?: return null
|
val psiClass = originalElement as? PsiClass ?: return null
|
||||||
return psiClass.getJavaDescriptorResolver()?.resolveClass(JavaClassImpl(psiClass))
|
return psiClass.getJavaDescriptorResolver()?.resolveClass(JavaClassImpl(psiClass))
|
||||||
|
|||||||
+3
-3
@@ -215,9 +215,9 @@ class BasicCompletionSession(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val staticMembersCompletion = StaticMembersCompletion(
|
val staticMembersCompletion = StaticMembersCompletion(
|
||||||
collector, prefixMatcher, resolutionFacade, lookupElementFactory, referenceVariants!!.imported, isJvmModule)
|
prefixMatcher, resolutionFacade, lookupElementFactory, referenceVariants!!.imported, isJvmModule)
|
||||||
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
|
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
|
||||||
staticMembersCompletion.completeFromImports(position.containingFile as KtFile)
|
staticMembersCompletion.completeFromImports(file, collector)
|
||||||
}
|
}
|
||||||
|
|
||||||
completeNonImported(lookupElementFactory)
|
completeNonImported(lookupElementFactory)
|
||||||
@@ -235,7 +235,7 @@ class BasicCompletionSession(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.completeStaticMembers && callTypeAndReceiver is CallTypeAndReceiver.DEFAULT && prefix.isNotEmpty()) {
|
if (configuration.completeStaticMembers && callTypeAndReceiver is CallTypeAndReceiver.DEFAULT && prefix.isNotEmpty()) {
|
||||||
staticMembersCompletion.completeFromIndices(indicesHelper(false))
|
staticMembersCompletion.completeFromIndices(indicesHelper(false), collector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ abstract class CompletionSession(
|
|||||||
resultSet: CompletionResultSet
|
resultSet: CompletionResultSet
|
||||||
) {
|
) {
|
||||||
protected val position = parameters.getPosition()
|
protected val position = parameters.getPosition()
|
||||||
private val file = position.getContainingFile() as KtFile
|
protected val file = position.getContainingFile() as KtFile
|
||||||
protected val resolutionFacade = file.getResolutionFacade()
|
protected val resolutionFacade = file.getResolutionFacade()
|
||||||
protected val moduleDescriptor = resolutionFacade.moduleDescriptor
|
protected val moduleDescriptor = resolutionFacade.moduleDescriptor
|
||||||
protected val project = position.getProject()
|
protected val project = position.getProject()
|
||||||
|
|||||||
+18
-6
@@ -42,6 +42,18 @@ import org.jetbrains.kotlin.types.TypeUtils
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
|
interface AbstractLookupElementFactory {
|
||||||
|
fun createStandardLookupElementsForDescriptor(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean): Collection<LookupElement>
|
||||||
|
|
||||||
|
fun createLookupElement(
|
||||||
|
descriptor: DeclarationDescriptor,
|
||||||
|
useReceiverTypes: Boolean,
|
||||||
|
qualifyNestedClasses: Boolean = false,
|
||||||
|
includeClassTypeArguments: Boolean = true,
|
||||||
|
parametersAndTypeGrayed: Boolean = false
|
||||||
|
): LookupElement?
|
||||||
|
}
|
||||||
|
|
||||||
data /* we need copy() */
|
data /* we need copy() */
|
||||||
class LookupElementFactory(
|
class LookupElementFactory(
|
||||||
val basicFactory: BasicLookupElementFactory,
|
val basicFactory: BasicLookupElementFactory,
|
||||||
@@ -50,7 +62,7 @@ class LookupElementFactory(
|
|||||||
private val inDescriptor: DeclarationDescriptor,
|
private val inDescriptor: DeclarationDescriptor,
|
||||||
private val contextVariablesProvider: ContextVariablesProvider,
|
private val contextVariablesProvider: ContextVariablesProvider,
|
||||||
private val standardLookupElementsPostProcessor: (LookupElement) -> LookupElement = { it }
|
private val standardLookupElementsPostProcessor: (LookupElement) -> LookupElement = { it }
|
||||||
) {
|
) : AbstractLookupElementFactory {
|
||||||
companion object {
|
companion object {
|
||||||
fun hasSingleFunctionTypeParameter(descriptor: FunctionDescriptor): Boolean {
|
fun hasSingleFunctionTypeParameter(descriptor: FunctionDescriptor): Boolean {
|
||||||
val parameter = descriptor.original.valueParameters.singleOrNull() ?: return false
|
val parameter = descriptor.original.valueParameters.singleOrNull() ?: return false
|
||||||
@@ -69,7 +81,7 @@ class LookupElementFactory(
|
|||||||
.toSet()
|
.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun createStandardLookupElementsForDescriptor(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean): Collection<LookupElement> {
|
override fun createStandardLookupElementsForDescriptor(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean): Collection<LookupElement> {
|
||||||
val result = SmartList<LookupElement>()
|
val result = SmartList<LookupElement>()
|
||||||
|
|
||||||
val isNormalCall = callType == CallType.DEFAULT || callType == CallType.DOT || callType == CallType.SAFE || callType == CallType.SUPER_MEMBERS
|
val isNormalCall = callType == CallType.DEFAULT || callType == CallType.DOT || callType == CallType.SAFE || callType == CallType.SUPER_MEMBERS
|
||||||
@@ -197,12 +209,12 @@ class LookupElementFactory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun createLookupElement(
|
override fun createLookupElement(
|
||||||
descriptor: DeclarationDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
useReceiverTypes: Boolean,
|
useReceiverTypes: Boolean,
|
||||||
qualifyNestedClasses: Boolean = false,
|
qualifyNestedClasses: Boolean,
|
||||||
includeClassTypeArguments: Boolean = true,
|
includeClassTypeArguments: Boolean,
|
||||||
parametersAndTypeGrayed: Boolean = false
|
parametersAndTypeGrayed: Boolean
|
||||||
): LookupElement {
|
): LookupElement {
|
||||||
var element = basicFactory.createLookupElement(descriptor, qualifyNestedClasses, includeClassTypeArguments, parametersAndTypeGrayed)
|
var element = basicFactory.createLookupElement(descriptor, qualifyNestedClasses, includeClassTypeArguments, parametersAndTypeGrayed)
|
||||||
|
|
||||||
|
|||||||
+40
-20
@@ -30,10 +30,10 @@ import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class StaticMembersCompletion(
|
class StaticMembersCompletion(
|
||||||
private val collector: LookupElementsCollector,
|
|
||||||
private val prefixMatcher: PrefixMatcher,
|
private val prefixMatcher: PrefixMatcher,
|
||||||
private val resolutionFacade: ResolutionFacade,
|
private val resolutionFacade: ResolutionFacade,
|
||||||
private val lookupElementFactory: LookupElementFactory,
|
private val lookupElementFactory: LookupElementFactory,
|
||||||
@@ -44,8 +44,24 @@ class StaticMembersCompletion(
|
|||||||
if (it is ImportedFromObjectCallableDescriptor<*>) it.callableFromObject else it
|
if (it is ImportedFromObjectCallableDescriptor<*>) it.callableFromObject else it
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: include it in smart completion?
|
fun decoratedLookupElementFactory(itemPriority: ItemPriority): AbstractLookupElementFactory {
|
||||||
fun completeFromImports(file: KtFile) {
|
return object : AbstractLookupElementFactory {
|
||||||
|
override fun createStandardLookupElementsForDescriptor(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean): Collection<LookupElement> {
|
||||||
|
if (!useReceiverTypes) return emptyList()
|
||||||
|
return lookupElementFactory.createLookupElement(descriptor, useReceiverTypes = false)
|
||||||
|
.decorateAsStaticMember(descriptor, classNameAsLookupString = false)
|
||||||
|
?.assignPriority(itemPriority)
|
||||||
|
?.suppressAutoInsertion()
|
||||||
|
.singletonOrEmptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createLookupElement(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean,
|
||||||
|
qualifyNestedClasses: Boolean, includeClassTypeArguments: Boolean,
|
||||||
|
parametersAndTypeGrayed: Boolean) = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun membersFromImports(file: KtFile): Collection<DeclarationDescriptor> {
|
||||||
val containers = file.importDirectives
|
val containers = file.importDirectives
|
||||||
.filter { !it.isAllUnder }
|
.filter { !it.isAllUnder }
|
||||||
.map {
|
.map {
|
||||||
@@ -54,42 +70,46 @@ class StaticMembersCompletion(
|
|||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
|
val result = ArrayList<DeclarationDescriptor>()
|
||||||
for (container in containers) {
|
for (container in containers) {
|
||||||
val memberScope = if (container.kind == ClassKind.OBJECT) container.unsubstitutedMemberScope else container.staticScope
|
val memberScope = if (container.kind == ClassKind.OBJECT) container.unsubstitutedMemberScope else container.staticScope
|
||||||
val members = memberScope.getDescriptorsFiltered(DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions, prefixMatcher.asNameFilter())
|
val members = memberScope.getDescriptorsFiltered(DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions, prefixMatcher.asNameFilter())
|
||||||
for (member in members) {
|
members.filterTo(result) { it is CallableDescriptor && it !in alreadyAdded } //TODO: substitution
|
||||||
if (member is CallableDescriptor) {
|
|
||||||
addFromDescriptor(member, ItemPriority.STATIC_MEMBER_FROM_IMPORTS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: filter out those that are accessible from SmartCompletion.additionalItems
|
//TODO: filter out those that are accessible from SmartCompletion.additionalItems
|
||||||
//TODO: what about enum members?
|
//TODO: what about enum members?
|
||||||
//TODO: better presentation for lookup elements from imports too
|
//TODO: better presentation for lookup elements from imports too
|
||||||
//TODO: from the same file
|
//TODO: from the same file
|
||||||
fun completeFromIndices(indicesHelper: KotlinIndicesHelper) {
|
|
||||||
|
fun membersFromIndices(indicesHelper: KotlinIndicesHelper): Collection<DeclarationDescriptor> {
|
||||||
val descriptorKindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions
|
val descriptorKindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions
|
||||||
val nameFilter: (String) -> Boolean = { prefixMatcher.prefixMatches(it) }
|
val nameFilter: (String) -> Boolean = { prefixMatcher.prefixMatches(it) }
|
||||||
|
|
||||||
|
val result = ArrayList<DeclarationDescriptor>()
|
||||||
|
|
||||||
if (isJvmModule) {
|
if (isJvmModule) {
|
||||||
indicesHelper.getJavaStaticMembers(descriptorKindFilter, nameFilter).forEach { addFromDescriptor(it, ItemPriority.STATIC_MEMBER) }
|
indicesHelper.getJavaStaticMembers(descriptorKindFilter, nameFilter).filterTo(result) { it !in alreadyAdded } //TODO: substitution
|
||||||
}
|
}
|
||||||
|
|
||||||
indicesHelper.getObjectMembers(descriptorKindFilter, nameFilter).forEach { addFromDescriptor(it, ItemPriority.STATIC_MEMBER) }
|
indicesHelper.getObjectMembers(descriptorKindFilter, nameFilter).filterTo(result) { it !in alreadyAdded } //TODO: substitution
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addFromDescriptor(member: CallableDescriptor, itemPriority: ItemPriority) {
|
fun completeFromImports(file: KtFile, collector: LookupElementsCollector) {
|
||||||
if (member !in alreadyAdded) { //TODO: substitution
|
val factory = decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER_FROM_IMPORTS)
|
||||||
collector.addElement(createLookupElement(member, itemPriority) ?: return)
|
membersFromImports(file)
|
||||||
}
|
.flatMap { factory.createStandardLookupElementsForDescriptor(it, useReceiverTypes = true) }
|
||||||
|
.forEach { collector.addElement(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLookupElement(descriptor: CallableDescriptor, itemPriority: ItemPriority): LookupElement? {
|
fun completeFromIndices(indicesHelper: KotlinIndicesHelper, collector: LookupElementsCollector) {
|
||||||
return lookupElementFactory.createLookupElement(descriptor, useReceiverTypes = false)
|
val factory = decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER)
|
||||||
.decorateAsStaticMember(descriptor, classNameAsLookupString = false)
|
membersFromIndices(indicesHelper)
|
||||||
?.assignPriority(itemPriority)
|
.flatMap { factory.createStandardLookupElementsForDescriptor(it, useReceiverTypes = true) }
|
||||||
?.suppressAutoInsertion()
|
.forEach { collector.addElement(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -83,9 +83,9 @@ class SmartCompletion(
|
|||||||
SmartCastCalculator(bindingContext, resolutionFacade.moduleDescriptor, expression, resolutionFacade)
|
SmartCastCalculator(bindingContext, resolutionFacade.moduleDescriptor, expression, resolutionFacade)
|
||||||
}
|
}
|
||||||
|
|
||||||
public val descriptorFilter: ((DeclarationDescriptor, LookupElementFactory) -> Collection<LookupElement>)? =
|
public val descriptorFilter: ((DeclarationDescriptor, AbstractLookupElementFactory) -> Collection<LookupElement>)? =
|
||||||
{ descriptor: DeclarationDescriptor, lookupElementFactory: LookupElementFactory ->
|
{ descriptor: DeclarationDescriptor, factory: AbstractLookupElementFactory ->
|
||||||
filterDescriptor(descriptor, lookupElementFactory).map { postProcess(it) }
|
filterDescriptor(descriptor, factory).map { postProcess(it) }
|
||||||
}.check { expectedInfos.isNotEmpty() }
|
}.check { expectedInfos.isNotEmpty() }
|
||||||
|
|
||||||
public fun additionalItems(lookupElementFactory: LookupElementFactory): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
public fun additionalItems(lookupElementFactory: LookupElementFactory): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
||||||
@@ -154,7 +154,7 @@ class SmartCompletion(
|
|||||||
return@lazy emptySet()
|
return@lazy emptySet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filterDescriptor(descriptor: DeclarationDescriptor, lookupElementFactory: LookupElementFactory): Collection<LookupElement> {
|
private fun filterDescriptor(descriptor: DeclarationDescriptor, lookupElementFactory: AbstractLookupElementFactory): Collection<LookupElement> {
|
||||||
val callType = callTypeAndReceiver.callType
|
val callType = callTypeAndReceiver.callType
|
||||||
if (descriptor in descriptorsToSkip) return emptyList()
|
if (descriptor in descriptorsToSkip) return emptyList()
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ class SmartCompletion(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableCollection<LookupElement>.addCallableReferenceLookupElements(descriptor: DeclarationDescriptor, lookupElementFactory: LookupElementFactory) {
|
private fun MutableCollection<LookupElement>.addCallableReferenceLookupElements(descriptor: DeclarationDescriptor, lookupElementFactory: AbstractLookupElementFactory) {
|
||||||
if (callableTypeExpectedInfo.isEmpty()) return
|
if (callableTypeExpectedInfo.isEmpty()) return
|
||||||
|
|
||||||
fun toLookupElement(descriptor: CallableDescriptor): LookupElement? {
|
fun toLookupElement(descriptor: CallableDescriptor): LookupElement? {
|
||||||
|
|||||||
+19
@@ -107,6 +107,18 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
|||||||
flushToResultSet()
|
flushToResultSet()
|
||||||
|
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
|
val staticMembersCompletion: StaticMembersCompletion?
|
||||||
|
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
|
||||||
|
staticMembersCompletion = StaticMembersCompletion(prefixMatcher, resolutionFacade, lookupElementFactory, referenceVariants!!.imported, isJvmModule)
|
||||||
|
val decoratedFactory = staticMembersCompletion.decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER_FROM_IMPORTS)
|
||||||
|
staticMembersCompletion.membersFromImports(file)
|
||||||
|
.flatMap { filter(it, decoratedFactory) }
|
||||||
|
.forEach { collector.addElement(it) }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
staticMembersCompletion = null
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldCompleteTopLevelCallablesFromIndex()) {
|
if (shouldCompleteTopLevelCallablesFromIndex()) {
|
||||||
getTopLevelCallables().forEach { collector.addElements(filter(it, lookupElementFactory), notImported = true) }
|
getTopLevelCallables().forEach { collector.addElements(filter(it, lookupElementFactory), notImported = true) }
|
||||||
flushToResultSet()
|
flushToResultSet()
|
||||||
@@ -122,6 +134,13 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
|||||||
flushToResultSet()
|
flushToResultSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (staticMembersCompletion != null && configuration.completeStaticMembers) {
|
||||||
|
val decoratedFactory = staticMembersCompletion.decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER)
|
||||||
|
staticMembersCompletion.membersFromIndices(indicesHelper(false))
|
||||||
|
.flatMap { filter(it, decoratedFactory) }
|
||||||
|
.forEach { collector.addElement(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fun foo(r: Runnable){}
|
||||||
|
|
||||||
|
fun bar(){
|
||||||
|
foo(<caret>)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 2
|
||||||
|
// ELEMENT_TEXT: Thread.currentThread
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fun foo(r: Runnable){}
|
||||||
|
|
||||||
|
fun bar(){
|
||||||
|
foo(Thread.currentThread())<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 2
|
||||||
|
// ELEMENT_TEXT: Thread.currentThread
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package dependency1
|
||||||
|
|
||||||
|
import test.C
|
||||||
|
|
||||||
|
object O1 {
|
||||||
|
fun foo(): C = C()
|
||||||
|
fun bar(): C = C()
|
||||||
|
fun x(): String = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dependency2
|
||||||
|
|
||||||
|
import test.C
|
||||||
|
|
||||||
|
object O2 {
|
||||||
|
fun foo(): C = C()
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import test.C
|
||||||
|
|
||||||
|
public class JavaClass1 {
|
||||||
|
public static C f() {
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static C g() {
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int h() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import test.C
|
||||||
|
|
||||||
|
public class JavaClass2 {
|
||||||
|
public static C f() {
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static C g() {
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import dependency1.O1.foo
|
||||||
|
import JavaClass1.f
|
||||||
|
|
||||||
|
class C
|
||||||
|
|
||||||
|
fun foo(): C {
|
||||||
|
return <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 1
|
||||||
|
|
||||||
|
// EXIST: { allLookupStrings: "bar", itemText: "O1.bar", tailText: "() (dependency1)", attributes: "" }
|
||||||
|
// EXIST: { itemText: "foo", tailText: "()", attributes: "" }
|
||||||
|
// ABSENT: { itemText: "O1.foo" }
|
||||||
|
// ABSENT: { itemText: "O2.foo" }
|
||||||
|
|
||||||
|
// EXIST: { allLookupStrings: "g", itemText: "JavaClass1.g", tailText: "() (<root>)", attributes: "" }
|
||||||
|
// EXIST: { itemText: "f", tailText: "()", attributes: "" }
|
||||||
|
// ABSENT: { itemText: "JavaClass1.f" }
|
||||||
|
// ABSENT: { itemText: "JavaClass1.h" }
|
||||||
|
// ABSENT: { itemText: "JavaClass2.f" }
|
||||||
|
// ABSENT: { itemText: "JavaClass2.g" }
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package dependency1
|
||||||
|
|
||||||
|
import test.C
|
||||||
|
|
||||||
|
object O1 {
|
||||||
|
fun foo(): C = C()
|
||||||
|
fun bar(): C = C()
|
||||||
|
fun x(): String = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dependency2
|
||||||
|
|
||||||
|
import test.C
|
||||||
|
|
||||||
|
object O2 {
|
||||||
|
fun foo(): C = C()
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import test.C
|
||||||
|
|
||||||
|
public class JavaClass1 {
|
||||||
|
public static C f() {
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static C g() {
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int h() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import test.C
|
||||||
|
|
||||||
|
public class JavaClass2 {
|
||||||
|
public static C f() {
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int g() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import dependency1.O1.foo
|
||||||
|
import JavaClass1.f
|
||||||
|
|
||||||
|
class C
|
||||||
|
|
||||||
|
fun foo(): C {
|
||||||
|
return <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION_COUNT: 2
|
||||||
|
|
||||||
|
// EXIST: { allLookupStrings: "bar", itemText: "O1.bar", tailText: "() (dependency1)", attributes: "" }
|
||||||
|
// EXIST: { itemText: "foo", tailText: "()", attributes: "" }
|
||||||
|
// ABSENT: { itemText: "O1.foo" }
|
||||||
|
// EXIST: { allLookupStrings: "foo", itemText: "O2.foo", tailText: "() (dependency2)", attributes: "" }
|
||||||
|
|
||||||
|
// EXIST: { allLookupStrings: "g", itemText: "JavaClass1.g", tailText: "() (<root>)", attributes: "" }
|
||||||
|
// EXIST: { itemText: "f", tailText: "()", attributes: "" }
|
||||||
|
// ABSENT: { itemText: "JavaClass1.f" }
|
||||||
|
// ABSENT: { itemText: "JavaClass1.h" }
|
||||||
|
// EXIST: { itemText: "JavaClass2.f" }
|
||||||
|
// ABSENT: { itemText: "JavaClass2.g" }
|
||||||
+12
@@ -136,4 +136,16 @@ public class MultiFileSmartCompletionTestGenerated extends AbstractMultiFileSmar
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smartMultiFile/NoObjectDuplication/");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smartMultiFile/NoObjectDuplication/");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StaticMembers1")
|
||||||
|
public void testStaticMembers1() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smartMultiFile/StaticMembers1/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StaticMembers2")
|
||||||
|
public void testStaticMembers2() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smartMultiFile/StaticMembers2/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -491,6 +491,12 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("JavaStaticMethod2.kt")
|
||||||
|
public void testJavaStaticMethod2() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/JavaStaticMethod2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("JavaStaticMethodInsertsImport.kt")
|
@TestMetadata("JavaStaticMethodInsertsImport.kt")
|
||||||
public void testJavaStaticMethodInsertsImport() throws Exception {
|
public void testJavaStaticMethodInsertsImport() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt");
|
||||||
|
|||||||
+6
-6
@@ -149,18 +149,18 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("SuperMembers.kt")
|
|
||||||
public void testSuperMembers() throws Exception {
|
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/SuperMembers.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("StaticMembers.kt")
|
@TestMetadata("StaticMembers.kt")
|
||||||
public void testStaticMembers() throws Exception {
|
public void testStaticMembers() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/StaticMembers.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/StaticMembers.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SuperMembers.kt")
|
||||||
|
public void testSuperMembers() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/SuperMembers.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo")
|
@TestMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ public class KotlinIndicesHelper(
|
|||||||
for (method in shortNamesCache.getMethodsByName(name, scope)) {
|
for (method in shortNamesCache.getMethodsByName(name, scope)) {
|
||||||
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue
|
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue
|
||||||
if (!visibilityFilterMayIncludeAccessible && method.hasModifierProperty(PsiModifier.PRIVATE)) continue
|
if (!visibilityFilterMayIncludeAccessible && method.hasModifierProperty(PsiModifier.PRIVATE)) continue
|
||||||
val descriptor = method.getJavaMethodDescriptor() ?: continue
|
val descriptor = method.getJavaMethodDescriptor(resolutionFacade) ?: continue
|
||||||
val container = descriptor.containingDeclaration as? ClassDescriptor ?: continue
|
val container = descriptor.containingDeclaration as? ClassDescriptor ?: continue
|
||||||
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
|
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
|
||||||
result.add(descriptor)
|
result.add(descriptor)
|
||||||
|
|||||||
Reference in New Issue
Block a user