From 6889908c2bbda520cc47ac55e4fb002588374bf7 Mon Sep 17 00:00:00 2001 From: Frederik Haselmeier Date: Tue, 2 Apr 2024 19:09:55 +0000 Subject: [PATCH] [Kotlin] Fixed KotlinInlineCompletionContextCollector using a K1 function in K2 mode Moved K2 specific inspection utility only used by the K2 inspection to shared and replaced the old K1/K2 specific calls to call the shared utility functions. ^KTIJ-28914 fixed Co-authored-by: Roman Golyshev Merge-request: IJ-MR-129458 Merged-by: Frederik Haselmeier GitOrigin-RevId: 13b4b2bae2002eef930b379aea1c05ec5bcecb25 --- ...SpecifyExplicitLambdaSignatureIntention.kt | 4 +- .../idea/codeInliner/CodeToInlineBuilder.kt | 4 +- .../ForEachParameterNotUsedInspection.kt | 2 +- ...SpecifyExplicitLambdaSignatureIntention.kt | 40 +----------- .../util/ExplicitLambdaSignatureUtil.kt | 55 ++++++++++++++++ .../codeInliner/InlinePreprocessorUtil.kt | 39 +++--------- .../util/ExplicitLambdaSignatureUtil.kt | 62 ------------------- 7 files changed, 72 insertions(+), 134 deletions(-) create mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/util/ExplicitLambdaSignatureUtil.kt delete mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/ExplicitLambdaSignatureUtil.kt diff --git a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/SpecifyExplicitLambdaSignatureIntention.kt b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/SpecifyExplicitLambdaSignatureIntention.kt index 2c22e5eeaa82..0b1b1558d447 100644 --- a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/SpecifyExplicitLambdaSignatureIntention.kt +++ b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/SpecifyExplicitLambdaSignatureIntention.kt @@ -7,8 +7,8 @@ import com.intellij.modcommand.ModPsiUpdater import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.KotlinApplicableModCommandAction -import org.jetbrains.kotlin.idea.k2.refactoring.util.getExplicitLambdaSignature -import org.jetbrains.kotlin.idea.k2.refactoring.util.specifyExplicitLambdaSignature +import org.jetbrains.kotlin.idea.refactoring.util.getExplicitLambdaSignature +import org.jetbrains.kotlin.idea.refactoring.util.specifyExplicitLambdaSignature import org.jetbrains.kotlin.psi.KtLambdaExpression internal class SpecifyExplicitLambdaSignatureIntention : diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt index b0856731ccea..d19929b59662 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt @@ -14,8 +14,8 @@ import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.core.asExpression import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArgumentsIntention -import org.jetbrains.kotlin.idea.intentions.SpecifyExplicitLambdaSignatureIntention import org.jetbrains.kotlin.idea.refactoring.inline.codeInliner.* +import org.jetbrains.kotlin.idea.refactoring.util.specifyExplicitLambdaSignature import org.jetbrains.kotlin.idea.references.canBeResolvedViaImport import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers @@ -166,7 +166,7 @@ class CodeToInlineBuilder(private val targetCallable: CallableDescriptor, } if (!needToAddParameterTypes(lambdaExpr, resolutionFacade)) return - SpecifyExplicitLambdaSignatureIntention.Holder.applyWithParameters(lambdaExpr, parameters) + specifyExplicitLambdaSignature(lambdaExpr, parameters) } private fun needToAddParameterTypes( diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ForEachParameterNotUsedInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ForEachParameterNotUsedInspection.kt index 5f10846f49a7..8531fd293cc0 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ForEachParameterNotUsedInspection.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ForEachParameterNotUsedInspection.kt @@ -17,10 +17,10 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.variableCallOrThis import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection -import org.jetbrains.kotlin.idea.intentions.SpecifyExplicitLambdaSignatureIntention.Holder.setParameterListIfAny import org.jetbrains.kotlin.idea.project.builtIns import org.jetbrains.kotlin.idea.refactoring.getThisLabelName import org.jetbrains.kotlin.idea.refactoring.moveFunctionLiteralOutsideParentheses +import org.jetbrains.kotlin.idea.refactoring.util.setParameterListIfAny import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt index 1fe070ba0bc7..b5b75780d953 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt @@ -4,19 +4,14 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.openapi.editor.Editor -import com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.safeAnalyzeNonSourceRootCode import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingOffsetIndependentIntention -import org.jetbrains.kotlin.idea.core.ShortenReferences +import org.jetbrains.kotlin.idea.refactoring.util.specifyExplicitLambdaSignature import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -import org.jetbrains.kotlin.idea.util.application.runWriteActionIfPhysical -import org.jetbrains.kotlin.psi.KtFunctionLiteral import org.jetbrains.kotlin.psi.KtLambdaExpression -import org.jetbrains.kotlin.psi.KtParameterList -import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.isError @@ -39,7 +34,7 @@ open class SpecifyExplicitLambdaSignatureIntention : SelfTargetingOffsetIndepend val functionLiteral = element.functionLiteral val functionDescriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.FUNCTION, functionLiteral]!! - applyWithParameters(element, functionDescriptor.valueParameters + specifyExplicitLambdaSignature(element, functionDescriptor.valueParameters .asSequence() .mapIndexed { index, parameterDescriptor -> parameterDescriptor.render(psiName = functionLiteral.valueParameters.getOrNull(index)?.let { @@ -48,37 +43,6 @@ open class SpecifyExplicitLambdaSignatureIntention : SelfTargetingOffsetIndepend } .joinToString()) } - - fun KtFunctionLiteral.setParameterListIfAny(psiFactory: KtPsiFactory, newParameterList: KtParameterList?) { - val oldParameterList = valueParameterList - if (oldParameterList != null && newParameterList != null) { - oldParameterList.replace(newParameterList) - } else { - val openBraceElement = lBrace - val nextSibling = openBraceElement.nextSibling - val addNewline = nextSibling is PsiWhiteSpace && nextSibling.text?.contains("\n") ?: false - val (whitespace, arrow) = psiFactory.createWhitespaceAndArrow() - addRangeAfter(whitespace, arrow, openBraceElement) - if (newParameterList != null) { - addAfter(newParameterList, openBraceElement) - } - - if (addNewline) { - addAfter(psiFactory.createNewLine(), openBraceElement) - } - } - } - - fun applyWithParameters(element: KtLambdaExpression, parameterString: String) { - val psiFactory = KtPsiFactory(element.project) - val functionLiteral = element.functionLiteral - val newParameterList = - (psiFactory.createExpression("{ $parameterString -> }") as KtLambdaExpression).functionLiteral.valueParameterList - runWriteActionIfPhysical(element) { - functionLiteral.setParameterListIfAny(psiFactory, newParameterList) - ShortenReferences.DEFAULT.process(element.valueParameters) - } - } } } diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/util/ExplicitLambdaSignatureUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/util/ExplicitLambdaSignatureUtil.kt new file mode 100644 index 000000000000..0af77c230242 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/util/ExplicitLambdaSignatureUtil.kt @@ -0,0 +1,55 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.refactoring.util + +import com.intellij.psi.PsiWhiteSpace +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol +import org.jetbrains.kotlin.analysis.api.types.KtErrorType +import org.jetbrains.kotlin.idea.base.codeInsight.ShortenReferencesFacility +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.types.Variance + +fun KtAnalysisSession.getExplicitLambdaSignature(element: KtLambdaExpression): String? { + val lambdaSymbol = element.functionLiteral.getSymbol() as KtFunctionLikeSymbol + val valueParameters = lambdaSymbol.valueParameters + if (valueParameters.any { it.returnType is KtErrorType } ) return null + return valueParameters.joinToString { param -> + val parameter = param.psi as? KtParameter + if (parameter != null) { + (parameter.name ?: parameter.destructuringDeclaration?.text + ?: "_") + ": " + param.returnType.render(position = Variance.IN_VARIANCE) + } else param.render() + } +} + +fun KtFunctionLiteral.setParameterListIfAny(psiFactory: KtPsiFactory, newParameterList: KtParameterList?) { + val oldParameterList = valueParameterList + if (oldParameterList != null && newParameterList != null) { + oldParameterList.replace(newParameterList) + } else { + val openBraceElement = lBrace + val nextSibling = openBraceElement.nextSibling + val addNewline = nextSibling is PsiWhiteSpace && nextSibling.text?.contains("\n") ?: false + val (whitespace, arrow) = psiFactory.createWhitespaceAndArrow() + addRangeAfter(whitespace, arrow, openBraceElement) + if (newParameterList != null) { + addAfter(newParameterList, openBraceElement) + } + + if (addNewline) { + addAfter(psiFactory.createNewLine(), openBraceElement) + } + } +} + +fun specifyExplicitLambdaSignature(element: KtLambdaExpression, parameterString: String) { + val psiFactory = KtPsiFactory(element.project) + val functionLiteral = element.functionLiteral + val newParameterList = (psiFactory.createExpression("{ $parameterString -> }") as KtLambdaExpression).functionLiteral.valueParameterList + + functionLiteral.setParameterListIfAny(psiFactory, newParameterList) + + for (parameter in element.valueParameters) { + ShortenReferencesFacility.getInstance().shorten(parameter) + } +} diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/inline/codeInliner/InlinePreprocessorUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/inline/codeInliner/InlinePreprocessorUtil.kt index a55657c0251b..f5970157c14b 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/inline/codeInliner/InlinePreprocessorUtil.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/inline/codeInliner/InlinePreprocessorUtil.kt @@ -12,48 +12,24 @@ import org.jetbrains.kotlin.analysis.api.calls.singleVariableAccessCall import org.jetbrains.kotlin.analysis.api.calls.symbol import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisFromWriteAction import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt -import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind -import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol +import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers -import org.jetbrains.kotlin.analysis.api.symbols.receiverType import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType import org.jetbrains.kotlin.idea.codeinsight.utils.addTypeArguments import org.jetbrains.kotlin.idea.codeinsight.utils.getRenderedTypeArguments import org.jetbrains.kotlin.idea.k2.refactoring.util.ConvertReferenceToLambdaUtil -import org.jetbrains.kotlin.idea.k2.refactoring.util.getExplicitLambdaSignature -import org.jetbrains.kotlin.idea.k2.refactoring.util.specifyExplicitLambdaSignature import org.jetbrains.kotlin.idea.refactoring.inline.codeInliner.CodeToInline import org.jetbrains.kotlin.idea.refactoring.inline.codeInliner.MutableCodeToInline import org.jetbrains.kotlin.idea.refactoring.inline.codeInliner.forEachDescendantOfType +import org.jetbrains.kotlin.idea.refactoring.util.getExplicitLambdaSignature +import org.jetbrains.kotlin.idea.refactoring.util.specifyExplicitLambdaSignature import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtCallElement -import org.jetbrains.kotlin.psi.KtCallExpression -import org.jetbrains.kotlin.psi.KtCallableDeclaration -import org.jetbrains.kotlin.psi.KtCallableReferenceExpression -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtLambdaExpression -import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.KtQualifiedExpression -import org.jetbrains.kotlin.psi.KtReferenceExpression -import org.jetbrains.kotlin.psi.KtSimpleNameExpression -import org.jetbrains.kotlin.psi.KtTypeParameter -import org.jetbrains.kotlin.psi.KtUserType -import org.jetbrains.kotlin.psi.KtValueArgumentName -import org.jetbrains.kotlin.psi.createExpressionByPattern +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression import org.jetbrains.kotlin.psi.psiUtil.isNull import org.jetbrains.kotlin.psi.psiUtil.parameterIndex -import org.jetbrains.kotlin.psi.unpackFunctionLiteral import org.jetbrains.kotlin.resolve.ImportPath import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -123,7 +99,12 @@ fun fullyExpandCall( for (lambdaExpression in lambdaExpressions) { allowAnalysisOnEdt { allowAnalysisFromWriteAction { - specifyExplicitLambdaSignature(lambdaExpression) + val parameterString = analyze(lambdaExpression) { + getExplicitLambdaSignature(lambdaExpression) + } + if (parameterString != null) { + specifyExplicitLambdaSignature(lambdaExpression, parameterString) + } } } } diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/ExplicitLambdaSignatureUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/ExplicitLambdaSignatureUtil.kt deleted file mode 100644 index fcd3d026f585..000000000000 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/ExplicitLambdaSignatureUtil.kt +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.k2.refactoring.util - -import com.intellij.psi.PsiWhiteSpace -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol -import org.jetbrains.kotlin.analysis.api.types.KtErrorType -import org.jetbrains.kotlin.idea.base.analysis.api.utils.shortenReferences -import org.jetbrains.kotlin.psi.KtFunctionLiteral -import org.jetbrains.kotlin.psi.KtLambdaExpression -import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.KtParameterList -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.types.Variance - -context(KtAnalysisSession) -fun getExplicitLambdaSignature(element: KtLambdaExpression): String? { - val lambdaSymbol = element.functionLiteral.getSymbol() as KtFunctionLikeSymbol - val valueParameters = lambdaSymbol.valueParameters - if (valueParameters.any { it.returnType is KtErrorType } ) return null - return valueParameters.joinToString { param -> - val parameter = param.psi as? KtParameter - if (parameter != null) { - (parameter.name ?: parameter.destructuringDeclaration?.text - ?: "_") + ": " + param.returnType.render(position = Variance.IN_VARIANCE) - } else param.render() - } -} - -fun specifyExplicitLambdaSignature(element: KtLambdaExpression) { - val parameterString = analyze(element) { getExplicitLambdaSignature(element) } ?: return - specifyExplicitLambdaSignature(element, parameterString) -} - -fun specifyExplicitLambdaSignature(element: KtLambdaExpression, parameterString: String) { - val psiFactory = KtPsiFactory(element.project) - val functionLiteral = element.functionLiteral - val newParameterList = (psiFactory.createExpression("{ $parameterString -> }") as KtLambdaExpression).functionLiteral.valueParameterList - - fun KtFunctionLiteral.setParameterListIfAny(psiFactory: KtPsiFactory, newParameterList: KtParameterList?) { - val oldParameterList = valueParameterList - if (oldParameterList != null && newParameterList != null) { - oldParameterList.replace(newParameterList) - } else { - val openBraceElement = lBrace - val nextSibling = openBraceElement.nextSibling - val addNewline = nextSibling is PsiWhiteSpace && nextSibling.text?.contains("\n") ?: false - val (whitespace, arrow) = psiFactory.createWhitespaceAndArrow() - addRangeAfter(whitespace, arrow, openBraceElement) - if (newParameterList != null) { - addAfter(newParameterList, openBraceElement) - } - - if (addNewline) { - addAfter(psiFactory.createNewLine(), openBraceElement) - } - } - } - functionLiteral.setParameterListIfAny(psiFactory, newParameterList) - shortenReferences(element.valueParameters) -}