Parameter info fetches default parameter values from library sources
This commit is contained in:
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import java.util.*
|
||||
|
||||
public object OptionalParametersHelper {
|
||||
@@ -114,26 +115,30 @@ public object OptionalParametersHelper {
|
||||
public val parameterUsages: Map<ValueParameterDescriptor, Collection<JetExpression>>
|
||||
)
|
||||
|
||||
//TODO: handle imports
|
||||
//TODO: handle implicit receivers
|
||||
public fun defaultParameterValue(parameter: ValueParameterDescriptor, project: Project): DefaultValue? {
|
||||
public fun defaultParameterValueExpression(parameter: ValueParameterDescriptor, project: Project): JetExpression? {
|
||||
if (!parameter.hasDefaultValue()) return null
|
||||
|
||||
if (!parameter.declaresDefaultValue()) {
|
||||
val overridden = parameter.getOverriddenDescriptors().firstOrNull { it.hasDefaultValue() } ?: return null
|
||||
return defaultParameterValue(overridden, project)
|
||||
return defaultParameterValueExpression(overridden, project)
|
||||
}
|
||||
|
||||
//TODO: parameter in overriding method!
|
||||
//TODO: it's a temporary code while we don't have default values accessible from descriptors
|
||||
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, parameter)?.getNavigationElement() as? JetParameter
|
||||
val expression = declaration?.getDefaultValue() ?: return null
|
||||
return declaration?.defaultValue
|
||||
}
|
||||
|
||||
//TODO: handle imports
|
||||
//TODO: handle implicit receivers
|
||||
public fun defaultParameterValue(parameter: ValueParameterDescriptor, project: Project): DefaultValue? {
|
||||
val expression = defaultParameterValueExpression(parameter, project) ?: return null
|
||||
|
||||
val allParameters = parameter.getContainingDeclaration().getValueParameters().toSet()
|
||||
|
||||
val parameterUsages = HashMap<ValueParameterDescriptor, MutableCollection<JetExpression>>()
|
||||
|
||||
val bindingContext = expression.analyze()
|
||||
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL)
|
||||
expression.forEachDescendantOfType<JetSimpleNameExpression> {
|
||||
val target = bindingContext[BindingContext.REFERENCE_TARGET, it]
|
||||
if (target is ValueParameterDescriptor && target in allParameters) {
|
||||
|
||||
+23
-20
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.idea.parameterInfo
|
||||
import com.intellij.codeInsight.CodeInsightBundle
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.lang.parameterInfo.*
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.ui.Gray
|
||||
import com.intellij.ui.JBColor
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.core.OptionalParametersHelper
|
||||
import org.jetbrains.kotlin.idea.core.getResolutionScope
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
||||
@@ -146,6 +147,8 @@ class KotlinFunctionParameterInfoHandler : ParameterInfoHandlerWithTabActionSupp
|
||||
val callElement = argumentList.parent as? JetCallElement ?: return false
|
||||
val call = callElement.getCall(bindingContext) ?: return false
|
||||
|
||||
val project = callElement.project
|
||||
|
||||
val currentParameterIndex = context.currentParameterIndex
|
||||
if (currentParameterIndex < 0) return false // by some strange reason we are invoked with currentParameterIndex == -1 during initialization
|
||||
|
||||
@@ -169,7 +172,7 @@ class KotlinFunctionParameterInfoHandler : ParameterInfoHandlerWithTabActionSupp
|
||||
boldStartOffset = length()
|
||||
}
|
||||
|
||||
append(renderParameter(parameter, namedMode))
|
||||
append(renderParameter(parameter, namedMode, project))
|
||||
|
||||
if (highlightParameter) {
|
||||
boldEndOffset = length()
|
||||
@@ -214,40 +217,40 @@ class KotlinFunctionParameterInfoHandler : ParameterInfoHandlerWithTabActionSupp
|
||||
companion object {
|
||||
val GREEN_BACKGROUND: Color = JBColor(Color(231, 254, 234), Gray._100)
|
||||
|
||||
private fun renderParameter(parameter: ValueParameterDescriptor, named: Boolean): String {
|
||||
private fun renderParameter(parameter: ValueParameterDescriptor, named: Boolean, project: Project): String {
|
||||
return StringBuilder {
|
||||
if (named) append("[")
|
||||
|
||||
if (parameter.varargElementType != null) {
|
||||
append("vararg ")
|
||||
}
|
||||
append(parameter.name)
|
||||
append(": ")
|
||||
append(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(parameterTypeToRender(parameter)))
|
||||
|
||||
if (parameter.hasDefaultValue()) {
|
||||
val parameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(parameter)
|
||||
append(" = ")
|
||||
append(getDefaultExpressionString(parameterDeclaration))
|
||||
append(parameter.renderDefaultValue(project))
|
||||
}
|
||||
|
||||
if (named) append("]")
|
||||
}.toString()
|
||||
}
|
||||
|
||||
private fun getDefaultExpressionString(parameterDeclaration: PsiElement?): String {
|
||||
if (parameterDeclaration is JetParameter) {
|
||||
val defaultValue = parameterDeclaration.defaultValue
|
||||
if (defaultValue != null) {
|
||||
val defaultExpression = defaultValue.text
|
||||
if (defaultExpression.length() <= 32) {
|
||||
return defaultExpression
|
||||
}
|
||||
private fun ValueParameterDescriptor.renderDefaultValue(project: Project): String {
|
||||
val expression = OptionalParametersHelper.defaultParameterValueExpression(this, project)
|
||||
if (expression != null) {
|
||||
val text = expression.text
|
||||
if (text.length() <= 32) {
|
||||
return text
|
||||
}
|
||||
|
||||
if (defaultValue is JetConstantExpression || defaultValue is JetStringTemplateExpression) {
|
||||
if (defaultExpression.startsWith("\"")) {
|
||||
return "\"...\""
|
||||
}
|
||||
else if (defaultExpression.startsWith("\'")) {
|
||||
return "\'...\'"
|
||||
}
|
||||
if (expression is JetConstantExpression || expression is JetStringTemplateExpression) {
|
||||
if (text.startsWith("\"")) {
|
||||
return "\"...\""
|
||||
}
|
||||
else if (text.startsWith("\'")) {
|
||||
return "\'...\'"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
fun f() {
|
||||
listOf(1).joinToString(<caret>)
|
||||
}
|
||||
|
||||
//Text: (<highlight>separator: String = ", "</highlight>, prefix: String = "", postfix: String = "", limit: Int = -1, truncated: String = "...", transform: ((Int) -> String)? = null), Disabled: false, Strikeout: false, Green: true
|
||||
+2
-2
@@ -20,8 +20,8 @@ import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
import org.jetbrains.kotlin.idea.test.ProjectDescriptorWithStdlibSources
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.junit.Assert
|
||||
|
||||
abstract class AbstractFunctionParameterInfoTest : LightCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor() = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
override fun getProjectDescriptor() = ProjectDescriptorWithStdlibSources.INSTANCE
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
+6
@@ -35,6 +35,12 @@ public class FunctionParameterInfoTestGenerated extends AbstractFunctionParamete
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/parameterInfo/functionParameterInfo"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultValuesFromLib.kt")
|
||||
public void testDefaultValuesFromLib() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/parameterInfo/functionParameterInfo/DefaultValuesFromLib.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Deprecated.kt")
|
||||
public void testDeprecated() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/parameterInfo/functionParameterInfo/Deprecated.kt");
|
||||
|
||||
Reference in New Issue
Block a user