diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt index b684059d1fa..97b858d5a08 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt @@ -16,26 +16,25 @@ package org.jetbrains.kotlin.cfg.pseudocode -import com.google.common.collect.Sets import com.intellij.psi.util.PsiTreeUtil -import com.intellij.util.SmartFMap -import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* +import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ConditionalJumpInstruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ReturnValueInstruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ThrowExceptionInstruction import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext +import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext.* import org.jetbrains.kotlin.resolve.DelegatingBindingTrace -import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets import org.jetbrains.kotlin.resolve.bindingContextUtil.getTargetFunctionDescriptor import org.jetbrains.kotlin.resolve.calls.ValueArgumentsToParametersMapper @@ -45,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverVa import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy +import org.jetbrains.kotlin.resolve.findTopMostOverriddenDescriptors import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils @@ -59,7 +59,7 @@ fun getReceiverTypePredicate(resolvedCall: ResolvedCall<*>, receiverValue: Recei if (receiverParameter != null) return receiverParameter.getType().getSubtypesPredicate() } resolvedCall.getDispatchReceiver() -> { - val rootCallableDescriptors = OverridingUtil.getTopmostOverridenDescriptors(callableDescriptor) + val rootCallableDescriptors = callableDescriptor.findTopMostOverriddenDescriptors() return or(rootCallableDescriptors.map { it.getDispatchReceiverParameter()?.getType()?.let { TypeUtils.makeNullableIfNeeded(it, resolvedCall.isSafeCall()) }?.getSubtypesPredicate() }.filterNotNull()) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java index 2095209fba5..045c0e51f9b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java @@ -30,7 +30,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeConstructor; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; -import org.jetbrains.kotlin.utils.DFS; import java.util.*; @@ -504,30 +503,6 @@ public class OverridingUtil { return maxVisibility; } - @NotNull - public static List getTopmostOverridenDescriptors(@NotNull CallableDescriptor originalDescriptor) { - return DFS.dfs( - Collections.singletonList(originalDescriptor), - new DFS.Neighbors() { - @NotNull - @Override - public Iterable getNeighbors(CallableDescriptor current) { - return current.getOverriddenDescriptors(); - } - }, - new DFS.CollectingNodeHandler>( - new ArrayList() - ) { - @Override - public void afterChildren(CallableDescriptor current) { - if (current.getOverriddenDescriptors().isEmpty()) { - result.add(current); - } - } - } - ); - } - public interface DescriptorSink { void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt index 9686a7abbc5..49690794864 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt @@ -17,8 +17,27 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.utils.DFS import java.util.* -fun CallableDescriptor.getOriginalTopmostOverriddenDescriptors(): Set { - return OverridingUtil.getTopmostOverridenDescriptors(this).mapTo(LinkedHashSet()) { it.original } +fun TDescriptor.findTopMostOverriddenDescriptors(): List { + return DFS.dfs( + listOf(this), + { current -> current.overriddenDescriptors }, + object : DFS.CollectingNodeHandler>(ArrayList()) { + override fun afterChildren(current: CallableDescriptor) { + if (current.overriddenDescriptors.isEmpty()) { + @Suppress("UNCHECKED_CAST") + result.add(current as TDescriptor) + } + } + }) +} + + +fun TDescriptor.findOriginalTopMostOverriddenDescriptors(): Set { + return findTopMostOverriddenDescriptors().mapTo(LinkedHashSet()) { + @Suppress("UNCHECKED_CAST") + (it.original as TDescriptor) + } } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt index 74cd26da33d..dfed7deb8c2 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf +import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.types.KotlinType @@ -62,9 +63,10 @@ class LookupElementFactory( private val superFunctions: Set by lazy { inDescriptor.parentsWithSelf + .takeWhile { it !is ClassDescriptor } .filterIsInstance() .toList() - .flatMap { it.overriddenDescriptors } + .flatMap { it.findOriginalTopMostOverriddenDescriptors() } .toSet() } @@ -155,7 +157,7 @@ class LookupElementFactory( private fun createSuperFunctionCallWithArguments(descriptor: FunctionDescriptor): LookupElement? { if (descriptor.valueParameters.isEmpty()) return null - if (descriptor !in superFunctions) return null + if (descriptor.findOriginalTopMostOverriddenDescriptors().none { it in superFunctions }) return null val argumentText = descriptor.valueParameters.map { (if (it.varargElementType != null) "*" else "") + it.name.render() diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt index 41f39bd7008..030e46857ae 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt @@ -32,7 +32,7 @@ import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.util.CallType import org.jetbrains.kotlin.idea.util.FuzzyType import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf -import org.jetbrains.kotlin.resolve.getOriginalTopmostOverriddenDescriptors +import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors object PriorityWeigher : LookupElementWeigher("kotlin.priority") { override fun weigh(element: LookupElement, context: WeighingContext) @@ -251,7 +251,7 @@ class PreferContextElementsWeigher(private val context: DeclarationDescriptor) : private val contextElements = context.parentsWithSelf .takeWhile { it !is PackageFragmentDescriptor } .toList() - .flatMap { if (it is CallableDescriptor) it.getOriginalTopmostOverriddenDescriptors() else listOf(it) } + .flatMap { if (it is CallableDescriptor) it.findOriginalTopMostOverriddenDescriptors() else listOf(it) } .toSet() private val contextElementNames = contextElements.map { it.name }.toSet() diff --git a/idea/idea-completion/testData/basic/common/SuperMembers3.kt b/idea/idea-completion/testData/basic/common/SuperMembers3.kt index 3674108e631..62ab1ee412c 100644 --- a/idea/idea-completion/testData/basic/common/SuperMembers3.kt +++ b/idea/idea-completion/testData/basic/common/SuperMembers3.kt @@ -1,6 +1,9 @@ -open class B { +open class A { open fun xxx_foo(p1: T, vararg p2: String) {} open fun xxx_bar(p1: Int, p2: String) {} +} + +open class B : A { open val xxx_val: Int = 0 } @@ -11,8 +14,8 @@ class C : B() { } // WITH_ORDER -// EXIST: { lookupString: "xxx_foo", itemText: "xxx_foo", tailText: "(p1, *p2)", typeText: "Unit", attributes: "bold" } -// EXIST: { lookupString: "xxx_foo", itemText: "xxx_foo", tailText: "(p1: String, vararg p2: String)", typeText: "Unit", attributes: "bold" } +// EXIST: { lookupString: "xxx_foo", itemText: "xxx_foo", tailText: "(p1, *p2)", typeText: "Unit", attributes: "" } +// EXIST: { lookupString: "xxx_foo", itemText: "xxx_foo", tailText: "(p1: String, vararg p2: String)", typeText: "Unit", attributes: "" } // EXIST: { lookupString: "xxx_val", itemText: "xxx_val", tailText: null, typeText: "Int", attributes: "bold" } -// EXIST: { lookupString: "xxx_bar", itemText: "xxx_bar", tailText: "(p1: Int, p2: String)", typeText: "Unit", attributes: "bold" } +// EXIST: { lookupString: "xxx_bar", itemText: "xxx_bar", tailText: "(p1: Int, p2: String)", typeText: "Unit", attributes: "" } // NOTHING_ELSE diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt index 9794e610da1..ef241c1358d 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.getOriginalTopmostOverriddenDescriptors +import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy @@ -88,8 +88,8 @@ public fun compareDescriptors(project: Project, currentDescriptor: DeclarationDe if (compareDescriptorsText(project, currentDescriptor, originalDescriptor)) return true if (originalDescriptor is CallableDescriptor && currentDescriptor is CallableDescriptor) { - val overriddenOriginalDescriptor = originalDescriptor.getOriginalTopmostOverriddenDescriptors() - val overriddenCurrentDescriptor = currentDescriptor.getOriginalTopmostOverriddenDescriptors() + val overriddenOriginalDescriptor = originalDescriptor.findOriginalTopMostOverriddenDescriptors() + val overriddenCurrentDescriptor = currentDescriptor.findOriginalTopMostOverriddenDescriptors() if (overriddenOriginalDescriptor.size != overriddenCurrentDescriptor.size) return false return overriddenCurrentDescriptor.zip(overriddenOriginalDescriptor).all { diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt index 1cb8657776a..6de8bd1effb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt @@ -48,7 +48,7 @@ import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.resolve.getOriginalTopmostOverriddenDescriptors +import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors import org.jetbrains.kotlin.resolve.source.getPsi public abstract class KotlinFindMemberUsagesHandler @@ -164,7 +164,7 @@ public abstract class KotlinFindMemberUsagesHandler override fun findReferencesToHighlight(target: PsiElement, searchScope: SearchScope): Collection { val callableDescriptor = (target as? KtCallableDeclaration)?.resolveToDescriptorIfAny() as? CallableDescriptor - val baseDescriptors = callableDescriptor?.getOriginalTopmostOverriddenDescriptors() ?: emptyList() + val baseDescriptors = callableDescriptor?.findOriginalTopMostOverriddenDescriptors() ?: emptyList() val baseDeclarations = baseDescriptors.map { it.source.getPsi() }.filter { it != null && it != target } return if (baseDeclarations.isNotEmpty()) {