Compare descriptors by topmost override

This commit is contained in:
Natalia Ukhorskaya
2015-10-07 13:43:17 +03:00
parent 17816002cc
commit 9f96de3f7b
3 changed files with 24 additions and 21 deletions
@@ -266,7 +266,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
val restrictedKindFilter = descriptorKindFilter!!.restrictedToKinds(DescriptorKindFilter.FUNCTIONS_MASK or DescriptorKindFilter.VARIABLES_MASK) // optimization
val descriptors = referenceVariantsHelper.getReferenceVariants(nameExpression!!, restrictedKindFilter, descriptorNameFilter, useRuntimeReceiverType = true)
return descriptors.filter { descriptor ->
referenceVariants.filter { it.name == descriptor.name }.none { comparePossiblyOverridingDescriptors(project, it, descriptor) }
referenceVariants.none { compareDescriptors(project, it, descriptor) }
}
}
@@ -19,11 +19,11 @@ package org.jetbrains.kotlin.idea.core
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
@@ -58,31 +58,34 @@ fun DeclarationDescriptorWithVisibility.isVisible(
return false
}
public fun compareDescriptors(project: Project, d1: DeclarationDescriptor?, d2: DeclarationDescriptor?): Boolean {
private fun compareDescriptorsText(project: Project, d1: DeclarationDescriptor?, d2: DeclarationDescriptor?): Boolean {
if (d1 == d2) return true
if (d1 == null || d2 == null) return false
if (d1.name != d2.name) return false
val renderedD1 = IdeDescriptorRenderers.SOURCE_CODE.render(d1)
val renderedD2 = IdeDescriptorRenderers.SOURCE_CODE.render(d2)
if (renderedD1 == renderedD2) return true
val declarations1 = DescriptorToSourceUtilsIde.getAllDeclarations(project, d1)
val declarations2 = DescriptorToSourceUtilsIde.getAllDeclarations(project, d2)
if (declarations1 == declarations2 && declarations1.isNotEmpty()) return true
return DescriptorRenderer.FQ_NAMES_IN_TYPES.render(d1) == DescriptorRenderer.FQ_NAMES_IN_TYPES.render(d2)
return false
}
public fun comparePossiblyOverridingDescriptors(project: Project,
currentDescriptor: DeclarationDescriptor?,
originalDescriptor: DeclarationDescriptor?): Boolean {
if (compareDescriptors(project, currentDescriptor, originalDescriptor)) return true
if (originalDescriptor is CallableDescriptor) {
if (!OverridingUtil.traverseOverridenDescriptors(originalDescriptor) { !compareDescriptors(project, currentDescriptor, it) }) return true
if (originalDescriptor !is CallableMemberDescriptor || currentDescriptor !is CallableMemberDescriptor) return false
val kind = originalDescriptor.getKind()
if (kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE && kind != CallableMemberDescriptor.Kind.DELEGATION) return false
if (currentDescriptor.getKind() != kind) return false
public fun compareDescriptors(project: Project, currentDescriptor: DeclarationDescriptor?, originalDescriptor: DeclarationDescriptor?): Boolean {
if (currentDescriptor?.name != originalDescriptor?.name) return false
val originalOverriddenDescriptors = originalDescriptor.getOverriddenDescriptors()
val currentOverriddenDescriptors = currentDescriptor.getOverriddenDescriptors()
if (originalOverriddenDescriptors.size() != currentOverriddenDescriptors.size()) return false
return (currentOverriddenDescriptors zip originalOverriddenDescriptors ).all {
comparePossiblyOverridingDescriptors(project, it.first, it.second)
if (compareDescriptorsText(project, currentDescriptor, originalDescriptor)) return true
if (originalDescriptor is CallableDescriptor && currentDescriptor is CallableDescriptor) {
val overriddenOriginalDescriptor = OverridingUtil.getTopmostOverridenDescriptors(originalDescriptor)
val overriddenCurrentDescriptor = OverridingUtil.getTopmostOverridenDescriptors(currentDescriptor)
if (overriddenOriginalDescriptor.size() != overriddenCurrentDescriptor.size()) return false
return (overriddenCurrentDescriptor zip overriddenOriginalDescriptor ).all {
compareDescriptorsText(project, it.first, it.second)
}
}
@@ -44,7 +44,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
import org.jetbrains.kotlin.idea.core.comparePossiblyOverridingDescriptors
import org.jetbrains.kotlin.idea.core.compareDescriptors
import org.jetbrains.kotlin.idea.core.getResolutionScope
import org.jetbrains.kotlin.idea.core.refactoring.createTempCopy
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
@@ -1031,7 +1031,7 @@ fun ExtractableCodeDescriptor.validate(): ExtractableCodeDescriptorWithConflicts
if (diagnostics.any { it.getFactory() in Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS }
|| (currentDescriptor != null
&& !ErrorUtils.isError(currentDescriptor)
&& !comparePossiblyOverridingDescriptors(extractionData.project, currentDescriptor, resolveResult.descriptor))) {
&& !compareDescriptors(extractionData.project, currentDescriptor, resolveResult.descriptor))) {
conflicts.putValue(
resolveResult.originalRefExpr,
getDeclarationMessage(resolveResult.declaration, "0.will.no.longer.be.accessible.after.extraction")