diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt index 11220ca682a..c320c27cc6a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeInfo.kt @@ -148,6 +148,11 @@ public open class JetChangeInfo( } } + public fun clearParameters() { + newParameters.clear() + receiverParameterInfo = null + } + public fun hasParameter(parameterInfo: JetParameterInfo): Boolean = parameterInfo in newParameters diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.kt index 3abdd682d24..8efb4040eda 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.kt @@ -22,19 +22,16 @@ import com.intellij.codeInsight.TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED import com.intellij.openapi.editor.Editor import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.JavaPsiFacade -import com.intellij.psi.PsiElement +import com.intellij.psi.PsiElementFactory import com.intellij.psi.PsiMethod import com.intellij.psi.PsiType import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex -import com.intellij.psi.search.GlobalSearchScope import com.intellij.refactoring.BaseRefactoringProcessor import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor import com.intellij.refactoring.changeSignature.ParameterInfoImpl -import com.intellij.refactoring.changeSignature.ThrownExceptionInfo import com.intellij.refactoring.util.CanonicalTypes import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.testFramework.UsefulTestCase -import com.intellij.util.ArrayUtil import com.intellij.util.VisibilityUtil import junit.framework.ComparisonFailure import junit.framework.TestCase @@ -42,1255 +39,38 @@ import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.idea.caches.resolve.analyze -import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle import org.jetbrains.kotlin.idea.refactoring.changeSignature.ui.KotlinMethodNode +import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils import org.jetbrains.kotlin.idea.test.KotlinCodeInsightTestCase import org.jetbrains.kotlin.idea.test.PluginTestCaseBase -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.dataClassUtils.createComponentName +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.utils.sure import java.io.File import java.util.* class JetChangeSignatureTest : KotlinCodeInsightTestCase() { - fun testBadSelection() { - configureByFile(getTestName(false) + "Before.kt") - TestCase.assertNull(JetChangeSignatureHandler().findTargetMember(file, editor)) - } - - fun testRenameFunction() { - val changeInfo = getChangeInfo() - changeInfo.newName = "after" - doTest(changeInfo) - } - - fun testChangeReturnType() { - val changeInfo = getChangeInfo() - changeInfo.newReturnTypeText = "Float" - doTest(changeInfo) - } - - fun testAddReturnType() { - val changeInfo = getChangeInfo() - changeInfo.newReturnTypeText = "Float" - doTest(changeInfo) - } - - fun testRemoveReturnType() { - val changeInfo = getChangeInfo() - changeInfo.newReturnTypeText = "Unit" - doTest(changeInfo) - } - - fun testChangeConstructorVisibility() { - val changeInfo = getChangeInfo() - - changeInfo.newVisibility = Visibilities.PROTECTED - doTest(changeInfo) - } - - fun testSynthesized() { - try { - getChangeInfo() - } - catch (e: CommonRefactoringUtil.RefactoringErrorHintException) { - TestCase.assertEquals(JetRefactoringBundle.message("cannot.refactor.synthesized.function", createComponentName(1).asString()), e.message) - return - } - - TestCase.fail() - } - - fun testPreferContainedInClass() { - val changeInfo = getChangeInfo() - TestCase.assertEquals("param", changeInfo.newParameters[0].name) - } - - fun testAddConstructorVisibility() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.PROTECTED - val psiFactory = KtPsiFactory(project) - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "x", BUILT_INS.anyType, - null, psiFactory.createExpression("12"), JetValVar.Val, null) - changeInfo.addParameter(newParameter) - doTest(changeInfo) - } - - fun testConstructor() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.PUBLIC - changeInfo.newParameters[0].valOrVar = JetValVar.Var - changeInfo.newParameters[1].valOrVar = JetValVar.None - changeInfo.newParameters[2].valOrVar = JetValVar.Val - changeInfo.newParameters[0].name = "_x1" - changeInfo.newParameters[1].name = "_x2" - changeInfo.newParameters[2].name = "_x3" - changeInfo.newParameters[1].currentTypeText = "Float?" - doTest(changeInfo) - } - - fun testGenericConstructor() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.PUBLIC - changeInfo.newParameters[0].valOrVar = JetValVar.Var - changeInfo.newParameters[1].valOrVar = JetValVar.None - changeInfo.newParameters[2].valOrVar = JetValVar.Val - changeInfo.newParameters[0].name = "_x1" - changeInfo.newParameters[1].name = "_x2" - changeInfo.newParameters[2].name = "_x3" - changeInfo.newParameters[1].currentTypeText = "Double?" - doTest(changeInfo) - } - - fun testConstructorSwapArguments() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[0].name = "_x1" - changeInfo.newParameters[1].name = "_x2" - val param = changeInfo.newParameters[0] - changeInfo.setNewParameter(0, changeInfo.newParameters[2]) - changeInfo.setNewParameter(2, param) - doTest(changeInfo) - } - - fun testFunctions() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.PUBLIC - changeInfo.newParameters[0].name = "_x1" - changeInfo.newParameters[1].name = "_x2" - changeInfo.newParameters[2].name = "_x3" - changeInfo.newParameters[1].currentTypeText = "Float?" - doTest(changeInfo) - } - - fun testGenericFunctions() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.PUBLIC - changeInfo.newParameters[0].name = "_x1" - changeInfo.newParameters[1].name = "_x2" - changeInfo.newParameters[2].name = "_x3" - changeInfo.newParameters[1].currentTypeText = "Double?" - doTest(changeInfo) - } - - fun testExpressionFunction() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[0].name = "x1" - changeInfo.addParameter(JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "y1", BUILT_INS.intType, null, null, JetValVar.None, null)) - doTest(changeInfo) - } - - fun testFunctionsAddRemoveArguments() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.INTERNAL - changeInfo.setNewParameter(2, changeInfo.newParameters[1]) - changeInfo.setNewParameter(1, changeInfo.newParameters[0]) - val psiFactory = KtPsiFactory(project) - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "x0", BUILT_INS.nullableAnyType, null, psiFactory.createExpression("null"), JetValVar.None, null) - changeInfo.setNewParameter(0, newParameter) - doTest(changeInfo) - } - - fun testFakeOverride() { - val changeInfo = getChangeInfo() - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "i", BUILT_INS.intType, null, null, JetValVar.None, null) - changeInfo.addParameter(newParameter) - doTest(changeInfo) - } - - fun testFunctionLiteral() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[1].name = "y1" - changeInfo.addParameter(JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "x", BUILT_INS.anyType, null, null, JetValVar.None, null)) - changeInfo.newReturnTypeText = "Int" - doTest(changeInfo) - } - - fun testVarargs() { - try { - getChangeInfo() - } - catch (e: CommonRefactoringUtil.RefactoringErrorHintException) { - TestCase.assertEquals("Can't refactor the function with variable arguments", e.message) - return - } - - TestCase.fail("Exception expected") - } - - fun testUnmodifiableFromLibrary() { - doTestUnmodifiableCheck() - } - - - fun testUnmodifiableFromBuiltins() { - doTestUnmodifiableCheck() - } - - private fun doTestUnmodifiableCheck() { - try { - val changeInfo = getChangeInfo() - val method = changeInfo.method as KtElement - val empty = object : JetChangeSignatureConfiguration { - override fun configure(originalDescriptor: JetMethodDescriptor) = originalDescriptor - - override fun performSilently(affectedFunctions: Collection) = true - - override fun forcePerformForSelectedFunctionOnly() = false - } - - runChangeSignature(project, changeInfo.originalBaseFunctionDescriptor, empty, method, "test") - } - catch (e: RuntimeException) { - TestCase.assertTrue(e.message!!.startsWith("Refactoring cannot be")) - return - } - - TestCase.fail("Exception expected") - } - - fun testInnerFunctionsConflict() { - val changeInfo = getChangeInfo() - changeInfo.newName = "inner2" - changeInfo.newParameters[0].name = "y" - doTestConflict(changeInfo) - } - - fun testMemberFunctionsConflict() { - val changeInfo = getChangeInfo() - changeInfo.newName = "inner2" - changeInfo.newParameters[0].name = "y" - doTestConflict(changeInfo) - } - - fun testTopLevelFunctionsConflict() { - val changeInfo = getChangeInfo() - changeInfo.newName = "fun2" - doTestConflict(changeInfo) - } - - fun testConstructorsConflict() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[0].name = "_x" - changeInfo.newParameters[1].name = "_y" - changeInfo.newParameters[2].name = "_z" - doTestConflict(changeInfo) - } - - fun testNoDefaultValuesInOverrides() { - val changeInfo = getChangeInfo() - val newParameters = changeInfo.newParameters - changeInfo.setNewParameter(0, newParameters[1]) - changeInfo.setNewParameter(1, newParameters[0]) - doTest(changeInfo) - } - - fun testOverridesInEnumEntries() { - val changeInfo = getChangeInfo() - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, null, JetValVar.None, null) - changeInfo.addParameter(newParameter) - doTest(changeInfo) - } - - fun testEnumEntriesWithoutSuperCalls() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, psiFactory.createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - doTest(changeInfo) - } - - fun testParameterChangeInOverrides() { - val changeInfo = getChangeInfo() - val parameterInfo = changeInfo.newParameters[0] - parameterInfo.name = "n" - parameterInfo.currentTypeText = "Int" - doTest(changeInfo) - } - - fun testConstructorJavaUsages() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, psiFactory.createExpression("\"abc\""), JetValVar.None, null) - changeInfo.addParameter(newParameter) - doTest(changeInfo) - } - - fun testFunctionJavaUsagesAndOverridesAddParam() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, psiFactory.createExpression("\"abc\""), - JetValVar.None, null)) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "o", BUILT_INS.nullableAnyType, null, - psiFactory.createExpression("\"def\""), JetValVar.None, null)) - doTest(changeInfo) - } - - fun testFunctionJavaUsagesAndOverridesChangeNullability() { - val changeInfo = getChangeInfo() - - val newParameters = changeInfo.newParameters - newParameters[1].currentTypeText = "String?" - newParameters[2].currentTypeText = "Any" - - changeInfo.newReturnTypeText = "String?" - - doTest(changeInfo) - } - - fun testFunctionJavaUsagesAndOverridesChangeTypes() { - val changeInfo = getChangeInfo() - - val newParameters = changeInfo.newParameters - newParameters[0].currentTypeText = "String?" - newParameters[1].currentTypeText = "Int" - newParameters[2].currentTypeText = "Long?" - - changeInfo.newReturnTypeText = "Any?" - - doTest(changeInfo) - } - - fun testGenericsWithOverrides() { - val changeInfo = getChangeInfo() - - val newParameters = changeInfo.newParameters - newParameters[0].currentTypeText = "List" - newParameters[1].currentTypeText = "A?" - newParameters[2].currentTypeText = "U" - - changeInfo.newReturnTypeText = "U?" - - doTest(changeInfo) - } - - fun testAddReceiverToGenericsWithOverrides() { - val changeInfo = getChangeInfo() - - val parameterInfo = changeInfo.newParameters[0] - parameterInfo.currentTypeText = "U" - changeInfo.receiverParameterInfo = parameterInfo - - doTest(changeInfo) - } - - fun testJavaMethodKotlinUsages() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewName(method: PsiMethod): String { - return "bar" - } - - override fun getNewParameters(method: PsiMethod): Array { - return ArrayUtil.remove(super.getNewParameters(method), 1) - } - }) - } - - fun testJavaConstructorKotlinUsages() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - return ArrayUtil.remove(super.getNewParameters(method), 1) - } - }) - } - - fun testSAMAddToEmptyParamList() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - val paramType = PsiType.getJavaLangString(psiManager, GlobalSearchScope.allScope(project)) - return arrayOf(ParameterInfoImpl(-1, "s", paramType)) - } - }) - } - - fun testSAMAddToSingletonParamList() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - val parameter = method.parameterList.parameters[0] - val originalParameter = ParameterInfoImpl(0, parameter.name, parameter.type) - val newParameter = ParameterInfoImpl(-1, "n", PsiType.INT) - - return arrayOf(newParameter, originalParameter) - } - }) - } - - fun testSAMAddToNonEmptyParamList() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - val originalParameters = super.getNewParameters(method) - val newParameters = Arrays.copyOf(originalParameters, originalParameters.size + 1) - - val paramType = PsiType.getJavaLangObject(psiManager, GlobalSearchScope.allScope(project)) - newParameters[originalParameters.size] = ParameterInfoImpl(-1, "o", paramType) - - return newParameters - } - }) - } - - fun testSAMRemoveSingletonParamList() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array = arrayOf() - } - ) - } - - fun testSAMRemoveParam() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - return ArrayUtil.remove(super.getNewParameters(method), 0) - } - } - ) - } - - fun testSAMRenameParam() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - val newParameters = super.getNewParameters(method) - newParameters[0].name = "p" - return newParameters - } - }) - } - - fun testSAMChangeParamType() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - val newParameters = super.getNewParameters(method) - newParameters[0].setType(PsiType.getJavaLangObject(psiManager, GlobalSearchScope.allScope(project))) - return newParameters - } - }) - } - - fun testSAMRenameMethod() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewName(method: PsiMethod): String { - return "bar" - } - }) - } - - fun testSAMChangeMethodReturnType() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewReturnType(method: PsiMethod): PsiType { - return PsiType.getJavaLangObject(psiManager, GlobalSearchScope.allScope(project)) - } - }) - } - - fun testGenericsWithSAMConstructors() { - doJavaTest( - object : JavaRefactoringProvider() { - internal val factory = JavaPsiFacade.getInstance(project).elementFactory - - override fun getNewParameters(method: PsiMethod): Array { - val newParameters = super.getNewParameters(method) - newParameters[0].setType(factory.createTypeFromText("java.util.List>", method.parameterList)) - newParameters[1].setType(factory.createTypeFromText("X>", method.parameterList)) - return newParameters - } - - override fun getNewReturnType(method: PsiMethod): PsiType { - return factory.createTypeFromText("X>", method) - } - }) - } - - fun testFunctionRenameJavaUsages() { - val changeInfo = getChangeInfo() - changeInfo.newName = "bar" - doTest(changeInfo) - } - - fun testParameterModifiers() { - val changeInfo = getChangeInfo() - changeInfo.addParameter(JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, null, JetValVar.None, null)) - doTest(changeInfo) - } - - fun testFqNameShortening() { - val changeInfo = getChangeInfo() - val parameterInfo = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.anyType, null, null, JetValVar.None, null) - parameterInfo.currentTypeText = "kotlin.String" - changeInfo.addParameter(parameterInfo) - doTest(changeInfo) - } - - fun testObjectMember() { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(0) - doTest(changeInfo) - } - - fun testParameterListAddParam() { - val changeInfo = getChangeInfo() - changeInfo.addParameter(JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "l", BUILT_INS.longType, null, null, JetValVar.None, null)) - doTest(changeInfo) - } - - fun testParameterListRemoveParam() { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(changeInfo.getNewParametersCount() - 1) - doTest(changeInfo) - } - - fun testParameterListRemoveAllParams() { - val changeInfo = getChangeInfo() - for (i in changeInfo.getNewParametersCount() - 1 downTo 0) { - changeInfo.removeParameter(i) - } - doTest(changeInfo) - } - - fun testAddNewReceiver() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - val parameterInfo = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "_", BUILT_INS.anyType, null, psiFactory.createExpression("X(0)"), JetValVar.None, null) - parameterInfo.currentTypeText = "X" - changeInfo.receiverParameterInfo = parameterInfo - doTest(changeInfo) - } - - fun testAddNewReceiverForMember() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - val parameterInfo = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "_", BUILT_INS.anyType, null, psiFactory.createExpression("X(0)"), JetValVar.None, null) - parameterInfo.currentTypeText = "X" - changeInfo.receiverParameterInfo = parameterInfo - doTest(changeInfo) - } - - fun testAddNewReceiverForMemberConflict() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - val parameterInfo = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "_", BUILT_INS.anyType, null, psiFactory.createExpression("X(0)"), JetValVar.None, null) - parameterInfo.currentTypeText = "X" - changeInfo.receiverParameterInfo = parameterInfo - doTestConflict(changeInfo) - } - - fun testAddNewReceiverConflict() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - val parameterInfo = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "_", BUILT_INS.anyType, null, psiFactory.createExpression("X(0)"), JetValVar.None, null) - parameterInfo.currentTypeText = "X" - changeInfo.receiverParameterInfo = parameterInfo - doTestConflict(changeInfo) - } - - fun testRemoveReceiver() { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(0) - doTest(changeInfo) - } - - fun testRemoveReceiverForMember() { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(0) - doTest(changeInfo) - } - - fun testConvertParameterToReceiver1() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[0] - doTest(changeInfo) - } - - fun testConvertParameterToReceiver2() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[1] - doTest(changeInfo) - } - - fun testConvertReceiverToParameter1() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testConvertReceiverToParameter2() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - val parameters = changeInfo.newParameters - changeInfo.setNewParameter(0, parameters[1]) - changeInfo.setNewParameter(1, parameters[0]) - doTest(changeInfo) - } - - fun testConvertParameterToReceiverForMember1() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[0] - doTest(changeInfo) - } - - fun testConvertParameterToReceiverForMember2() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[1] - doTest(changeInfo) - } - - fun testConvertParameterToReceiverForMemberConflict() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[0] - doTestConflict(changeInfo) - } - - fun testConvertReceiverToParameterForMember1() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testConvertReceiverToParameterForMember2() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - val parameters = changeInfo.newParameters - changeInfo.setNewParameter(0, parameters[1]) - changeInfo.setNewParameter(1, parameters[0]) - doTest(changeInfo) - } - - fun testConvertReceiverToParameterWithNameClash() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testConvertReceiverToParameterAndChangeName() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - changeInfo.newParameters[0].name = "abc" - doTest(changeInfo) - } - - fun testChangeReceiver() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[1] - doTest(changeInfo) - } - - fun testChangeReceiverForMember() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[1] - doTest(changeInfo) - } - - fun testChangeParameterTypeWithImport() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[0].currentTypeText = "a.Bar" - doTest(changeInfo) - } - - fun testSecondaryConstructor() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, psiFactory.createExpression("\"foo\""), - JetValVar.None, null)) - doTest(changeInfo) - } - - fun testJavaConstructorInDelegationCall() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - var newParameters = super.getNewParameters(method) - newParameters = Arrays.copyOf(newParameters, newParameters.size + 1) - - val paramType = PsiType.getJavaLangString(psiManager, GlobalSearchScope.allScope(project)) - newParameters[newParameters.size - 1] = ParameterInfoImpl(-1, "s", paramType, "\"foo\"") - - return newParameters - } - }) - } - - fun testPrimaryConstructorByThisRef() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, psiFactory.createExpression("\"foo\""), JetValVar.None, null)) - doTest(changeInfo) - } - - fun testPrimaryConstructorBySuperRef() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, psiFactory.createExpression("\"foo\""), JetValVar.None, null)) - doTest(changeInfo) - } - - fun testSecondaryConstructorByThisRef() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, psiFactory.createExpression("\"foo\""), JetValVar.None, null)) - doTest(changeInfo) - } - - fun testSecondaryConstructorBySuperRef() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", BUILT_INS.stringType, null, psiFactory.createExpression("\"foo\""), JetValVar.None, null)) - doTest(changeInfo) - } - - fun testJavaConstructorBySuperRef() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - var newParameters = super.getNewParameters(method) - newParameters = Arrays.copyOf(newParameters, newParameters.size + 1) - - val paramType = PsiType.getJavaLangString(psiManager, GlobalSearchScope.allScope(project)) - newParameters[newParameters.size - 1] = ParameterInfoImpl(-1, "s", paramType, "\"foo\"") - - return newParameters - } - }) - } - - fun testNoConflictWithReceiverName() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - changeInfo.addParameter( - JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "i", BUILT_INS.intType, null, psiFactory.createExpression("0"), JetValVar.None, null)) - doTest(changeInfo) - } - - fun testRemoveParameterBeforeLambda() { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(1) - doTest(changeInfo) - } - - fun testMoveLambdaParameter() { - val changeInfo = getChangeInfo() - val newParameters = changeInfo.newParameters - changeInfo.setNewParameter(1, newParameters[2]) - changeInfo.setNewParameter(2, newParameters[1]) - doTest(changeInfo) - } - - fun testConvertLambdaParameterToReceiver() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[2] - doTest(changeInfo) - } - - fun testRemoveLambdaParameter() { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(2) - doTest(changeInfo) - } - - fun testRemoveEnumConstructorParameter() { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(1) - doTest(changeInfo) - } - - fun testRemoveAllEnumConstructorParameters() { - val changeInfo = getChangeInfo() - for (i in changeInfo.getNewParametersCount() - 1 downTo 0) { - changeInfo.removeParameter(i) - } - doTest(changeInfo) - } - - fun testDoNotApplyPrimarySignatureToSecondaryCalls() { - val changeInfo = getChangeInfo() - val newParameters = changeInfo.newParameters - changeInfo.setNewParameter(0, newParameters[1]) - changeInfo.setNewParameter(1, newParameters[0]) - doTest(changeInfo) - } - - fun testConvertToExtensionAndRename() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[0] - changeInfo.newName = "foo1" - doTest(changeInfo) - } - - fun testRenameExtensionParameter() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[1].name = "b" - doTest(changeInfo) - } - - fun testConvertParameterToReceiverAddParens() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[0] - doTest(changeInfo) - } - - fun testThisReplacement() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testPrimaryConstructorByRef() { - val changeInfo = getChangeInfo() - val psiFactory = KtPsiFactory(project) - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, - psiFactory.createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - doTest(changeInfo) - } - - fun testReceiverToParameterExplicitReceiver() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testReceiverToParameterImplicitReceivers() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testParameterToReceiverExplicitReceiver() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[0] - doTest(changeInfo) - } - - fun testParameterToReceiverImplicitReceivers() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = changeInfo.newParameters[0] - doTest(changeInfo) - } - - fun testJavaMethodOverridesReplaceParam() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewReturnType(method: PsiMethod): PsiType { - return PsiType.getJavaLangString(psiManager, GlobalSearchScope.allScope(project)) - } - - override fun getNewParameters(method: PsiMethod): Array { - val newParameters = super.getNewParameters(method) - newParameters[0] = ParameterInfoImpl(-1, "x", PsiType.INT, "1") - return newParameters - } - }) - } - - fun testJavaMethodOverridesChangeParam() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewReturnType(method: PsiMethod): PsiType { - return PsiType.getJavaLangString(psiManager, GlobalSearchScope.allScope(project)) - } - - override fun getNewParameters(method: PsiMethod): Array { - val newParameters = super.getNewParameters(method) - newParameters[0].name = "x" - newParameters[0].setType(PsiType.INT) - return newParameters - } - }) - } - - fun testChangeProperty() { - val changeInfo = getChangeInfo() - changeInfo.newName = "s" - changeInfo.newReturnTypeText = "String" - doTest(changeInfo) - } - - fun testAddPropertyReceiverConflict() { - val changeInfo = getChangeInfo() - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "receiver", BUILT_INS.stringType, null, - KtPsiFactory(project).createExpression("\"\""), JetValVar.None, null) - changeInfo.receiverParameterInfo = newParameter - doTestConflict(changeInfo) - } - - fun testAddPropertyReceiver() { - val changeInfo = getChangeInfo() - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "receiver", BUILT_INS.stringType, null, - KtPsiFactory(project).createExpression("\"\""), JetValVar.None, null) - changeInfo.receiverParameterInfo = newParameter - doTest(changeInfo) - } - - fun testChangePropertyReceiver() { - val changeInfo = getChangeInfo() - //noinspection ConstantConditions - changeInfo.receiverParameterInfo!!.currentTypeText = "Int" - doTest(changeInfo) - } - - fun testRemovePropertyReceiver() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testAddTopLevelPropertyReceiver() { - val changeInfo = getChangeInfo() - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "receiver", null, null, - KtPsiFactory(project).createExpression("A()"), JetValVar.None, null) - newParameter.currentTypeText = "test.A" - changeInfo.receiverParameterInfo = newParameter - doTest(changeInfo) - } - - fun testChangeTopLevelPropertyReceiver() { - val changeInfo = getChangeInfo() - //noinspection ConstantConditions - changeInfo.receiverParameterInfo!!.currentTypeText = "String" - doTest(changeInfo) - } - - fun testRemoveTopLevelPropertyReceiver() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testChangeClassParameter() { - val changeInfo = getChangeInfo() - changeInfo.newName = "s" - changeInfo.newReturnTypeText = "String" - doTest(changeInfo) - } - - fun testParameterPropagation() { - val changeInfo = getChangeInfo() - - val newParameter1 = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", null, null, - KtPsiFactory(project).createExpression("1"), JetValVar.None, null) - newParameter1.currentTypeText = "kotlin.Int" - changeInfo.addParameter(newParameter1) - - val newParameter2 = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "s", null, null, - KtPsiFactory(project).createExpression("\"abc\""), JetValVar.None, null) - newParameter2.currentTypeText = "kotlin.String" - changeInfo.addParameter(newParameter2) - - val classA = KotlinFullClassNameIndex.getInstance().get("A", project, GlobalSearchScope.allScope(project)).iterator().next() - val functionBar = classA.declarations.first { it is KtNamedFunction && it.name == "bar" } - val functionTest = KotlinTopLevelFunctionFqnNameIndex.getInstance().get("test", project, GlobalSearchScope.allScope(project)).iterator().next() - - changeInfo.primaryPropagationTargets = Arrays.asList(functionBar, functionTest) - - doTest(changeInfo) - } - - fun testJavaParameterPropagation() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod): Array { - return arrayOf( - ParameterInfoImpl(-1, "n", PsiType.INT, "1"), - ParameterInfoImpl(-1, "s", PsiType.getJavaLangString(psiManager, GlobalSearchScope.allScope(project)), "\"abc\"") - ) - } - - override fun getParameterPropagationTargets(method: PsiMethod): Set { - val classA = JavaFullClassNameIndex.getInstance() - .get("A".hashCode(), project, GlobalSearchScope.allScope(project)) - .first { it.name == "A" } - val methodBar = classA.methods.first { it.name == "bar" } - val functionTest = KotlinTopLevelFunctionFqnNameIndex.getInstance() - .get("test", project, GlobalSearchScope.allScope(project)) - .first() - return setOf(methodBar, functionTest.getRepresentativeLightMethod()!!) - } - }) - } - - fun testPropagateWithParameterDuplication() { - val changeInfo = getChangeInfo() - - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, - KtPsiFactory(project).createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - - val functionBar = KotlinTopLevelFunctionFqnNameIndex.getInstance().get("bar", project, GlobalSearchScope.allScope(project)).iterator().next() - - changeInfo.primaryPropagationTargets = listOf(functionBar) - - doTestConflict(changeInfo) - } - - fun testPropagateWithVariableDuplication() { - val changeInfo = getChangeInfo() - - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, - KtPsiFactory(project).createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - - val functionBar = KotlinTopLevelFunctionFqnNameIndex.getInstance().get("bar", project, GlobalSearchScope.allScope(project)).iterator().next() - - changeInfo.primaryPropagationTargets = listOf(functionBar) - - doTestConflict(changeInfo) - } - - fun testPropagateWithThisQualificationInClassMember() { - val changeInfo = getChangeInfo() - - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, - KtPsiFactory(project).createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - - val classA = KotlinFullClassNameIndex.getInstance().get("A", project, GlobalSearchScope.allScope(project)).iterator().next() - val functionBar = classA.declarations.first { it is KtNamedFunction && it.name == "bar" } - changeInfo.primaryPropagationTargets = listOf(functionBar) - - doTest(changeInfo) - } - - fun testPropagateWithThisQualificationInExtension() { - val changeInfo = getChangeInfo() - - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, - KtPsiFactory(project).createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - - val functionBar = KotlinTopLevelFunctionFqnNameIndex.getInstance().get("bar", project, GlobalSearchScope.allScope(project)).iterator().next() - - changeInfo.primaryPropagationTargets = listOf(functionBar) - - doTest(changeInfo) - } - - fun testJavaConstructorParameterPropagation() { - doJavaTest( - object : JavaRefactoringProvider() { - override fun getNewParameters(method: PsiMethod) = arrayOf(ParameterInfoImpl(-1, "n", PsiType.INT, "1")) - - override fun getParameterPropagationTargets(method: PsiMethod) = findCallers(method) - } - ) - } - - fun testPrimaryConstructorParameterPropagation() { - val changeInfo = getChangeInfo() - - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, - KtPsiFactory(project).createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - - val constructor = changeInfo.method.getRepresentativeLightMethod() - assert(constructor != null) - changeInfo.primaryPropagationTargets = findCallers(constructor!!) - - doTest(changeInfo) - } - - fun testSecondaryConstructorParameterPropagation() { - val changeInfo = getChangeInfo() - - val newParameter = JetParameterInfo(changeInfo.methodDescriptor.baseDescriptor, - -1, "n", BUILT_INS.intType, null, - KtPsiFactory(project).createExpression("1"), JetValVar.None, null) - changeInfo.addParameter(newParameter) - - val constructor = changeInfo.method.getRepresentativeLightMethod() - assert(constructor != null) - changeInfo.primaryPropagationTargets = findCallers(constructor!!) - - doTest(changeInfo) - } - - fun testJavaMethodOverridesOmitUnitType() { - doJavaTest(JavaRefactoringProvider()) - } - - fun testOverrideInAnonymousObjectWithTypeParameters() { - val changeInfo = getChangeInfo() - changeInfo.newName = "bar" - doTest(changeInfo) - } - - fun testMakePrimaryConstructorPrivateNoParams() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.PRIVATE - doTest(changeInfo) - } - - fun testMakePrimaryConstructorPublic() { - val changeInfo = getChangeInfo() - changeInfo.newVisibility = Visibilities.PUBLIC - doTest(changeInfo) - } - - fun testRenameExtensionParameterWithNamedArgs() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[2].name = "bb" - doTest(changeInfo) - } - - fun testImplicitThisToParameterWithChangedType() { - val changeInfo = getChangeInfo() - changeInfo.receiverParameterInfo!!.currentTypeText = "Older" - changeInfo.receiverParameterInfo = null - doTest(changeInfo) - } - - fun testJvmOverloadedRenameParameter() { - val changeInfo = getChangeInfo() - changeInfo.newParameters[0].name = "aa" - doTest(changeInfo) - } - - fun testJvmOverloadedSwapParams1() { - val changeInfo = getChangeInfo() - val param = changeInfo.newParameters[1] - changeInfo.setNewParameter(1, changeInfo.newParameters[2]) - changeInfo.setNewParameter(2, param) - doTest(changeInfo) - } - - fun testJvmOverloadedSwapParams2() { - val changeInfo = getChangeInfo() - val param = changeInfo.newParameters[0] - changeInfo.setNewParameter(0, changeInfo.newParameters[2]) - changeInfo.setNewParameter(2, param) - doTest(changeInfo) - } - - private fun doTestJvmOverloadedAddDefault(index: Int) { - val changeInfo = getChangeInfo() - val defaultValue = KtPsiFactory(project).createExpression("2") - val descriptor = changeInfo.methodDescriptor.baseDescriptor - changeInfo.addParameter(JetParameterInfo(descriptor, -1, "n", BUILT_INS.intType, defaultValue, defaultValue), index) - doTest(changeInfo) - } - - private fun doTestJvmOverloadedAddNonDefault(index: Int) { - val changeInfo = getChangeInfo() - val defaultValue = KtPsiFactory(project).createExpression("2") - val descriptor = changeInfo.methodDescriptor.baseDescriptor - changeInfo.addParameter(JetParameterInfo(descriptor, -1, "n", BUILT_INS.intType, null, defaultValue), index) - doTest(changeInfo) - } - - private fun doTestRemoveAt(index: Int) { - val changeInfo = getChangeInfo() - changeInfo.removeParameter(if (index >= 0) index else changeInfo.getNewParametersCount() - 1) - doTest(changeInfo) - } - - fun testJvmOverloadedAddDefault1() { - doTestJvmOverloadedAddDefault(0) - } - - fun testJvmOverloadedAddDefault2() { - doTestJvmOverloadedAddDefault(1) - } - - fun testJvmOverloadedAddDefault3() { - doTestJvmOverloadedAddDefault(-1) - } - - fun testJvmOverloadedAddNonDefault1() { - doTestJvmOverloadedAddNonDefault(0) - } - - fun testJvmOverloadedAddNonDefault2() { - doTestJvmOverloadedAddNonDefault(1) - } - - fun testJvmOverloadedAddNonDefault3() { - doTestJvmOverloadedAddNonDefault(-1) - } - - fun testJvmOverloadedRemoveDefault1() { - doTestRemoveAt(0) - } - - fun testJvmOverloadedRemoveDefault2() { - doTestRemoveAt(1) - } - - fun testJvmOverloadedRemoveDefault3() { - doTestRemoveAt(-1) - } - - fun testJvmOverloadedRemoveNonDefault1() { - doTestRemoveAt(0) - } - - fun testJvmOverloadedRemoveNonDefault2() { - doTestRemoveAt(1) - } - - fun testJvmOverloadedRemoveNonDefault3() { - doTestRemoveAt(-1) - } - - fun testJvmOverloadedConstructorSwapParams() { - testJvmOverloadedSwapParams1() + companion object { + private val BUILT_INS = JvmPlatform.builtIns + private val EXTENSIONS = arrayOf(".kt", ".java") } private var editors: MutableList? = null + override fun getTestProjectJdk() = PluginTestCaseBase.mockJdk() + + override fun getTestDataPath() = File(PluginTestCaseBase.getTestDataPathBase(), "/refactoring/changeSignature").path + File.separator + override fun setUp() { super.setUp() editors = ArrayList() @@ -1305,24 +85,10 @@ class JetChangeSignatureTest : KotlinCodeInsightTestCase() { } private fun findCallers(method: PsiMethod): LinkedHashSet { - val rootNode = KotlinMethodNode(method, - HashSet(), - project, - object : Runnable { - override fun run() { - - } - }) - val callers = LinkedHashSet() - for (i in 0..rootNode.childCount - 1) { - val element = (rootNode.getChildAt(i) as KotlinMethodNode).method - callers.addAll(element.toLightMethods()) + val root = KotlinMethodNode(method, HashSet(), project, Runnable { }) + return (0..root.childCount - 1).flatMapTo(LinkedHashSet()) { + (root.getChildAt(it) as KotlinMethodNode).method.toLightMethods() } - return callers - } - - override fun getTestDataPath(): String { - return File(PluginTestCaseBase.getTestDataPathBase(), "/refactoring/changeSignature").path + File.separator } private fun configureFiles() { @@ -1346,73 +112,116 @@ class JetChangeSignatureTest : KotlinCodeInsightTestCase() { setActiveEditor(editors!![0]) } - private fun getChangeInfo(): JetChangeInfo { + private fun createChangeInfo(): JetChangeInfo { configureFiles() - val editor = editor - val file = file - val project = project - - val element = JetChangeSignatureHandler().findTargetMember(file, editor) as KtElement? - TestCase.assertNotNull("Target element is null", element) - - val bindingContext = element!!.analyze(BodyResolveMode.FULL) - val context = file.findElementAt(editor.caretModel.offset) - TestCase.assertNotNull(context) - - val callableDescriptor = JetChangeSignatureHandler.findDescriptor(element, project, editor, bindingContext) - TestCase.assertNotNull(callableDescriptor) - - return createChangeInfo(project, callableDescriptor!!, JetChangeSignatureConfiguration.Empty, context!!)!! + val element = (JetChangeSignatureHandler().findTargetMember(file, editor) as KtElement?).sure { "Target element is null" } + val context = file.findElementAt(editor.caretModel.offset).sure { "Context element is null" } + val bindingContext = element.analyze(BodyResolveMode.FULL) + val callableDescriptor = JetChangeSignatureHandler + .findDescriptor(element, project, editor, bindingContext) + .sure { "Target descriptor is null" } + return createChangeInfo(project, callableDescriptor, JetChangeSignatureConfiguration.Empty, context)!! } - private open inner class JavaRefactoringProvider { - open fun getNewName(method: PsiMethod) = method.name + private fun doTest(configure: JetChangeInfo.() -> Unit = {}) { + JetChangeSignatureProcessor(project, createChangeInfo().apply { configure() }, "Change signature").run() - open fun getNewReturnType(method: PsiMethod) = method.returnType ?: PsiType.VOID + compareEditorsWithExpectedData() + } - open fun getNewParameters(method: PsiMethod): Array { - val parameters = method.parameterList.parameters - return Array(parameters.size) { i -> - val parameter = parameters[i] - ParameterInfoImpl(i, parameter.name, parameter.type) + private fun doTestConflict(configure: JetChangeInfo.() -> Unit = {}) { + try { + doTest(configure) + TestCase.fail("No conflicts found") + } + catch (e: Throwable) { + val message = when { + e is BaseRefactoringProcessor.ConflictsInTestsException -> StringUtil.join(e.messages.sorted(), "\n") + e is CommonRefactoringUtil.RefactoringErrorHintException -> e.message + e is RuntimeException && e.message!!.startsWith("Refactoring cannot be performed") -> e.message + else -> throw e } + val conflictsFile = File(testDataPath + getTestName(false) + "Messages.txt") + UsefulTestCase.assertSameLinesWithFile(conflictsFile.absolutePath, message) + } + } + + private fun doTestUnmodifiable(configure: JetChangeInfo.() -> Unit = {}) { + try { + doTest(configure) + TestCase.fail("No conflicts found") + } + catch (e: RuntimeException) { + if ((e.message ?: "").contains("Cannot modify file")) return + + val message = when { + e is BaseRefactoringProcessor.ConflictsInTestsException -> StringUtil.join(e.messages.sorted(), "\n") + e is CommonRefactoringUtil.RefactoringErrorHintException -> e.message + e is RuntimeException && e.message!!.startsWith("Refactoring cannot be performed") -> e.message + else -> throw e + } + val conflictsFile = File(testDataPath + getTestName(false) + "Messages.txt") + UsefulTestCase.assertSameLinesWithFile(conflictsFile.absolutePath, message) + } + } + + private class JavaRefactoringConfiguration(val method: PsiMethod) { + val project = method.project + + var newName = method.name + var newReturnType = method.returnType ?: PsiType.VOID + val newParameters = ArrayList() + val parameterPropagationTargets = LinkedHashSet() + + val psiFactory: PsiElementFactory + get() = JavaPsiFacade.getInstance(project).elementFactory + + val objectPsiType: PsiType + get() = PsiType.getJavaLangObject(method.manager, project.allScope()) + + val stringPsiType: PsiType + get() = PsiType.getJavaLangString(method.manager, project.allScope()) + + init { + method.parameterList.parameters + .withIndex() + .mapTo(newParameters) { + val (i, param) = it + ParameterInfoImpl(i, param.name, param.type) + } } - open fun getParameterPropagationTargets(method: PsiMethod) = emptySet() - - fun getProcessor(method: PsiMethod): ChangeSignatureProcessor { + fun createProcessor(): ChangeSignatureProcessor { return ChangeSignatureProcessor( project, method, false, VisibilityUtil.getVisibilityModifier(method.modifierList), - getNewName(method), - CanonicalTypes.createTypeWrapper(getNewReturnType(method)), - getNewParameters(method), - arrayOfNulls(0), - getParameterPropagationTargets(method), + newName, + CanonicalTypes.createTypeWrapper(newReturnType), + newParameters.toTypedArray(), + arrayOf(), + parameterPropagationTargets, emptySet() ) } } - private fun doJavaTest(provider: JavaRefactoringProvider) { + private fun doJavaTest(configure: JavaRefactoringConfiguration.() -> Unit) { configureFiles() val targetElement = TargetElementUtil.findTargetElement(editor, ELEMENT_NAME_ACCEPTED or REFERENCED_ELEMENT_ACCEPTED) - TestCase.assertTrue(" is not on method name", targetElement is PsiMethod) + val targetMethod = (targetElement as? PsiMethod).sure { " is not on method name" } - provider.getProcessor(targetElement as PsiMethod).run() + JavaRefactoringConfiguration(targetMethod) + .apply { configure() } + .createProcessor() + .run() compareEditorsWithExpectedData() } - private fun doTest(changeInfo: JetChangeInfo) { - JetChangeSignatureProcessor(project, changeInfo, "Change signature").run() - compareEditorsWithExpectedData() - } - private fun compareEditorsWithExpectedData() { //noinspection ConstantConditions val checkErrorsAfter = InTextDirectivesUtils.isDirectiveDefined(getPsiFile(editors!![0].document)!!.text, @@ -1434,25 +243,594 @@ class JetChangeSignatureTest : KotlinCodeInsightTestCase() { } } - private fun doTestConflict(changeInfo: JetChangeInfo) { - try { - JetChangeSignatureProcessor(project, changeInfo, "Change signature").run() - } - catch (e: BaseRefactoringProcessor.ConflictsInTestsException) { - val messages = ArrayList(e.messages) - Collections.sort(messages) - val conflictsFile = File(testDataPath + getTestName(false) + "Messages.txt") - UsefulTestCase.assertSameLinesWithFile(conflictsFile.absolutePath, StringUtil.join(messages, "\n")) - return - } - - TestCase.fail("No conflicts found") + private fun JetChangeInfo.swapParameters(i: Int, j: Int) { + val newParameters = newParameters + val temp = newParameters[i] + setNewParameter(i, newParameters[j]) + setNewParameter(j, temp) } - override fun getTestProjectJdk() = PluginTestCaseBase.mockJdk() + // --------------------------------- Tests --------------------------------- - companion object { - private val BUILT_INS = JvmPlatform.builtIns - private val EXTENSIONS = arrayOf(".kt", ".java") + fun testBadSelection() { + configureByFile(getTestName(false) + "Before.kt") + TestCase.assertNull(JetChangeSignatureHandler().findTargetMember(file, editor)) } + + fun testSynthesized() = doTestConflict() + + fun testPreferContainedInClass() = TestCase.assertEquals("param", createChangeInfo().newParameters[0].name) + + fun testRenameFunction() = doTest { newName = "after" } + + fun testChangeReturnType() = doTest { newReturnTypeText = "Float" } + + fun testAddReturnType() = doTest { newReturnTypeText = "Float" } + + fun testRemoveReturnType() = doTest { newReturnTypeText = "Unit" } + + fun testChangeConstructorVisibility() = doTest { newVisibility = Visibilities.PROTECTED } + + fun testAddConstructorVisibility() = doTest { + newVisibility = Visibilities.PROTECTED + + val newParameter = JetParameterInfo( + callableDescriptor = originalBaseFunctionDescriptor, + name = "x", + type = BUILT_INS.anyType, + defaultValueForCall = KtPsiFactory(project).createExpression("12"), + valOrVar = JetValVar.Val + ) + addParameter(newParameter) + } + + fun testConstructor() = doTest { + newVisibility = Visibilities.PUBLIC + + newParameters[0].valOrVar = JetValVar.Var + newParameters[1].valOrVar = JetValVar.None + newParameters[2].valOrVar = JetValVar.Val + + newParameters[0].name = "_x1" + newParameters[1].name = "_x2" + newParameters[2].name = "_x3" + + newParameters[1].currentTypeText = "Float?" + } + + fun testGenericConstructor() = doTest { + newVisibility = Visibilities.PUBLIC + + newParameters[0].valOrVar = JetValVar.Var + newParameters[1].valOrVar = JetValVar.None + newParameters[2].valOrVar = JetValVar.Val + + newParameters[0].name = "_x1" + newParameters[1].name = "_x2" + newParameters[2].name = "_x3" + + newParameters[1].currentTypeText = "Double?" + } + + fun testConstructorSwapArguments() = doTest { + newParameters[0].name = "_x1" + newParameters[1].name = "_x2" + + swapParameters(0, 2) + } + + fun testFunctions() = doTest { + newVisibility = Visibilities.PUBLIC + + newParameters[0].name = "_x1" + newParameters[1].name = "_x2" + newParameters[2].name = "_x3" + + newParameters[1].currentTypeText = "Float?" + } + + fun testGenericFunctions() = doTest() { + newVisibility = Visibilities.PUBLIC + + newParameters[0].name = "_x1" + newParameters[1].name = "_x2" + newParameters[2].name = "_x3" + + newParameters[1].currentTypeText = "Double?" + } + + fun testExpressionFunction() = doTest { + newParameters[0].name = "x1" + + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "y1", BUILT_INS.intType)) + } + + fun testFunctionsAddRemoveArguments() = doTest { + newVisibility = Visibilities.INTERNAL + + val defaultValueForCall = KtPsiFactory(project).createExpression("null") + val newParameters = newParameters + setNewParameter(2, newParameters[1]) + setNewParameter(1, newParameters[0]) + setNewParameter(0, JetParameterInfo(originalBaseFunctionDescriptor, -1, "x0", BUILT_INS.nullableAnyType, null, defaultValueForCall)) + } + + fun testFakeOverride() = doTest { + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "i", BUILT_INS.intType)) + } + + fun testFunctionLiteral() = doTest { + newParameters[1].name = "y1" + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "x", BUILT_INS.anyType)) + + newReturnTypeText = "Int" + } + + fun testVarargs() = doTestConflict() + + fun testUnmodifiableFromLibrary() = doTestUnmodifiable() + + fun testUnmodifiableFromBuiltins() = doTestUnmodifiable() + + fun testInnerFunctionsConflict() = doTestConflict { + newName = "inner2" + newParameters[0].name = "y" + } + + fun testMemberFunctionsConflict() = doTestConflict { + newName = "inner2" + newParameters[0].name = "y" + } + + fun testTopLevelFunctionsConflict() = doTestConflict { newName = "fun2" } + + fun testConstructorsConflict() = doTestConflict { + newParameters[0].name = "_x" + newParameters[1].name = "_y" + newParameters[2].name = "_z" + } + + fun testNoDefaultValuesInOverrides() = doTest { swapParameters(0, 1) } + + fun testOverridesInEnumEntries() = doTest { + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.stringType)) + } + + fun testEnumEntriesWithoutSuperCalls() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + } + + fun testParameterChangeInOverrides() = doTest { + newParameters[0].name = "n" + newParameters[0].currentTypeText = "Int" + } + + fun testConstructorJavaUsages() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"abc\"") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.stringType, null, defaultValueForCall)) + } + + fun testFunctionJavaUsagesAndOverridesAddParam() = doTest { + val psiFactory = KtPsiFactory(project) + val defaultValueForCall1 = psiFactory.createExpression("\"abc\"") + val defaultValueForCall2 = psiFactory.createExpression("\"def\"") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.stringType, null, defaultValueForCall1)) + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "o", BUILT_INS.nullableAnyType, null, defaultValueForCall2)) + } + + fun testFunctionJavaUsagesAndOverridesChangeNullability() = doTest { + newParameters[1].currentTypeText = "String?" + newParameters[2].currentTypeText = "Any" + + newReturnTypeText = "String?" + } + + fun testFunctionJavaUsagesAndOverridesChangeTypes() = doTest { + newParameters[0].currentTypeText = "String?" + newParameters[1].currentTypeText = "Int" + newParameters[2].currentTypeText = "Long?" + + newReturnTypeText = "Any?" + } + + fun testGenericsWithOverrides() = doTest { + newParameters[0].currentTypeText = "List" + newParameters[1].currentTypeText = "A?" + newParameters[2].currentTypeText = "U" + + newReturnTypeText = "U?" + } + + fun testAddReceiverToGenericsWithOverrides() = doTest { + val parameterInfo = newParameters[0] + parameterInfo.currentTypeText = "U" + receiverParameterInfo = parameterInfo + } + + fun testJavaMethodKotlinUsages() = doJavaTest { + newName = "bar" + newParameters.removeAt(1) + } + + fun testJavaConstructorKotlinUsages() = doJavaTest { newParameters.removeAt(1) } + + fun testSAMAddToEmptyParamList() = doJavaTest { newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType)) } + + fun testSAMAddToSingletonParamList() = doJavaTest { newParameters.add(0, ParameterInfoImpl(-1, "n", PsiType.INT)) } + + fun testSAMAddToNonEmptyParamList() = doJavaTest { newParameters.add(ParameterInfoImpl(-1, "o", objectPsiType)) } + + fun testSAMRemoveSingletonParamList() = doJavaTest { newParameters.clear() } + + fun testSAMRemoveParam() = doJavaTest { newParameters.removeAt(0) } + + fun testSAMRenameParam() = doJavaTest { newParameters[0].name = "p" } + + fun testSAMChangeParamType() = doJavaTest { newParameters[0].setType(objectPsiType) } + + fun testSAMRenameMethod() = doJavaTest { newName = "bar" } + + fun testSAMChangeMethodReturnType() = doJavaTest { newReturnType = objectPsiType } + + fun testGenericsWithSAMConstructors() = doJavaTest { + newParameters[0].setType(psiFactory.createTypeFromText("java.util.List>", method.parameterList)) + newParameters[1].setType(psiFactory.createTypeFromText("X>", method.parameterList)) + + newReturnType = psiFactory.createTypeFromText("X>", method) + } + + fun testFunctionRenameJavaUsages() = doTest { newName = "bar" } + + fun testParameterModifiers() = doTest { addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType)) } + + fun testFqNameShortening() = doTest { + val newParameter = JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.anyType).apply { + currentTypeText = "kotlin.String" + } + addParameter(newParameter) + } + + fun testObjectMember() = doTest { removeParameter(0) } + + fun testParameterListAddParam() = doTest { addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "l", BUILT_INS.longType)) } + + fun testParameterListRemoveParam() = doTest { removeParameter(getNewParametersCount() - 1) } + + fun testParameterListRemoveAllParams() = doTest { clearParameters() } + + fun testAddNewReceiver() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("X(0)") + receiverParameterInfo = JetParameterInfo(originalBaseFunctionDescriptor, -1, "_", BUILT_INS.anyType, null, defaultValueForCall) + .apply { currentTypeText = "X" } + } + + fun testAddNewReceiverForMember() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("X(0)") + receiverParameterInfo = JetParameterInfo(originalBaseFunctionDescriptor, -1, "_", BUILT_INS.anyType, null, defaultValueForCall) + .apply { currentTypeText = "X" } + } + + fun testAddNewReceiverForMemberConflict() = doTestConflict { + val defaultValueForCall = KtPsiFactory(project).createExpression("X(0)") + receiverParameterInfo = JetParameterInfo(originalBaseFunctionDescriptor, -1, "_", BUILT_INS.anyType, null, defaultValueForCall) + .apply { currentTypeText = "X" } + } + + fun testAddNewReceiverConflict() = doTestConflict { + val defaultValueForCall = KtPsiFactory(project).createExpression("X(0)") + receiverParameterInfo = JetParameterInfo(originalBaseFunctionDescriptor, -1, "_", BUILT_INS.anyType, null, defaultValueForCall) + .apply { currentTypeText = "X" } + } + + fun testRemoveReceiver() = doTest { removeParameter(0) } + + fun testRemoveReceiverForMember() = doTest { removeParameter(0) } + + fun testConvertParameterToReceiver1() = doTest { receiverParameterInfo = newParameters[0] } + + fun testConvertParameterToReceiver2() = doTest { receiverParameterInfo = newParameters[1] } + + fun testConvertReceiverToParameter1() = doTest { receiverParameterInfo = null } + + fun testConvertReceiverToParameter2() = doTest { + receiverParameterInfo = null + + val newParameters = newParameters + setNewParameter(0, newParameters[1]) + setNewParameter(1, newParameters[0]) + } + + fun testConvertParameterToReceiverForMember1() = doTest { receiverParameterInfo = newParameters[0] } + + fun testConvertParameterToReceiverForMember2() = doTest { receiverParameterInfo = newParameters[1] } + + fun testConvertParameterToReceiverForMemberConflict() = doTestConflict { receiverParameterInfo = newParameters[0] } + + fun testConvertReceiverToParameterForMember1() = doTest { receiverParameterInfo = null } + + fun testConvertReceiverToParameterForMember2() = doTest { + receiverParameterInfo = null + + val newParameters = newParameters + setNewParameter(0, newParameters[1]) + setNewParameter(1, newParameters[0]) + } + + fun testConvertReceiverToParameterWithNameClash() = doTest { receiverParameterInfo = null } + + fun testConvertReceiverToParameterAndChangeName() = doTest { + receiverParameterInfo = null + newParameters[0].name = "abc" + } + + fun testChangeReceiver() = doTest { receiverParameterInfo = newParameters[1] } + + fun testChangeReceiverForMember() = doTest { receiverParameterInfo = newParameters[1] } + + fun testChangeParameterTypeWithImport() = doTest { newParameters[0].currentTypeText = "a.Bar" } + + fun testSecondaryConstructor() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"foo\"") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.stringType, null, defaultValueForCall)) + } + + fun testJavaConstructorInDelegationCall() = doJavaTest { newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType, "\"foo\"")) } + + fun testPrimaryConstructorByThisRef() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"foo\"") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.stringType, null, defaultValueForCall)) + } + + fun testPrimaryConstructorBySuperRef() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"foo\"") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.stringType, null, defaultValueForCall)) + } + + fun testSecondaryConstructorByThisRef() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"foo\"") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", BUILT_INS.stringType, null, defaultValueForCall)) + } + + fun testSecondaryConstructorBySuperRef() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"foo\"") + addParameter(JetParameterInfo(methodDescriptor.baseDescriptor, -1, "s", BUILT_INS.stringType, null, defaultValueForCall)) + } + + fun testJavaConstructorBySuperRef() = doJavaTest { newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType, "\"foo\"")) } + + fun testNoConflictWithReceiverName() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("0") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "i", BUILT_INS.intType, null, defaultValueForCall)) + } + + fun testRemoveParameterBeforeLambda() = doTest { removeParameter(1) } + + fun testMoveLambdaParameter() = doTest { + val newParameters = newParameters + setNewParameter(1, newParameters[2]) + setNewParameter(2, newParameters[1]) + } + + fun testConvertLambdaParameterToReceiver() = doTest { receiverParameterInfo = newParameters[2] } + + fun testRemoveLambdaParameter() = doTest { removeParameter(2) } + + fun testRemoveEnumConstructorParameter() = doTest { removeParameter(1) } + + fun testRemoveAllEnumConstructorParameters() = doTest { clearParameters() } + + fun testDoNotApplyPrimarySignatureToSecondaryCalls() = doTest { + val newParameters = newParameters + setNewParameter(0, newParameters[1]) + setNewParameter(1, newParameters[0]) + } + + fun testConvertToExtensionAndRename() = doTest { + receiverParameterInfo = newParameters[0] + newName = "foo1" + } + + fun testRenameExtensionParameter() = doTest { newParameters[1].name = "b" } + + fun testConvertParameterToReceiverAddParens() = doTest { receiverParameterInfo = newParameters[0] } + + fun testThisReplacement() = doTest { receiverParameterInfo = null } + + fun testPrimaryConstructorByRef() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + } + + fun testReceiverToParameterExplicitReceiver() = doTest { receiverParameterInfo = null } + + fun testReceiverToParameterImplicitReceivers() = doTest { receiverParameterInfo = null } + + fun testParameterToReceiverExplicitReceiver() = doTest { receiverParameterInfo = newParameters[0] } + + fun testParameterToReceiverImplicitReceivers() = doTest { receiverParameterInfo = newParameters[0] } + + fun testJavaMethodOverridesReplaceParam() = doJavaTest { + newReturnType = stringPsiType + newParameters[0] = ParameterInfoImpl(-1, "x", PsiType.INT, "1") + } + + fun testJavaMethodOverridesChangeParam() = doJavaTest { + newReturnType = stringPsiType + + newParameters[0].name = "x" + newParameters[0].setType(PsiType.INT) + } + + fun testChangeProperty() = doTest { + newName = "s" + newReturnTypeText = "String" + } + + fun testAddPropertyReceiverConflict() = doTestConflict { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"\"") + receiverParameterInfo = JetParameterInfo(originalBaseFunctionDescriptor, -1, "receiver", BUILT_INS.stringType, null, defaultValueForCall) + } + + fun testAddPropertyReceiver() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("\"\"") + receiverParameterInfo = JetParameterInfo(originalBaseFunctionDescriptor, -1, "receiver", BUILT_INS.stringType, null, defaultValueForCall) + } + + fun testChangePropertyReceiver() = doTest { receiverParameterInfo!!.currentTypeText = "Int" } + + fun testRemovePropertyReceiver() = doTest { receiverParameterInfo = null } + + fun testAddTopLevelPropertyReceiver() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("A()") + receiverParameterInfo = JetParameterInfo(originalBaseFunctionDescriptor, -1, "receiver", null, null, defaultValueForCall) + .apply { currentTypeText = "test.A" } + } + + fun testChangeTopLevelPropertyReceiver() = doTest { receiverParameterInfo!!.currentTypeText = "String" } + + fun testRemoveTopLevelPropertyReceiver() = doTest { receiverParameterInfo = null } + + fun testChangeClassParameter() = doTest { + newName = "s" + newReturnTypeText = "String" + } + + fun testParameterPropagation() = doTest { + val psiFactory = KtPsiFactory(project) + + val defaultValueForCall1 = psiFactory.createExpression("1") + val newParameter1 = JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", null, null, defaultValueForCall1) + .apply { currentTypeText = "kotlin.Int" } + addParameter(newParameter1) + + val defaultValueForCall2 = psiFactory.createExpression("\"abc\"") + val newParameter2 = JetParameterInfo(originalBaseFunctionDescriptor, -1, "s", null, null, defaultValueForCall2) + .apply { currentTypeText = "kotlin.String" } + addParameter(newParameter2) + + val classA = KotlinFullClassNameIndex.getInstance().get("A", project, project.allScope()).first() + val functionBar = classA.declarations.first { it is KtNamedFunction && it.name == "bar" } + val functionTest = KotlinTopLevelFunctionFqnNameIndex.getInstance().get("test", project, project.allScope()).first() + + primaryPropagationTargets = listOf(functionBar, functionTest) + } + + fun testJavaParameterPropagation() = doJavaTest { + newParameters.add(ParameterInfoImpl(-1, "n", PsiType.INT, "1")) + newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType, "\"abc\"")) + + val classA = JavaFullClassNameIndex.getInstance().get("A".hashCode(), project, project.allScope()).first { it.name == "A" } + val methodBar = classA.methods.first { it.name == "bar" } + parameterPropagationTargets.add(methodBar) + + val functionTest = KotlinTopLevelFunctionFqnNameIndex.getInstance().get("test", project, project.allScope()).first() + parameterPropagationTargets.add(functionTest.getRepresentativeLightMethod()!!) + } + + fun testPropagateWithParameterDuplication() = doTestConflict { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + + primaryPropagationTargets = listOf(KotlinTopLevelFunctionFqnNameIndex.getInstance().get("bar", project, project.allScope()).first()) + } + + fun testPropagateWithVariableDuplication() = doTestConflict { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + + primaryPropagationTargets = listOf(KotlinTopLevelFunctionFqnNameIndex.getInstance().get("bar", project, project.allScope()).first()) + } + + fun testPropagateWithThisQualificationInClassMember() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + + val classA = KotlinFullClassNameIndex.getInstance().get("A", project, project.allScope()).first() + val functionBar = classA.declarations.first { it is KtNamedFunction && it.name == "bar" } + primaryPropagationTargets = listOf(functionBar) + } + + fun testPropagateWithThisQualificationInExtension() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + + primaryPropagationTargets = listOf(KotlinTopLevelFunctionFqnNameIndex.getInstance().get("bar", project, project.allScope()).first()) + } + + fun testJavaConstructorParameterPropagation() = doJavaTest { + newParameters.add(ParameterInfoImpl(-1, "n", PsiType.INT, "1")) + parameterPropagationTargets.addAll(findCallers(method)) + } + + fun testPrimaryConstructorParameterPropagation() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + + primaryPropagationTargets = findCallers(method.getRepresentativeLightMethod()!!) + } + + fun testSecondaryConstructorParameterPropagation() = doTest { + val defaultValueForCall = KtPsiFactory(project).createExpression("1") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValueForCall)) + + primaryPropagationTargets = findCallers(method.getRepresentativeLightMethod()!!) + } + + fun testJavaMethodOverridesOmitUnitType() = doJavaTest {} + + fun testOverrideInAnonymousObjectWithTypeParameters() = doTest { newName = "bar" } + + fun testMakePrimaryConstructorPrivateNoParams() = doTest { newVisibility = Visibilities.PRIVATE } + + fun testMakePrimaryConstructorPublic() = doTest { newVisibility = Visibilities.PUBLIC } + + fun testRenameExtensionParameterWithNamedArgs() = doTest { newParameters[2].name = "bb" } + + fun testImplicitThisToParameterWithChangedType() = doTest { + receiverParameterInfo!!.currentTypeText = "Older" + receiverParameterInfo = null + } + + fun testJvmOverloadedRenameParameter() = doTest { newParameters[0].name = "aa" } + + fun testJvmOverloadedSwapParams1() = doTest { swapParameters(1, 2) } + + fun testJvmOverloadedSwapParams2() = doTest { swapParameters(0, 2) } + + private fun doTestJvmOverloadedAddDefault(index: Int) = doTest { + val defaultValue = KtPsiFactory(project).createExpression("2") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, defaultValue, defaultValue), index) + } + + private fun doTestJvmOverloadedAddNonDefault(index: Int) = doTest { + val defaultValue = KtPsiFactory(project).createExpression("2") + addParameter(JetParameterInfo(originalBaseFunctionDescriptor, -1, "n", BUILT_INS.intType, null, defaultValue), index) + } + + fun testJvmOverloadedAddDefault1() = doTestJvmOverloadedAddDefault(0) + + fun testJvmOverloadedAddDefault2() = doTestJvmOverloadedAddDefault(1) + + fun testJvmOverloadedAddDefault3() = doTestJvmOverloadedAddDefault(-1) + + fun testJvmOverloadedAddNonDefault1() = doTestJvmOverloadedAddNonDefault(0) + + fun testJvmOverloadedAddNonDefault2() = doTestJvmOverloadedAddNonDefault(1) + + fun testJvmOverloadedAddNonDefault3() = doTestJvmOverloadedAddNonDefault(-1) + + fun testJvmOverloadedRemoveDefault1() = doTest { removeParameter(0) } + + fun testJvmOverloadedRemoveDefault2() = doTest { removeParameter(1) } + + fun testJvmOverloadedRemoveDefault3() = doTest { removeParameter(getNewParametersCount() - 1) } + + fun testJvmOverloadedRemoveNonDefault1() = doTest { removeParameter(0) } + + fun testJvmOverloadedRemoveNonDefault2() = doTest { removeParameter(1) } + + fun testJvmOverloadedRemoveNonDefault3() = doTest { removeParameter(getNewParametersCount() - 1) } + + fun testJvmOverloadedConstructorSwapParams() = doTest { swapParameters(1, 2) } }