From a7580d95e5cfa681d40de902c927dcf117b1b198 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 21 May 2015 22:17:12 +0300 Subject: [PATCH] Accessing of default parameter value in compiled code via source (if found) --- .../kotlin/idea/decompiler/KotlinClsFileBase.kt | 17 ++++++++++++++--- .../navigation/JetSourceNavigationHelper.java | 14 ++++++++++++++ .../idea/core/OptionalParametersHelper.kt | 11 ++++++++--- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt index 00665da80e0..80759daaedb 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/KotlinClsFileBase.kt @@ -20,18 +20,29 @@ import com.intellij.openapi.util.TextRange import com.intellij.psi.FileViewProvider import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.annotations.TestOnly +import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText -import org.jetbrains.kotlin.psi.JetDeclaration import org.jetbrains.kotlin.idea.decompiler.textBuilder.descriptorToKey -import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue +import org.jetbrains.kotlin.psi.JetCallableDeclaration +import org.jetbrains.kotlin.psi.JetDeclaration import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue public abstract class KotlinClsFileBase(provider: FileViewProvider) : JetFile(provider, true) { protected abstract val decompiledText: LockedClearableLazyValue public fun getDeclarationForDescriptor(descriptor: DeclarationDescriptor): JetDeclaration? { - val key = descriptorToKey(descriptor.getOriginal()) + val original = descriptor.getOriginal() + + if (original is ValueParameterDescriptor) { + val callable = original.getContainingDeclaration() as? CallableDescriptor ?: return null + val callableDeclaration = getDeclarationForDescriptor(callable) as? JetCallableDeclaration ?: return null + return callableDeclaration.getValueParameters()[original.getIndex()] + } + + val key = descriptorToKey(original) val range = decompiledText.get().renderedDescriptorsToRange[key] return if (range != null) { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JetSourceNavigationHelper.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JetSourceNavigationHelper.java index ad12d925f6c..4f4edcb4ffa 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JetSourceNavigationHelper.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/JetSourceNavigationHelper.java @@ -439,6 +439,20 @@ public class JetSourceNavigationHelper { public JetDeclaration visitClass(@NotNull JetClass klass, Void data) { return getSourceClassOrObject(klass); } + + @Override + public JetDeclaration visitParameter(@NotNull JetParameter parameter, Void data) { + PsiElement pparent = parameter.getParent().getParent(); + JetCallableDeclaration callableDeclaration = (JetCallableDeclaration) pparent; + List parameters = callableDeclaration.getValueParameters(); + int index = parameters.indexOf(parameter); + + JetCallableDeclaration sourceCallable = (JetCallableDeclaration) callableDeclaration.accept(this, null); + if (sourceCallable == null) return null; + List sourceParameters = sourceCallable.getValueParameters(); + if (sourceParameters.size() != parameters.size()) return null; + return sourceParameters.get(index); + } } private static class LibrarySourcesScope extends GlobalSearchScope { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/OptionalParametersHelper.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/OptionalParametersHelper.kt index d61f800537c..e24cda897f2 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/OptionalParametersHelper.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/OptionalParametersHelper.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.idea.decompiler.navigation.JetSourceNavigationHelper import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.psi.JetParameter import org.jetbrains.kotlin.psi.JetSimpleNameExpression @@ -118,10 +119,14 @@ public object OptionalParametersHelper { //TODO: handle implicit receivers public fun defaultParameterValue(parameter: ValueParameterDescriptor, project: Project): DefaultValue? { if (!parameter.hasDefaultValue()) return null + //TODO: parameter in overriding method! - val sourceParameter = DescriptorToSourceUtilsIde.getAnyDeclaration(project, parameter) as? JetParameter ?: return null - //TODO: use JetSourceNavigationHelper - val expression = sourceParameter.getDefaultValue() ?: return null + //TODO: it's a temporary code while we don't have default values accessible from descriptors + var declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, parameter) as? JetParameter ?: return null + if (declaration.getContainingJetFile().isCompiled()) { + declaration = JetSourceNavigationHelper.replaceBySourceDeclarationIfPresent(declaration) as? JetParameter ?: return null + } + val expression = declaration.getDefaultValue() ?: return null val allParameters = (parameter.getContainingDeclaration() as CallableDescriptor).getValueParameters().toSet()