diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt index 9bfafd63c17..806cb6692a7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt @@ -572,11 +572,11 @@ public inline fun PsiElement.forEachDescendantOfType(no }) } -public inline fun PsiElement.anyDescendantOfType(noinline predicate: (T) -> Boolean): Boolean { +public inline fun PsiElement.anyDescendantOfType(noinline predicate: (T) -> Boolean = { true }): Boolean { return findDescendantOfType(predicate) != null } -public inline fun PsiElement.findDescendantOfType(noinline predicate: (T) -> Boolean): T? { +public inline fun PsiElement.findDescendantOfType(noinline predicate: (T) -> Boolean = { true }): T? { var result: T? = null this.accept(object : PsiRecursiveElementVisitor(){ override fun visitElement(element: PsiElement) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/CommentSaver.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/CommentSaver.kt index 5e94f420e13..1dfd3e6c2db 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/CommentSaver.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/CommentSaver.kt @@ -18,12 +18,9 @@ package org.jetbrains.kotlin.idea.core import com.intellij.openapi.util.Key import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiComment -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiRecursiveElementVisitor -import com.intellij.psi.PsiWhiteSpace -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.psi.JetFile +import com.intellij.psi.* +import org.jetbrains.kotlin.lexer.JetToken +import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.psiUtil.* import java.util.ArrayList @@ -35,14 +32,26 @@ public class CommentSaver(originalElements: PsiChildRange) { private val SAVED_TREE_KEY = Key("SAVED_TREE") - private class TreeElement( - var parent: TreeElement? = null, - var prev: TreeElement? = null, - var next: TreeElement? = null, - var firstChild: TreeElement? = null, - var lastChild: TreeElement? = null + private abstract class TreeElement { + public companion object { + public fun create(element: PsiElement): TreeElement? { + val elementType = element.getNode().getElementType() + val treeElement = when (elementType) { + TokenType.WHITE_SPACE -> if (element.textContains('\n')) LineBreakTreeElement() else null + is JetToken -> if (element is PsiComment) CommentTreeElement.create(element) else TokenTreeElement(elementType) + else -> StandardTreeElement() + } +// treeElement?.debugText = element.getText() + return treeElement + } + } + + var parent: TreeElement? = null + var prev: TreeElement? = null + var next: TreeElement? = null + var firstChild: TreeElement? = null + var lastChild: TreeElement? = null - ) { val children: Sequence get() = sequence({ firstChild }, { it.next }) @@ -69,28 +78,34 @@ public class CommentSaver(originalElements: PsiChildRange) { // var debugText: String? = null } - private data class CommentData( + private class StandardTreeElement() : TreeElement() + private class TokenTreeElement(val tokenType: JetToken) : TreeElement() + private class LineBreakTreeElement() : TreeElement() + + private class CommentTreeElement( val commentText: String, val spaceBefore: String, val spaceAfter: String - ) - - private fun PsiComment.buildData(): CommentData { - val spaceBefore = (prevLeaf(skipEmptyElements = true) as? PsiWhiteSpace)?.getText() ?: "" - val spaceAfter = (nextLeaf(skipEmptyElements = true) as? PsiWhiteSpace)?.getText() ?: "" - return CommentData(getText(), spaceBefore, spaceAfter) + ) : TreeElement() { + public companion object { + fun create(comment: PsiComment): CommentTreeElement { + val spaceBefore = (comment.prevLeaf(skipEmptyElements = true) as? PsiWhiteSpace)?.getText() ?: "" + val spaceAfter = (comment.nextLeaf(skipEmptyElements = true) as? PsiWhiteSpace)?.getText() ?: "" + return CommentTreeElement(comment.getText(), spaceBefore, spaceAfter) + } + } } - private val commentsToRestore = LinkedHashMap() + private val commentsToRestore = ArrayList() init { - if (originalElements.any { it.anyDescendantOfTypeTemp() }) { + if (originalElements.any { it.anyDescendantOfType() }) { originalElements.save(null) for (element in originalElements) { element.accept(object : PsiRecursiveElementVisitor(){ override fun visitComment(comment: PsiComment) { - commentsToRestore.put(comment.savedTreeElement!!, comment.buildData()) + commentsToRestore.add(comment.savedTreeElement as CommentTreeElement) } }) } @@ -101,12 +116,14 @@ public class CommentSaver(originalElements: PsiChildRange) { var first: TreeElement? = null var last: TreeElement? = null for (child in this) { - if (!child.shouldSave) continue assert(child.savedTreeElement == null) - val savedChild = TreeElement(parent = parentTreeElement, prev = last) -// savedChild.debugText = child.getText() - child.savedTreeElement = savedChild + val savedChild = TreeElement.create(child) ?: continue + savedChild.parent = parentTreeElement + savedChild.prev = last + if (child !is PsiWhiteSpace) { // we don't try to anchor comments to whitespaces + child.savedTreeElement = savedChild + } last?.next = savedChild last = savedChild @@ -121,9 +138,6 @@ public class CommentSaver(originalElements: PsiChildRange) { parentTreeElement?.lastChild = last } - private val PsiElement.shouldSave: Boolean - get() = this !is PsiWhiteSpace - private var PsiElement.savedTreeElement: TreeElement? get() = getCopyableUserData(SAVED_TREE_KEY) set(value) = putCopyableUserData(SAVED_TREE_KEY, value) @@ -145,7 +159,7 @@ public class CommentSaver(originalElements: PsiChildRange) { createdElement.accept(object : PsiRecursiveElementVisitor() { override fun visitElement(element: PsiElement) { - if (!element.shouldSave) return + if (element is PsiWhiteSpace) return val token = original.findElementAt(element.getStartOffsetIn(createdElement) + rangeInOriginal.getStartOffset()) if (token != null) { @@ -206,47 +220,89 @@ public class CommentSaver(originalElements: PsiChildRange) { } val psiFactory = JetPsiFactory(resultElements.first!!) - for ((treeElement, commentData) in commentsToRestore) { - val comment = psiFactory.createComment(commentData.commentText) + var putAbandonedCommentsAfter = resultElements.last!! - //TODO: should we restore multiple? - val putAfter: PsiElement? = treeElement.prevElements.map { toNewPsiElementMap[it]?.first() }.filterNotNull().firstOrNull() - if (putAfter != null) { - val parent = putAfter.getParent() - parent.addAfter(comment, putAfter) - if (commentData.spaceBefore.isNotEmpty()) { - parent.addAfter(psiFactory.createWhiteSpace(commentData.spaceBefore), putAfter) + for (commentTreeElement in commentsToRestore) { + val comment = psiFactory.createComment(commentTreeElement.commentText) + + val anchorBefore = findAnchor(commentTreeElement, toNewPsiElementMap, before = true) + val anchorAfter = findAnchor(commentTreeElement, toNewPsiElementMap, before = false) + val anchor = chooseAnchor(anchorBefore, anchorAfter) + + if (anchor != null) { + val anchorElement = findFinalAnchorElement(anchor) + val parent = anchorElement.getParent() + if (anchor.before) { + parent.addAfter(comment, anchorElement) + if (commentTreeElement.spaceBefore.isNotEmpty()) { + parent.addAfter(psiFactory.createWhiteSpace(commentTreeElement.spaceBefore), anchorElement) + } } - continue - } - - val putBefore: PsiElement? = treeElement.nextElements.map { toNewPsiElementMap[it]?.first() }.filterNotNull().firstOrNull() - if (putBefore != null) { - val parent = putBefore.getParent() - parent.addBefore(comment, putBefore) - if (commentData.spaceAfter.isNotEmpty()) { - parent.addBefore(psiFactory.createWhiteSpace(commentData.spaceAfter), putBefore) + else { + parent.addBefore(comment, anchorElement) + if (commentTreeElement.spaceAfter.isNotEmpty()) { + parent.addBefore(psiFactory.createWhiteSpace(commentTreeElement.spaceAfter), anchorElement) + } } - continue } - - // TODO: everything deleted, don't restore anything? + else { + putAbandonedCommentsAfter = putAbandonedCommentsAfter.getParent().addAfter(comment, putAbandonedCommentsAfter) + } } } - //TODO - private inline fun PsiElement.anyDescendantOfTypeTemp(): Boolean { - var result = false - this.accept(object : PsiRecursiveElementVisitor(){ - override fun visitElement(element: PsiElement) { - if (result) return - if (element is T) { - result = true - return - } - super.visitElement(element) + private class Anchor(val element: PsiElement, val treeElementsBetween: Collection, val before: Boolean) + + private fun findAnchor(commentTreeElement: CommentTreeElement, toNewPsiElementMap: Map>, before: Boolean): Anchor? { + val treeElementsBetween = ArrayList() + val sequence = if (before) commentTreeElement.prevElements else commentTreeElement.nextElements + for (treeElement in sequence) { + val newPsiElements = toNewPsiElementMap[treeElement] + if (newPsiElements != null) { + var psiElement = newPsiElements.first() //TODO: should we restore multiple? + psiElement = psiElement.parents() + .dropWhile { it.getParent() !is PsiFile && (if (before) it.getNextSibling() else it.getPrevSibling()) == null } + .first() + return Anchor(psiElement, treeElementsBetween, before) } - }) - return result + if (treeElement.firstChild == null) { // we put only leafs into treeElementsBetween + treeElementsBetween.add(treeElement) + } + } + return null + } + + private fun chooseAnchor(anchorBefore: Anchor?, anchorAfter: Anchor?): Anchor? { + if (anchorBefore == null) return anchorAfter + if (anchorAfter == null) return anchorBefore + + val elementsBefore = anchorBefore.treeElementsBetween + val elementsAfter = anchorAfter.treeElementsBetween + + val lineBreakBefore = elementsBefore.any { it is LineBreakTreeElement } + val lineBreakAfter = elementsAfter.any { it is LineBreakTreeElement } + if (lineBreakBefore && !lineBreakAfter) return anchorAfter + + if (elementsBefore.isNotEmpty() && elementsAfter.isEmpty()) return anchorAfter + + return anchorBefore //TODO: more analysis? + } + + private fun findFinalAnchorElement(anchor: Anchor): PsiElement { + val tokensBetween = anchor.treeElementsBetween.filterIsInstance() + var psiElement = anchor.element + if (tokensBetween.isEmpty()) return psiElement + + fun PsiElement.next(): PsiElement? { + val filter = { element: PsiElement -> element !is PsiWhiteSpace && element.getTextLength() > 0 } + return if (anchor.before) nextLeaf(filter) else prevLeaf(filter) + } + + for (token in tokensBetween.reverse()) { + val next = psiElement.next() ?: break + if (next.getNode().getElementType() != token.tokenType) break + psiElement = next + } + return psiElement } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt b/idea/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt index 223a709ede1..8de7c8ae8ef 100644 --- a/idea/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt +++ b/idea/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt @@ -333,6 +333,8 @@ fun createSpacingBuilder(settings: CodeStyleSettings): KotlinSpacingBuilder { // if when entry has block, spacing after arrow should be set by lbrace rule aroundInside(ARROW, WHEN_ENTRY).spaceIf(jetSettings.SPACE_AROUND_WHEN_ARROW) + + after(EOL_COMMENT).lineBreakInCode() } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/DeprecatedSymbolUsageFixBase.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/DeprecatedSymbolUsageFixBase.kt index 45e6f8791a2..56428c2cf0e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/DeprecatedSymbolUsageFixBase.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/DeprecatedSymbolUsageFixBase.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade +import org.jetbrains.kotlin.idea.core.CommentSaver import org.jetbrains.kotlin.idea.core.OptionalParametersHelper import org.jetbrains.kotlin.idea.core.asExpression import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester @@ -42,17 +43,13 @@ import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.renderName import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType -import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType -import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression -import org.jetbrains.kotlin.psi.psiUtil.isAncestor +import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns @@ -62,7 +59,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.utils.addIfNotNull -import java.util.* +import java.util.ArrayList +import java.util.LinkedHashSet //TODO: replacement of class usages //TODO: different replacements for property accessors @@ -136,6 +134,8 @@ public abstract class DeprecatedSymbolUsageFixBase( val qualifiedExpression = callExpression.getParent() as? JetQualifiedExpression val expressionToBeReplaced = qualifiedExpression ?: callExpression + val commentSaver = CommentSaver(expressionToBeReplaced) + var receiver = element.getReceiverExpression()?.marked(USER_CODE_KEY) var receiverType = if (receiver != null) bindingContext.getType(receiver) else null @@ -225,6 +225,12 @@ public abstract class DeprecatedSymbolUsageFixBase( result = postProcessInsertedExpression(result, wrapper.addedStatements) + val resultRange = if (wrapper.addedStatements.isEmpty()) + PsiChildRange.singleElement(result) + else + PsiChildRange(wrapper.addedStatements.first(), result) + commentSaver.restoreComments(resultRange) + return result } diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/commentBeforeArgument.kt b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/commentBeforeArgument.kt new file mode 100644 index 00000000000..9891c165453 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/commentBeforeArgument.kt @@ -0,0 +1,14 @@ +// "Replace with 'newFun(p4, p3, p2, p1, p0)'" "true" + +@deprecated("", ReplaceWith("newFun(p4, p3, p2, p1, p0)")) +fun oldFun(p0: Int, p1: Int, p2: Int, p3: Int, p4: Int){} + +fun newFun(p4: Int, p3: Int, p2: Int, p1: Int, p0: Int){} + + +fun foo() { + oldFun(/* 0 */ 0, + /* 1 */ 1, + 2, // 2 + 3, /* 4 */ 4) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/commentBeforeArgument.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/commentBeforeArgument.kt.after new file mode 100644 index 00000000000..7074f0505dc --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/commentBeforeArgument.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'newFun(p4, p3, p2, p1, p0)'" "true" + +@deprecated("", ReplaceWith("newFun(p4, p3, p2, p1, p0)")) +fun oldFun(p0: Int, p1: Int, p2: Int, p3: Int, p4: Int){} + +fun newFun(p4: Int, p3: Int, p2: Int, p1: Int, p0: Int){} + + +fun foo() { + newFun(/* 4 */ 4, 3, 2, // 2 + /* 1 */ 1, /* 0 */ 0) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/dropArgument.kt b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/dropArgument.kt new file mode 100644 index 00000000000..ac2a3e09ac0 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/dropArgument.kt @@ -0,0 +1,12 @@ +// "Replace with 'newFun()'" "true" + +@deprecated("", ReplaceWith("newFun()")) +fun oldFun(p: Int) { + newFun() +} + +fun newFun(){} + +fun foo() { + oldFun(O /* use zero */) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/dropArgument.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/dropArgument.kt.after new file mode 100644 index 00000000000..0e70fb7b87f --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/dropArgument.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'newFun()'" "true" + +@deprecated("", ReplaceWith("newFun()")) +fun oldFun(p: Int) { + newFun() +} + +fun newFun(){} + +fun foo() { + newFun()/* use zero */ +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/multipleArguments.kt b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/multipleArguments.kt new file mode 100644 index 00000000000..234620b41f0 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/multipleArguments.kt @@ -0,0 +1,15 @@ +// "Replace with 'newFun(this, p1, p2)'" "true" + +interface X { + @deprecated("", ReplaceWith("newFun(this, p1, p2)")) + fun oldFun(p1: Int, p2: Int) +} + +fun newFun(x: X, a: Int, b: Int){} + +fun foo(x: X) { + x/*receiver*/.oldFun( + 1, // pass 1 + 2 // pass 2 + ) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/multipleArguments.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/multipleArguments.kt.after new file mode 100644 index 00000000000..b71e1f0610f --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/multipleArguments.kt.after @@ -0,0 +1,14 @@ +// "Replace with 'newFun(this, p1, p2)'" "true" + +interface X { + @deprecated("", ReplaceWith("newFun(this, p1, p2)")) + fun oldFun(p1: Int, p2: Int) +} + +fun newFun(x: X, a: Int, b: Int){} + +fun foo(x: X) { + newFun(x/*receiver*/, 1, // pass 1 + 2 // pass 2 + ) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/simple.kt b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/simple.kt new file mode 100644 index 00000000000..0e24d83a129 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/simple.kt @@ -0,0 +1,14 @@ +// "Replace with 'newFun(p)'" "true" + +class X { + @deprecated("", ReplaceWith("newFun(p)")) + fun oldFun(p: Int) { + newFun(p) + } + + fun newFun(p: Int){} +} + +fun foo(x: X) { + x/*receiver*/.oldFun(1/*parameter*/) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/simple.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/simple.kt.after new file mode 100644 index 00000000000..0be753cc376 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/simple.kt.after @@ -0,0 +1,14 @@ +// "Replace with 'newFun(p)'" "true" + +class X { + @deprecated("", ReplaceWith("newFun(p)")) + fun oldFun(p: Int) { + newFun(p) + } + + fun newFun(p: Int){} +} + +fun foo(x: X) { + x/*receiver*/.newFun(1/*parameter*/) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/usedTwice.kt b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/usedTwice.kt new file mode 100644 index 00000000000..d7f2405e57c --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/usedTwice.kt @@ -0,0 +1,12 @@ +// "Replace with 'newFun(p, p)'" "true" + +@deprecated("", ReplaceWith("newFun(p, p)")) +fun oldFun(p: Int) { + newFun(p, p) +} + +fun newFun(p1: Int, p2: Int){} + +fun foo() { + oldFun(0/*use zero*/) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/usedTwice.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/usedTwice.kt.after new file mode 100644 index 00000000000..98ab8c9034b --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/usedTwice.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'newFun(p, p)'" "true" + +@deprecated("", ReplaceWith("newFun(p, p)")) +fun oldFun(p: Int) { + newFun(p, p) +} + +fun newFun(p1: Int, p2: Int){} + +fun foo() { + newFun(0/*use zero*/, 0) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/variableForArgument.kt b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/variableForArgument.kt new file mode 100644 index 00000000000..4e75034a4ce --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/variableForArgument.kt @@ -0,0 +1,14 @@ +// "Replace with 'newFun(p, p)'" "true" + +@deprecated("", ReplaceWith("newFun(p, p)")) +fun oldFun(p: Int) { + newFun(p, p) +} + +fun newFun(p1: Int, p2: Int){} + +fun foo() { + oldFun(bar()/*use bar()*/) +} + +fun bar(): Int = 0 diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/variableForArgument.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/variableForArgument.kt.after new file mode 100644 index 00000000000..6d61a53498f --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/keepComments/variableForArgument.kt.after @@ -0,0 +1,15 @@ +// "Replace with 'newFun(p, p)'" "true" + +@deprecated("", ReplaceWith("newFun(p, p)")) +fun oldFun(p: Int) { + newFun(p, p) +} + +fun newFun(p1: Int, p2: Int){} + +fun foo() { + val p = bar()/*use bar()*/ + newFun(p, p) +} + +fun bar(): Int = 0 diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 9cf77f63ccc..ff981b7e1d7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -3217,6 +3217,51 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/keepComments") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class KeepComments extends AbstractQuickFixTest { + public void testAllFilesPresentInKeepComments() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/deprecatedSymbolUsage/keepComments"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("commentBeforeArgument.kt") + public void testCommentBeforeArgument() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/keepComments/commentBeforeArgument.kt"); + doTest(fileName); + } + + @TestMetadata("dropArgument.kt") + public void testDropArgument() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/keepComments/dropArgument.kt"); + doTest(fileName); + } + + @TestMetadata("multipleArguments.kt") + public void testMultipleArguments() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/keepComments/multipleArguments.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/keepComments/simple.kt"); + doTest(fileName); + } + + @TestMetadata("usedTwice.kt") + public void testUsedTwice() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/keepComments/usedTwice.kt"); + doTest(fileName); + } + + @TestMetadata("variableForArgument.kt") + public void testVariableForArgument() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/keepComments/variableForArgument.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)