[java-refactoring] IDEA-380516 JavaSuggestedRefactoringAvailability.extractAnnotationsWithResolve: IllegalArgumentException: Failed requirement

GitOrigin-RevId: 76f78b44e8595f57beca1306ac2868e96630cfb8
This commit is contained in:
Mikhail Pyltsin
2025-11-07 03:24:28 +00:00
committed by intellij-monorepo-bot
parent 76019e807b
commit 9de81a8590
3 changed files with 51 additions and 9 deletions
@@ -18,6 +18,7 @@ class JavaSuggestedRefactoringAvailability(refactoringSupport: SuggestedRefactor
SuggestedRefactoringAvailability(refactoringSupport) {
private val HAS_OVERRIDES = Key<Boolean>("JavaSuggestedRefactoringAvailability.HAS_OVERRIDES")
private val HAS_USAGES = Key<Boolean>("JavaSuggestedRefactoringAvailability.HAS_USAGES")
private val HAS_NOT_MATCHED_PARAMETERS = Key<Boolean>("JavaSuggestedRefactoringAvailability.HAS_NOT_MATCHED_PARAMETERS")
// disable refactoring suggestion for method which overrides another method
override fun shouldSuppressRefactoringForDeclaration(state: SuggestedRefactoringState): Boolean {
@@ -113,9 +114,14 @@ class JavaSuggestedRefactoringAvailability(refactoringSupport: SuggestedRefactor
val declaration = anchor as? PsiMethod ?: return state
val restoredDeclarationCopy = state.restoredDeclarationCopy() as PsiMethod
val psiFile = declaration.containingFile
val oldSignature = extractAnnotationsWithResolve(state.oldSignature, restoredDeclarationCopy, psiFile)
val newSignature = extractAnnotationsWithResolve(state.newSignature, declaration, psiFile)
if(oldSignature == null || newSignature == null) {
return state.withAdditionalData(HAS_NOT_MATCHED_PARAMETERS, true)
}
return state
.withOldSignature(extractAnnotationsWithResolve(state.oldSignature, restoredDeclarationCopy, psiFile))
.withNewSignature(extractAnnotationsWithResolve(state.newSignature, declaration, psiFile))
.withOldSignature(oldSignature)
.withNewSignature(newSignature)
}
override fun detectAvailableRefactoring(state: SuggestedRefactoringState): SuggestedRefactoringData? {
@@ -123,6 +129,7 @@ class JavaSuggestedRefactoringAvailability(refactoringSupport: SuggestedRefactor
val whatToUpdate: String
val declaration: PsiElement
val anchor = state.anchor
if (updatedState.additionalData[HAS_NOT_MATCHED_PARAMETERS] == true) return null
if (anchor is PsiCallExpression) {
updatedState = callStateToDeclarationState(updatedState) ?: return null
declaration = anchor.resolveMethod() ?: return null
@@ -183,9 +190,9 @@ class JavaSuggestedRefactoringAvailability(refactoringSupport: SuggestedRefactor
}
// Annotations were extracted without use of resolve. We must extract them again using more precise method.
private fun extractAnnotationsWithResolve(signature: Signature, declaration: PsiMethod, psiFile: PsiFile): Signature {
private fun extractAnnotationsWithResolve(signature: Signature, declaration: PsiMethod, psiFile: PsiFile): Signature? {
val psiParameters = declaration.parameterList.parameters
require(signature.parameters.size == psiParameters.size)
if(signature.parameters.size != psiParameters.size) return null
return Signature.create(
signature.name,
@@ -11,9 +11,10 @@ import com.intellij.psi.PsiElementFactory
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.refactoring.BaseRefactoringProcessor
import com.intellij.refactoring.suggested.BaseSuggestedRefactoringTest
import com.intellij.refactoring.suggested.SuggestedRefactoringExecution
import com.intellij.refactoring.suggested._suggestedChangeSignatureNewParameterValuesForTests
import com.intellij.refactoring.RefactoringBundle.message
import com.intellij.refactoring.suggested.*
import com.intellij.refactoring.suggested.SuggestedRefactoringSupport.Parameter
import com.intellij.refactoring.suggested.SuggestedRefactoringSupport.Signature
class JavaSuggestedRefactoringTest : BaseSuggestedRefactoringTest() {
override val fileType: LanguageFileType
@@ -1315,7 +1316,41 @@ class JavaSuggestedRefactoringTest : BaseSuggestedRefactoringTest() {
executeCommand(project) { type(", int p2") }
}
}
fun testBrokenParameters() {
doTest(
initialText = """
interface I {
void foo(<caret>);
}
""".trimIndent(),
actionName = message("suggested.refactoring.change.signature.intention.text", "usages"),
textAfterRefactoring = """
interface I {
void foo(String s<caret>);
}
""".trimIndent(),
checkPresentation = {
var state = SuggestedRefactoringProviderImpl.getInstance(this.project).state!!
val oldSignature = state.oldSignature
state = state.withOldSignature(Signature.create(oldSignature.name, oldSignature.type,
oldSignature.parameters.let {
val list = it.toMutableList()
list.add(Parameter("s", "s", "String"))
list
},
oldSignature.additionalData)!!)
state = state.refactoringSupport.availability.refineSignaturesWithResolve(state)
val refactoringSupport = state.refactoringSupport
val refactoring = refactoringSupport.availability.detectAvailableRefactoring(state)
assertNull(refactoring)
},
editingActions = {
type("String s")
}
)
}
private fun addFileWithAnnotations() {
myFixture.addFileToProject(
"Annotations.java",
@@ -64,7 +64,7 @@ abstract class BaseSuggestedRefactoringTest : LightJavaCodeInsightFixtureTestCas
)
}
private fun doTest(
protected fun doTest(
initialText: String,
actionName: String,
textAfterRefactoring: String,