diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtParameter.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtParameter.java index 726a270f9f5..98a33cc04d3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtParameter.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtParameter.java @@ -21,6 +21,7 @@ import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.ItemPresentationProviders; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.lexer.KtTokens; @@ -64,6 +65,11 @@ public class KtParameter extends KtNamedDeclarationStub imp return findChildByType(KtTokens.COLON); } + @Nullable + public PsiElement getEqualsToken() { + return findChildByType(KtTokens.EQ); + } + public boolean hasDefaultValue() { KotlinParameterStub stub = getStub(); if (stub != null) { @@ -75,20 +81,10 @@ public class KtParameter extends KtNamedDeclarationStub imp @Nullable public KtExpression getDefaultValue() { KotlinParameterStub stub = getStub(); - if (stub != null && !stub.hasDefaultValue()) { - return null; - } - boolean passedEQ = false; - ASTNode child = getNode().getFirstChildNode(); - while (child != null) { - if (child.getElementType() == KtTokens.EQ) passedEQ = true; - if (passedEQ && child.getPsi() instanceof KtExpression) { - return (KtExpression) child.getPsi(); - } - child = child.getTreeNext(); - } + if (stub != null && !stub.hasDefaultValue()) return null; - return null; + PsiElement equalsToken = getEqualsToken(); + return equalsToken != null ? PsiTreeUtil.getNextSiblingOfType(equalsToken, KtExpression.class) : null; } public boolean isMutable() { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt index 50767c6e0ed..5b8bbd959f5 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt @@ -191,4 +191,10 @@ fun KtSecondaryConstructor.getOrCreateBody(): KtBlockExpression { val anchor = if (delegationCall.isImplicit) valueParameterList else delegationCall val newBody = KtPsiFactory(this).createEmptyBody() return addAfter(newBody, anchor) as KtBlockExpression +} + +fun KtParameter.dropDefaultValue() { + val from = equalsToken ?: return + val to = defaultValue ?: from + deleteChildRange(from, to) } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt index 68214bfa6f6..ad2d7ede2d0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpHelper.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet +import org.jetbrains.kotlin.idea.core.dropDefaultValue import org.jetbrains.kotlin.idea.core.refactoring.createJavaField import org.jetbrains.kotlin.idea.core.refactoring.createJavaMethod import org.jetbrains.kotlin.idea.core.refactoring.createPrimaryConstructorIfAbsent @@ -360,6 +361,7 @@ class KotlinPullUpHelper( } else { member.addModifierWithSpace(KtTokens.OVERRIDE_KEYWORD) + (member as? KtNamedFunction)?.valueParameters?.forEach { it.dropDefaultValue() } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt index e3598ec8910..1583e0c167e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.idea.refactoring.pullUp import com.intellij.psi.PsiClass -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet @@ -46,7 +45,7 @@ fun KtNamedDeclaration.canMoveMemberToJavaClass(targetClass: PsiClass): Boolean if (accessors.isNotEmpty() || delegateExpression != null) return false true } - is KtNamedFunction -> true + is KtNamedFunction -> valueParameters.all { it.defaultValue == null } else -> false } } diff --git a/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.1.java b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.1.java new file mode 100644 index 00000000000..1b4568a8f26 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.1.java @@ -0,0 +1,3 @@ +class A { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.1.java.after b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.1.java.after new file mode 100644 index 00000000000..1b4568a8f26 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.1.java.after @@ -0,0 +1,3 @@ +class A { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.kt b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.kt new file mode 100644 index 00000000000..eb4ce25097d --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.kt @@ -0,0 +1,11 @@ +class B : A() { + // INFO: {"checked": "true", "toAbstract": "true"} + fun foo(n: Int = 1) { + + } +} + +fun test() { + B().foo() + B().foo(2) +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.kt.after b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.kt.after new file mode 100644 index 00000000000..d1a254142f7 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.kt.after @@ -0,0 +1,11 @@ +class B : A() { + // INFO: {"checked": "true", "toAbstract": "true"} + fun foo(n: Int = 1) { + + } +} + +fun test() { + B().foo() + B().foo(2) +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/defaultValuesInOverride.kt b/idea/testData/refactoring/pullUp/k2k/defaultValuesInOverride.kt new file mode 100644 index 00000000000..534118d4a69 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/defaultValuesInOverride.kt @@ -0,0 +1,15 @@ +open class A { + +} + +class B : A() { + // INFO: {"checked": "true", "toAbstract": "true"} + fun foo(n: Int = 1) { + + } +} + +fun test() { + B().foo() + B().foo(2) +} \ No newline at end of file diff --git a/idea/testData/refactoring/pullUp/k2k/defaultValuesInOverride.kt.after b/idea/testData/refactoring/pullUp/k2k/defaultValuesInOverride.kt.after new file mode 100644 index 00000000000..8a9a6cd26c8 --- /dev/null +++ b/idea/testData/refactoring/pullUp/k2k/defaultValuesInOverride.kt.after @@ -0,0 +1,17 @@ +abstract class A { + // INFO: {"checked": "true", "toAbstract": "true"} + abstract fun foo(n: Int = 1) + +} + +class B : A() { + // INFO: {"checked": "true", "toAbstract": "true"} + override fun foo(n: Int) { + + } +} + +fun test() { + B().foo() + B().foo(2) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java index 3c5ee6e8931..6a1eaf6cf7b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/pullUp/PullUpTestGenerated.java @@ -49,6 +49,12 @@ public class PullUpTestGenerated extends AbstractPullUpTest { doKotlinTest(fileName); } + @TestMetadata("defaultValuesInOverride.kt") + public void testDefaultValuesInOverride() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/defaultValuesInOverride.kt"); + doKotlinTest(fileName); + } + @TestMetadata("fromClassToClass.kt") public void testFromClassToClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2k/fromClassToClass.kt"); @@ -232,6 +238,12 @@ public class PullUpTestGenerated extends AbstractPullUpTest { KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClass(this.getClass(), new File("idea/testData/refactoring/pullUp/k2j"), Pattern.compile("^(.+)\\.kt$")); } + @TestMetadata("defaultValuesInOverride.kt") + public void testDefaultValuesInOverride() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2j/defaultValuesInOverride.kt"); + doKotlinTest(fileName); + } + @TestMetadata("fromClassToClass.kt") public void testFromClassToClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/pullUp/k2j/fromClassToClass.kt");