Navigation: Filter out candidate declarations coming from the wrong library

#KT-13726 In Progress
This commit is contained in:
Alexey Sedunov
2016-09-29 13:05:51 +03:00
parent 6c2d4ad8eb
commit ba1ee99e97
5 changed files with 44 additions and 3 deletions
@@ -36,6 +36,8 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.StringStubIndexExtension;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -199,6 +201,8 @@ public class SourceNavigationHelper {
return null;
}
candidates = filterByOrderEntries(declaration, candidates);
if (!forceResolve) {
candidates = filterByReceiverPresenceAndParametersCount(declaration, candidates);
@@ -340,6 +344,26 @@ public class SourceNavigationHelper {
});
}
@NotNull
private static List<KtNamedDeclaration> filterByOrderEntries(
@NotNull KtNamedDeclaration declaration,
@NotNull Collection<KtNamedDeclaration> candidates
) {
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(declaration.getProject()).getFileIndex();
final List<OrderEntry> orderEntries = fileIndex.getOrderEntriesForFile(declaration.getContainingFile().getVirtualFile());
return CollectionsKt.filter(
candidates,
new Function1<KtNamedDeclaration, Boolean>() {
@Override
public Boolean invoke(KtNamedDeclaration candidate) {
List<OrderEntry> candidateOrderEntries = fileIndex.getOrderEntriesForFile(candidate.getContainingFile().getVirtualFile());
return ContainerUtil.intersects(orderEntries, candidateOrderEntries);
}
}
);
}
@NotNull
private static List<KtNamedDeclaration> filterByReceiverPresenceAndParametersCount(
final @NotNull KtNamedDeclaration decompiledDeclaration,
@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.idea.decompiler.navigation
import com.intellij.openapi.project.Project
import com.intellij.psi.search.EverythingGlobalScope
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.*
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledTextIndexer
import org.jetbrains.kotlin.idea.stubindex.*
@@ -33,6 +35,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
import org.jetbrains.kotlin.types.ErrorUtils
import java.util.*
@@ -47,7 +50,19 @@ fun findDecompiledDeclaration(
val decompiledFiles = findDecompiledFilesForDescriptor(project, referencedDescriptor)
val referencedModule = referencedDescriptor.module
return decompiledFiles.asSequence().mapNotNull { file ->
val moduleInfo = file.getNullableModuleInfo()
val libraryInfo = when (moduleInfo) {
is LibraryInfo -> moduleInfo
is LibrarySourceInfo -> LibraryInfo(project, moduleInfo.library)
else -> null
}
val libraryModule = libraryInfo?.let { file.getResolutionFacade().findModuleDescriptor(it) }
if (libraryModule != null
&& referencedModule.name != KotlinBuiltIns.BUILTINS_MODULE_NAME
&& referencedModule.name != libraryModule.name) return@mapNotNull null
ByDescriptorIndexer.getDeclarationForDescriptor(referencedDescriptor, file)
}.firstOrNull()
}