Unified obtaining psi element for descriptor. Now code for finding effective descriptors of fake override and finding source element for original declarations are separated. Old method DescriptorToSourceUtils.descriptorToDeclaration is still there, because it has ~90 usages.

This commit is contained in:
Evgeny Gerashchenko
2015-03-03 12:38:31 +03:00
parent a56b1da11f
commit 7b6f83815c
15 changed files with 94 additions and 131 deletions
@@ -18,38 +18,38 @@ package org.jetbrains.kotlin.idea.codeInsight
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.idea.decompiler.navigation.DecompiledNavigationUtils
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
import java.util.HashSet
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import com.intellij.psi.JavaPsiFacade
import org.jetbrains.kotlin.idea.search.allScope
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*
import java.util.*
import org.jetbrains.kotlin.descriptors.*
// TODO rename it it DescriptorToSourceIde
public object DescriptorToDeclarationUtil {
public fun getDeclaration(project: Project, descriptor: DeclarationDescriptor): PsiElement? {
var elements: Collection<PsiElement> = DescriptorToSourceUtils.descriptorToDeclarations(descriptor)
if (elements.isEmpty()) {
elements = findDecompiledAndBuiltInDeclarations(project, descriptor)
}
return elements.firstOrNull()
// TODO optimize it!
return resolveToPsiElements(project, descriptor).firstOrNull()
}
public fun resolveToPsiElements(project: Project, targetDescriptor: DeclarationDescriptor): Collection<PsiElement> {
val result = HashSet<PsiElement>()
// todo: remove getOriginal()
val originalDescriptor = targetDescriptor.getOriginal()
result.addAll(DescriptorToSourceUtils.descriptorToDeclarations(originalDescriptor))
result.addAll(DescriptorToDeclarationUtil.findDecompiledAndBuiltInDeclarations(project, originalDescriptor))
val effectiveReferencedDescriptors: Collection<DeclarationDescriptor> = DescriptorToSourceUtils.getEffectiveReferencedDescriptors(targetDescriptor)
if (originalDescriptor is PackageViewDescriptor) {
for (descriptor in effectiveReferencedDescriptors) {
result.addIfNotNull(DescriptorToSourceUtils.getSourceFromDescriptor(descriptor))
result.addIfNotNull(findBuiltinDeclaration(project, descriptor))
result.addIfNotNull(DecompiledNavigationUtils.getDeclarationFromDecompiledClassFile(project, descriptor))
}
if (targetDescriptor is PackageViewDescriptor) {
val psiFacade = JavaPsiFacade.getInstance(project)
val fqName = originalDescriptor.getFqName().asString()
val fqName = targetDescriptor.getFqName().asString()
result.addIfNotNull(psiFacade.findPackage(fqName))
result.addIfNotNull(psiFacade.findClass(fqName, project.allScope()))
}
@@ -58,17 +58,8 @@ public object DescriptorToDeclarationUtil {
return result.filter { element -> result.none { element != it && it.getNavigationElement() == element } }
}
private fun findDecompiledAndBuiltInDeclarations(project: Project, descriptor: DeclarationDescriptor): Collection<PsiElement> {
private fun findBuiltinDeclaration(project: Project, descriptor: DeclarationDescriptor): PsiElement? {
val libraryReferenceResolver = project.getComponent(javaClass<BuiltInsReferenceResolver>())
val elements = libraryReferenceResolver!!.resolveBuiltInSymbol(descriptor)
if (elements.isNotEmpty()) {
return elements
}
val decompiledDeclaration = DecompiledNavigationUtils.getDeclarationFromDecompiledClassFile(project, descriptor)
if (decompiledDeclaration != null) {
return setOf(decompiledDeclaration)
}
return setOf()
return libraryReferenceResolver!!.resolveBuiltInSymbol(descriptor)
}
}
@@ -45,8 +45,7 @@ public final class DecompiledNavigationUtils {
@NotNull Project project,
@NotNull DeclarationDescriptor referencedDescriptor
) {
DeclarationDescriptor effectiveReferencedDescriptor = getEffectiveReferencedDescriptor(referencedDescriptor);
VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, effectiveReferencedDescriptor);
VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor);
if (virtualFile == null || !DecompilerPackage.isKotlinCompiledFile(virtualFile)) return null;
@@ -55,19 +54,9 @@ public final class DecompiledNavigationUtils {
return null;
}
return ((JetClsFile) psiFile).getDeclarationForDescriptor(effectiveReferencedDescriptor);
return ((JetClsFile) psiFile).getDeclarationForDescriptor(referencedDescriptor);
}
//TODO: should be done via some generic mechanism
@NotNull
private static DeclarationDescriptor getEffectiveReferencedDescriptor(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof CallableMemberDescriptor) {
return DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor);
}
return descriptor;
}
/*
Find virtual file which contains the declaration of descriptor we're navigating to.
*/
@@ -57,7 +57,6 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.unwrapFakeOverride;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getClassId;
import static org.jetbrains.kotlin.serialization.deserialization.DeserializationPackage.findClassAcrossModuleDependencies;
@@ -186,11 +185,6 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
@Nullable
private DeclarationDescriptor findCurrentDescriptorForMember(@NotNull MemberDescriptor originalDescriptor) {
if (originalDescriptor instanceof CallableMemberDescriptor &&
((CallableMemberDescriptor) originalDescriptor).getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
return findCurrentDescriptorForMember(unwrapFakeOverride((CallableMemberDescriptor) originalDescriptor).getOriginal());
}
if (!isFromBuiltinModule(originalDescriptor)) return null;
DeclarationDescriptor containingDeclaration = findCurrentDescriptor(originalDescriptor.getContainingDeclaration());
@@ -240,17 +234,17 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
return KotlinBuiltIns.getInstance().getBuiltInsModule() == DescriptorUtils.getContainingModule(originalDescriptor);
}
@NotNull
public Collection<PsiElement> resolveBuiltInSymbol(@NotNull DeclarationDescriptor declarationDescriptor) {
@Nullable
public PsiElement resolveBuiltInSymbol(@NotNull DeclarationDescriptor declarationDescriptor) {
if (moduleDescriptor == null) {
return Collections.emptyList();
return null;
}
DeclarationDescriptor descriptor = findCurrentDescriptor(declarationDescriptor.getOriginal());
DeclarationDescriptor descriptor = findCurrentDescriptor(declarationDescriptor);
if (descriptor != null) {
return DescriptorToSourceUtils.descriptorToDeclarations(descriptor);
return DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
}
return Collections.emptyList();
return null;
}
public static boolean isFromBuiltIns(@NotNull PsiElement element) {