KT-7895 Auto replace for deprecated (ReplaceWith) loses generic type
#KT-7895 Fixed
This commit is contained in:
@@ -136,9 +136,16 @@ public fun PsiElement.isInsideOf(elements: Iterable<PsiElement>): Boolean = elem
|
||||
// -------------------- Recursive tree visiting --------------------------------------------------------------------------------------------
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.forEachDescendantOfType(noinline action: (T) -> Unit) {
|
||||
forEachDescendantOfType<T>({true}, action)
|
||||
}
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.forEachDescendantOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline action: (T) -> Unit) {
|
||||
this.accept(object : PsiRecursiveElementVisitor(){
|
||||
override fun visitElement(element: PsiElement) {
|
||||
super.visitElement(element)
|
||||
if (canGoInside(element)) {
|
||||
super.visitElement(element)
|
||||
}
|
||||
|
||||
if (element is T) {
|
||||
action(element)
|
||||
}
|
||||
@@ -147,27 +154,43 @@ public inline fun <reified T : PsiElement> PsiElement.forEachDescendantOfType(no
|
||||
}
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.anyDescendantOfType(noinline predicate: (T) -> Boolean = { true }): Boolean {
|
||||
return findDescendantOfType(predicate) != null
|
||||
return findDescendantOfType<T>(predicate) != null
|
||||
}
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.anyDescendantOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline predicate: (T) -> Boolean = { true }): Boolean {
|
||||
return findDescendantOfType<T>(canGoInside, predicate) != null
|
||||
}
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.findDescendantOfType(noinline predicate: (T) -> Boolean = { true }): T? {
|
||||
return findDescendantOfType<T>({ true}, predicate)
|
||||
}
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.findDescendantOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline predicate: (T) -> Boolean = { true }): T? {
|
||||
var result: T? = null
|
||||
this.accept(object : PsiRecursiveElementVisitor(){
|
||||
override fun visitElement(element: PsiElement) {
|
||||
if (result != null) return
|
||||
|
||||
if (element is T && predicate(element)) {
|
||||
result = element
|
||||
return
|
||||
}
|
||||
super.visitElement(element)
|
||||
|
||||
if (canGoInside(element)) {
|
||||
super.visitElement(element)
|
||||
}
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.collectDescendantsOfType(noinline predicate: (T) -> Boolean = { true }): List<T> {
|
||||
return collectDescendantsOfType<T>({ true }, predicate)
|
||||
}
|
||||
|
||||
public inline fun <reified T : PsiElement> PsiElement.collectDescendantsOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline predicate: (T) -> Boolean = { true }): List<T> {
|
||||
val result = ArrayList<T>()
|
||||
forEachDescendantOfType<T> {
|
||||
forEachDescendantOfType<T>(canGoInside) {
|
||||
if (predicate(it)) {
|
||||
result.add(it)
|
||||
}
|
||||
|
||||
+2
-1
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArguments
|
||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||
import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.createTempCopy
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||
@@ -251,7 +252,7 @@ private fun addDebugExpressionBeforeContextElement(codeFragment: JetCodeFragment
|
||||
private fun replaceByRunFunction(expression: JetExpression): JetCallExpression {
|
||||
val callExpression = JetPsiFactory(expression).createExpression("run { \n${expression.getText()} \n}") as JetCallExpression
|
||||
val replaced = expression.replaced(callExpression)
|
||||
val typeArguments = InsertExplicitTypeArguments.createTypeArguments(replaced)
|
||||
val typeArguments = InsertExplicitTypeArguments.createTypeArguments(replaced, replaced.analyze())
|
||||
if (typeArguments?.getArguments()?.isNotEmpty() ?: false) {
|
||||
val calleeExpression = replaced.getCalleeExpression()
|
||||
replaced.addAfter(typeArguments!!, calleeExpression)
|
||||
|
||||
@@ -16,29 +16,26 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.psi.JetCallExpression
|
||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.psi.JetTypeArgumentList
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
|
||||
public class InsertExplicitTypeArguments : JetSelfTargetingIntention<JetCallExpression>(javaClass(), "Add explicit type arguments") {
|
||||
override fun isApplicableTo(element: JetCallExpression, caretOffset: Int): Boolean {
|
||||
if (!element.getTypeArguments().isEmpty()) return false
|
||||
val callee = element.getCalleeExpression() ?: return false
|
||||
if (!callee.getTextRange().containsOffset(caretOffset)) return false
|
||||
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return false
|
||||
val typeArgs = resolvedCall.getTypeArguments()
|
||||
return !typeArgs.isEmpty() && typeArgs.values().none { ErrorUtils.containsErrorType(it) }
|
||||
public class InsertExplicitTypeArguments : JetSelfTargetingRangeIntention<JetCallExpression>(javaClass(), "Add explicit type arguments"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: JetCallExpression): TextRange? {
|
||||
return if (isApplicableTo(element, element.analyze())) element.getCalleeExpression()!!.getTextRange() else null
|
||||
}
|
||||
|
||||
override fun applyTo(element: JetCallExpression, editor: Editor) {
|
||||
val argumentList = createTypeArguments(element)!!
|
||||
val argumentList = createTypeArguments(element, element.analyze())!!
|
||||
|
||||
val callee = element.getCalleeExpression()!!
|
||||
val newArgumentList = element.addAfter(argumentList, callee) as JetTypeArgumentList
|
||||
@@ -47,8 +44,17 @@ public class InsertExplicitTypeArguments : JetSelfTargetingIntention<JetCallExpr
|
||||
}
|
||||
|
||||
companion object {
|
||||
public fun createTypeArguments(element: JetCallExpression): JetTypeArgumentList? {
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null
|
||||
public fun isApplicableTo(element: JetCallExpression, bindingContext: BindingContext): Boolean {
|
||||
if (!element.getTypeArguments().isEmpty()) return false
|
||||
if (element.getCalleeExpression() == null) return false
|
||||
|
||||
val resolvedCall = element.getResolvedCall(bindingContext) ?: return false
|
||||
val typeArgs = resolvedCall.getTypeArguments()
|
||||
return typeArgs.isNotEmpty() && typeArgs.values().none { ErrorUtils.containsErrorType(it) }
|
||||
}
|
||||
|
||||
public fun createTypeArguments(element: JetCallExpression, bindingContext: BindingContext): JetTypeArgumentList? {
|
||||
val resolvedCall = element.getResolvedCall(bindingContext) ?: return null
|
||||
|
||||
val args = resolvedCall.getTypeArguments()
|
||||
val types = resolvedCall.getCandidateDescriptor().getTypeParameters()
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.core.*
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.JetNameValidator
|
||||
import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.setType
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||
@@ -197,6 +198,27 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
||||
}
|
||||
}
|
||||
|
||||
for (typeParameter in descriptor.getOriginal().getTypeParameters()) {
|
||||
val parameterName = typeParameter.getName()
|
||||
val usages = replacement.expression.collectDescendantsOfType<JetExpression> {
|
||||
it[ReplaceWithAnnotationAnalyzer.TYPE_PARAMETER_USAGE_KEY] == parameterName
|
||||
}
|
||||
|
||||
val type = resolvedCall.getTypeArguments()[typeParameter]!!
|
||||
val typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||
|
||||
for (usage in usages) {
|
||||
val parent = usage.getParent()
|
||||
if (parent is JetUserType) {
|
||||
val typeReference = psiFactory.createType(typeString)
|
||||
parent.replace(typeReference.getTypeElement()!!)
|
||||
}
|
||||
else { //TODO: tests for this?
|
||||
usage.replace(psiFactory.createExpression(typeString))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val wrapper = ConstructedExpressionWrapper(replacement.expression, expressionToBeReplaced, bindingContext)
|
||||
|
||||
if (qualifiedExpression is JetSafeQualifiedExpression) {
|
||||
@@ -227,15 +249,16 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
||||
.flatMap { file.resolveImportReference(it) }
|
||||
.forEach { ImportInsertHelper.getInstance(project).importDescriptor(file, it) }
|
||||
|
||||
result = postProcessInsertedExpression(result, wrapper.addedStatements)
|
||||
|
||||
val resultRange = if (wrapper.addedStatements.isEmpty())
|
||||
var resultRange = if (wrapper.addedStatements.isEmpty())
|
||||
PsiChildRange.singleElement(result)
|
||||
else
|
||||
PsiChildRange(wrapper.addedStatements.first(), result)
|
||||
|
||||
resultRange = postProcessInsertedExpression(resultRange)
|
||||
|
||||
commentSaver.restore(resultRange)
|
||||
|
||||
return result
|
||||
return resultRange.last as JetExpression
|
||||
}
|
||||
|
||||
private fun ConstructedExpressionWrapper.wrapExpressionForSafeCall(receiver: JetExpression, receiverType: JetType?) {
|
||||
@@ -358,16 +381,20 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
||||
}
|
||||
}
|
||||
|
||||
private fun postProcessInsertedExpression(result: JetExpression, additionalStatements: Collection<JetExpression>): JetExpression {
|
||||
var allExpressions = listOf(result) + additionalStatements
|
||||
private fun postProcessInsertedExpression(range: PsiChildRange): PsiChildRange {
|
||||
val expressions = range.filterIsInstance<JetExpression>().toList()
|
||||
|
||||
allExpressions.forEach {
|
||||
expressions.forEach {
|
||||
introduceNamedArguments(it)
|
||||
|
||||
restoreFunctionLiteralArguments(it)
|
||||
|
||||
//TODO: do this earlier
|
||||
dropArgumentsForDefaultValues(it)
|
||||
|
||||
simplifySpreadArrayOfArguments(it)
|
||||
|
||||
removeExplicitTypeArguments(it)
|
||||
}
|
||||
|
||||
|
||||
@@ -384,17 +411,16 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
||||
}
|
||||
}
|
||||
|
||||
allExpressions = allExpressions.map {
|
||||
val newExpressions = expressions.map {
|
||||
ShortenReferences({ ShortenReferences.Options(removeThis = true) }).process(it, shortenFilter) as JetExpression
|
||||
}
|
||||
|
||||
allExpressions.forEach {
|
||||
simplifySpreadArrayOfArguments(it)
|
||||
|
||||
newExpressions.forEach {
|
||||
// clean up user data
|
||||
it.forEachDescendantOfType<JetExpression> {
|
||||
it.clear(USER_CODE_KEY)
|
||||
it.clear(ReplaceWithAnnotationAnalyzer.PARAMETER_USAGE_KEY)
|
||||
it.clear(ReplaceWithAnnotationAnalyzer.TYPE_PARAMETER_USAGE_KEY)
|
||||
it.clear(PARAMETER_VALUE_KEY)
|
||||
it.clear(RECEIVER_VALUE_KEY)
|
||||
it.clear(WAS_FUNCTION_LITERAL_ARGUMENT_KEY)
|
||||
@@ -405,7 +431,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
||||
}
|
||||
}
|
||||
|
||||
return allExpressions.first()
|
||||
return PsiChildRange(newExpressions.first(), newExpressions.last())
|
||||
}
|
||||
|
||||
private fun introduceNamedArguments(result: JetExpression) {
|
||||
@@ -484,32 +510,27 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeExplicitTypeArguments(result: JetExpression) {
|
||||
val intention = RemoveExplicitTypeArgumentsIntention()
|
||||
result.collectDescendantsOfType<JetTypeArgumentList>(canGoInside = { !it[USER_CODE_KEY] }) { intention.isApplicableTo(it) }
|
||||
.forEach { it.delete() }
|
||||
}
|
||||
|
||||
private fun simplifySpreadArrayOfArguments(expression: JetExpression) {
|
||||
//TODO: test for nested
|
||||
|
||||
val argumentsToExpand = ArrayList<Pair<JetValueArgument, Collection<JetValueArgument>>>()
|
||||
|
||||
expression.accept(object : JetTreeVisitorVoid() {
|
||||
override fun visitArgument(argument: JetValueArgument) {
|
||||
super.visitArgument(argument)
|
||||
|
||||
if (argument.getSpreadElement() != null && !argument.isNamed()) {
|
||||
val call = argument.getArgumentExpression() as? JetCallExpression
|
||||
if (call != null) {
|
||||
val resolvedCall = call.getResolvedCall(call.analyze(BodyResolveMode.PARTIAL))
|
||||
if (resolvedCall != null && CompileTimeConstantUtils.isArrayMethodCall(resolvedCall)) {
|
||||
argumentsToExpand.add(argument to call.getValueArguments())
|
||||
}
|
||||
}
|
||||
expression.forEachDescendantOfType<JetValueArgument>(canGoInside = { !it[USER_CODE_KEY] }) { argument ->
|
||||
if (argument.getSpreadElement() != null && !argument.isNamed()) {
|
||||
val argumentExpression = argument.getArgumentExpression() ?: return@forEachDescendantOfType
|
||||
val resolvedCall = argumentExpression.getResolvedCall(argumentExpression.analyze(BodyResolveMode.PARTIAL)) ?: return@forEachDescendantOfType
|
||||
val callExpression = resolvedCall.getCall().getCallElement() as? JetCallExpression ?: return@forEachDescendantOfType
|
||||
if (CompileTimeConstantUtils.isArrayMethodCall(resolvedCall)) {
|
||||
argumentsToExpand.add(argument to callExpression.getValueArguments())
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitJetElement(element: JetElement) {
|
||||
if (!element[USER_CODE_KEY]) { // do not go inside original user's code
|
||||
super.visitJetElement(element)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for ((argument, replacements) in argumentsToExpand) {
|
||||
argument.replaceByMultiple(replacements)
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.core.copied
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArguments
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -53,6 +54,7 @@ data class ReplaceWith(val expression: String, vararg val imports: String)
|
||||
|
||||
object ReplaceWithAnnotationAnalyzer {
|
||||
public val PARAMETER_USAGE_KEY: Key<Name> = Key("PARAMETER_USAGE")
|
||||
public val TYPE_PARAMETER_USAGE_KEY: Key<Name> = Key("TYPE_PARAMETER_USAGE")
|
||||
|
||||
public data class ReplacementExpression(
|
||||
val expression: JetExpression,
|
||||
@@ -94,7 +96,23 @@ object ReplaceWithAnnotationAnalyzer {
|
||||
val symbolScope = getResolutionScope(symbolDescriptor)
|
||||
val scope = ChainedScope(symbolDescriptor, "ReplaceWith resolution scope", ExplicitImportsScope(explicitlyImportedSymbols), symbolScope)
|
||||
|
||||
val bindingContext = expression.analyzeInContext(scope)
|
||||
var bindingContext = expression.analyzeInContext(scope)
|
||||
|
||||
val typeArgsToAdd = ArrayList<Pair<JetCallExpression, JetTypeArgumentList>>()
|
||||
expression.forEachDescendantOfType<JetCallExpression> {
|
||||
if (InsertExplicitTypeArguments.isApplicableTo(it, bindingContext)) {
|
||||
typeArgsToAdd.add(it to InsertExplicitTypeArguments.createTypeArguments(it, bindingContext)!!)
|
||||
}
|
||||
}
|
||||
|
||||
if (typeArgsToAdd.isNotEmpty()) {
|
||||
for ((callExpr, typeArgs) in typeArgsToAdd) {
|
||||
callExpr.addAfter(typeArgs, callExpr.getCalleeExpression())
|
||||
}
|
||||
|
||||
// reanalyze expression - new usages of type parameters may be added
|
||||
bindingContext = expression.analyzeInContext(scope)
|
||||
}
|
||||
|
||||
val receiversToAdd = ArrayList<Pair<JetExpression, JetExpression>>()
|
||||
|
||||
@@ -109,6 +127,9 @@ object ReplaceWithAnnotationAnalyzer {
|
||||
if (target is ValueParameterDescriptor && target.getContainingDeclaration() == symbolDescriptor) {
|
||||
expression.putCopyableUserData(PARAMETER_USAGE_KEY, target.getName())
|
||||
}
|
||||
else if (target is TypeParameterDescriptor && target.getContainingDeclaration() == symbolDescriptor) {
|
||||
expression.putCopyableUserData(TYPE_PARAMETER_USAGE_KEY, target.getName())
|
||||
}
|
||||
|
||||
val resolvedCall = expression.getResolvedCall(bindingContext)
|
||||
if (resolvedCall != null && resolvedCall.getStatus().isSuccess()) {
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace with 'newFun()'" "true"
|
||||
package ppp
|
||||
|
||||
fun bar(): Int = 0
|
||||
|
||||
@deprecated("", ReplaceWith("newFun()"))
|
||||
fun oldFun(p: Int = ppp.bar()) {
|
||||
newFun()
|
||||
}
|
||||
|
||||
fun newFun(){}
|
||||
|
||||
fun foo() {
|
||||
<caret>oldFun()
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with 'newFun()'" "true"
|
||||
package ppp
|
||||
|
||||
fun bar(): Int = 0
|
||||
|
||||
@deprecated("", ReplaceWith("newFun()"))
|
||||
fun oldFun(p: Int = ppp.bar()) {
|
||||
newFun()
|
||||
}
|
||||
|
||||
fun newFun(){}
|
||||
|
||||
fun foo() {
|
||||
bar()
|
||||
<caret>newFun()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun <T> oldFun(vararg elements: T) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun <T> newFun(vararg elements: T){}
|
||||
|
||||
fun foo() {
|
||||
<caret>oldFun<String>()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun <T> oldFun(vararg elements: T) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun <T> newFun(vararg elements: T){}
|
||||
|
||||
fun foo() {
|
||||
newFun<String>()
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun<T>()'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun<T>()"))
|
||||
fun <T : Any> oldFun(): T? {
|
||||
return newFun<T>()
|
||||
}
|
||||
|
||||
fun <T : Any> newFun(): T? = null
|
||||
|
||||
fun foo(): String? {
|
||||
return <caret>oldFun()
|
||||
}
|
||||
idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/explicitInPatternImplicitInUsage.kt.after
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun<T>()'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun<T>()"))
|
||||
fun <T : Any> oldFun(): T? {
|
||||
return newFun<T>()
|
||||
}
|
||||
|
||||
fun <T : Any> newFun(): T? = null
|
||||
|
||||
fun foo(): String? {
|
||||
return newFun()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun<T>()'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun<T>()"))
|
||||
fun <T> oldFun() {
|
||||
newFun<T>()
|
||||
}
|
||||
|
||||
fun <T> newFun(){}
|
||||
|
||||
fun foo() {
|
||||
<caret>oldFun<String>()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun<T>()'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun<T>()"))
|
||||
fun <T> oldFun() {
|
||||
newFun<T>()
|
||||
}
|
||||
|
||||
fun <T> newFun(){}
|
||||
|
||||
fun foo() {
|
||||
newFun<String>()
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(p)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(p)"))
|
||||
fun oldFun(p: List<String>) {
|
||||
newFun(p)
|
||||
}
|
||||
|
||||
fun newFun(p: List<String>){}
|
||||
|
||||
fun foo() {
|
||||
<caret>oldFun(listOf<String>("a"))
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(p)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(p)"))
|
||||
fun oldFun(p: List<String>) {
|
||||
newFun(p)
|
||||
}
|
||||
|
||||
fun newFun(p: List<String>){}
|
||||
|
||||
fun foo() {
|
||||
<caret>newFun(listOf<String>("a"))
|
||||
}
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun <T> oldFun(vararg elements: T) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun <T> newFun(vararg elements: T){}
|
||||
|
||||
fun foo() {
|
||||
<caret>oldFun(bar())
|
||||
}
|
||||
|
||||
fun bar(): java.io.File? = null
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun <T> oldFun(vararg elements: T) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun <T> newFun(vararg elements: T){}
|
||||
|
||||
fun foo() {
|
||||
<caret>newFun(bar())
|
||||
}
|
||||
|
||||
fun bar(): java.io.File? = null
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun <T> oldFun(vararg elements: T) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun <T> newFun(vararg elements: T){}
|
||||
|
||||
fun foo() {
|
||||
<caret>oldFun("a")
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun <T> oldFun(vararg elements: T) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun <T> newFun(vararg elements: T){}
|
||||
|
||||
fun foo() {
|
||||
newFun("a")
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun oldFun(vararg elements: java.io.File?) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun newFun(vararg elements: java.io.File?){}
|
||||
|
||||
fun foo() {
|
||||
<caret>oldFun()
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'newFun(*elements)'" "true"
|
||||
|
||||
@deprecated("", ReplaceWith("newFun(*elements)"))
|
||||
fun oldFun(vararg elements: java.io.File?) {
|
||||
newFun(*elements)
|
||||
}
|
||||
|
||||
fun newFun(vararg elements: java.io.File?){}
|
||||
|
||||
fun foo() {
|
||||
<caret>newFun()
|
||||
}
|
||||
@@ -3126,6 +3126,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("complexExpressionNotUsedShortenRefsRuntime.kt")
|
||||
public void testComplexExpressionNotUsedShortenRefsRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/argumentSideEffects/complexExpressionNotUsedShortenRefsRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("complexExpressionUsedTwice.kt")
|
||||
public void testComplexExpressionUsedTwice() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/argumentSideEffects/complexExpressionUsedTwice.kt");
|
||||
@@ -3460,6 +3466,51 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TypeArguments extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInTypeArguments() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("emptyVarargRuntime.kt")
|
||||
public void testEmptyVarargRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/emptyVarargRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("explicitInPatternImplicitInUsage.kt")
|
||||
public void testExplicitInPatternImplicitInUsage() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/explicitInPatternImplicitInUsage.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("explicitTypeArg.kt")
|
||||
public void testExplicitTypeArg() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/explicitTypeArg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("keepInUserCodeRuntime.kt")
|
||||
public void testKeepInUserCodeRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/keepInUserCodeRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noImplicitTypeArgImportRuntime.kt")
|
||||
public void testNoImplicitTypeArgImportRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/noImplicitTypeArgImportRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nonEmptyVarargRuntime.kt")
|
||||
public void testNonEmptyVarargRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/nonEmptyVarargRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/vararg")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -3546,6 +3597,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noImportRuntime.kt")
|
||||
public void testNoImportRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/vararg/noImportRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("shortArrayRuntime.kt")
|
||||
public void testShortArrayRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/vararg/shortArrayRuntime.kt");
|
||||
|
||||
Reference in New Issue
Block a user