diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CallableUsageReplacementStrategy.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CallableUsageReplacementStrategy.kt index 4c5c18590c8..b15d6d333d4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CallableUsageReplacementStrategy.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CallableUsageReplacementStrategy.kt @@ -19,7 +19,10 @@ package org.jetbrains.kotlin.idea.codeInliner import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtOperationReferenceExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -36,12 +39,9 @@ class CallableUsageReplacementStrategy( val callElement = when (resolvedCall) { is VariableAsFunctionResolvedCall -> resolvedCall.variableCall.call.callElement else -> resolvedCall.call.callElement - } - if (callElement !is KtExpression && callElement !is KtAnnotationEntry) { - return null - } + if (!CodeInliner.canBeReplaced(callElement)) return null //TODO: precheck pattern correctness for annotation entry diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ClassUsageReplacementStrategy.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ClassUsageReplacementStrategy.kt index 9e1eb77c322..35be8099dd1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ClassUsageReplacementStrategy.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ClassUsageReplacementStrategy.kt @@ -28,7 +28,7 @@ import org.jetbrains.kotlin.idea.util.replaceOrCreateTypeArgumentList import org.jetbrains.kotlin.ir.expressions.typeParametersCount import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector class ClassUsageReplacementStrategy( typeReplacement: KtUserType?, @@ -65,7 +65,7 @@ class ClassUsageReplacementStrategy( } } - is KtCallExpression -> { + is KtCallElement -> { if (usage != parent.calleeExpression) return null when { constructorReplacementStrategy == null && typeReplacement != null -> return { @@ -90,7 +90,7 @@ class ClassUsageReplacementStrategy( } } - private fun replaceConstructorCallWithOtherTypeConstruction(callExpression: KtCallExpression): KtElement { + private fun replaceConstructorCallWithOtherTypeConstruction(callExpression: KtCallElement): KtElement { val referenceExpression = typeReplacement?.referenceExpression ?: error("Couldn't find referenceExpression") val classFromReplacement = KotlinClassShortNameIndex .getInstance()[referenceExpression.text, callExpression.project, callExpression.resolveScope] @@ -115,7 +115,7 @@ class ClassUsageReplacementStrategy( callExpression.calleeExpression?.replace(referenceExpression) - val expressionToReplace = callExpression.getQualifiedExpressionForSelectorOrThis() + val expressionToReplace = callExpression.getQualifiedExpressionForSelector() ?: callExpression val newExpression = if (typeReplacementQualifierAsExpression != null) factory.createExpressionByPattern("$0.$1", typeReplacementQualifierAsExpression, callExpression) else diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt index 07c3b9b645e..59b238e4e9f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt @@ -34,7 +34,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.utils.addIfNotNull -import java.util.* class CodeInliner( private val nameExpression: KtSimpleNameExpression, @@ -135,9 +134,14 @@ class CodeInliner( val replacementPerformer = when (elementToBeReplaced) { is KtExpression -> ExpressionReplacementPerformer(codeToInline, elementToBeReplaced) is KtAnnotationEntry -> AnnotationEntryReplacementPerformer(codeToInline, elementToBeReplaced) - else -> error("Unsupported element") + is KtSuperTypeCallEntry -> SuperTypeCallEntryReplacementPerformer(codeToInline, elementToBeReplaced) + else -> { + assert(!canBeReplaced(elementToBeReplaced)) + error("Unsupported element") + } } + assert(canBeReplaced(elementToBeReplaced)) return replacementPerformer.doIt(postProcessing = { range -> val newRange = postProcessInsertedCode(range, lexicalScope) if (!newRange.isEmpty) { @@ -207,7 +211,7 @@ class CodeInliner( val typeParameters = resolvedCall.resultingDescriptor.original.typeParameters val callElement = resolvedCall.call.callElement - val callExpression = callElement as? KtCallExpression + val callExpression = callElement as? KtCallElement val explicitTypeArgs = callExpression?.typeArgumentList?.arguments if (explicitTypeArgs != null && explicitTypeArgs.size != typeParameters.size) return @@ -498,7 +502,7 @@ class CodeInliner( // we drop only those arguments that added to the code from some parameter's default fun canDropArgument(argument: ValueArgument) = (argument as KtValueArgument)[DEFAULT_PARAMETER_VALUE_KEY] - result.forEachDescendantOfType { callExpression -> + result.forEachDescendantOfType { callExpression -> val resolvedCall = callExpression.getResolvedCall(newBindingContext) ?: return@forEachDescendantOfType argumentsToDrop.addAll(OptionalParametersHelper.detectArgumentsToDropForDefaults(resolvedCall, project, ::canDropArgument)) @@ -509,7 +513,7 @@ class CodeInliner( val argumentList = argument.parent as KtValueArgumentList argumentList.removeArgument(argument) if (argumentList.arguments.isEmpty()) { - val callExpression = argumentList.parent as KtCallExpression + val callExpression = argumentList.parent as KtCallElement if (callExpression.lambdaArguments.isNotEmpty()) { argumentList.delete() } @@ -547,9 +551,9 @@ class CodeInliner( if (argument.getSpreadElement() != null && !argument.isNamed()) { val argumentExpression = argument.getArgumentExpression() ?: return@forEachDescendantOfType val resolvedCall = argumentExpression.resolveToCall() ?: return@forEachDescendantOfType - val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return@forEachDescendantOfType + val callExpression = resolvedCall.call.callElement as? KtCallElement ?: return@forEachDescendantOfType if (CompileTimeConstantUtils.isArrayFunctionCall(resolvedCall)) { - argumentsToExpand.add(argument to callExpression.valueArguments) + argumentsToExpand.add(argument to callExpression.valueArgumentList?.arguments.orEmpty()) } } } @@ -619,5 +623,10 @@ class CodeInliner( // these keys are used on KtValueArgument private val MAKE_ARGUMENT_NAMED_KEY = Key("MAKE_ARGUMENT_NAMED") private val DEFAULT_PARAMETER_VALUE_KEY = Key("DEFAULT_PARAMETER_VALUE") + + fun canBeReplaced(element: KtElement): Boolean = when (element) { + is KtExpression, is KtAnnotationEntry, is KtSuperTypeCallEntry -> true + else -> false + } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt index ec0a21bc2af..a52c1793b71 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeToInlineBuilder.kt @@ -137,8 +137,8 @@ class CodeToInlineBuilder( bindingContext: BindingContext, analyze: () -> BindingContext ): BindingContext { - val typeArgsToAdd = ArrayList>() - codeToInline.forEachDescendantOfType { + val typeArgsToAdd = ArrayList>() + codeToInline.forEachDescendantOfType { if (InsertExplicitTypeArgumentsIntention.isApplicableTo(it, bindingContext)) { typeArgsToAdd.add(it to InsertExplicitTypeArgumentsIntention.createTypeArguments(it, bindingContext)!!) } diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt index 0bbf1c192c9..c7cb5fb6a1d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt @@ -88,7 +88,7 @@ internal class SuperTypeCallEntryReplacementPerformer( elementToBeReplaced: KtSuperTypeCallEntry ) : AbstractSimpleReplacementPerformer(codeToInline, elementToBeReplaced) { override fun createDummyElement(mainExpression: KtExpression): KtSuperTypeCallEntry { - val text = if (mainExpression is KtCallExpression && mainExpression.lambdaArguments.isNotEmpty()) { + val text = if (mainExpression is KtCallElement && mainExpression.lambdaArguments.isNotEmpty()) { callWithoutLambdaArguments(mainExpression) } else { mainExpression.text @@ -98,8 +98,8 @@ internal class SuperTypeCallEntryReplacementPerformer( } } -private fun callWithoutLambdaArguments(callExpression: KtCallExpression): String { - val copy = callExpression.copy() as KtCallExpression +private fun callWithoutLambdaArguments(callExpression: KtCallElement): String { + val copy = callExpression.copy() as KtCallElement val lambdaArgument = copy.lambdaArguments.first() val argumentExpression = lambdaArgument.getArgumentExpression() ?: return callExpression.text diff --git a/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt b/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt index 9a79561c4aa..20e9470e0e9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt +++ b/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -fun KtCallExpression.replaceOrCreateTypeArgumentList(newTypeArgumentList: KtTypeArgumentList) { +fun KtCallElement.replaceOrCreateTypeArgumentList(newTypeArgumentList: KtTypeArgumentList) { if (typeArgumentList != null) typeArgumentList?.replace(newTypeArgumentList) else addAfter( newTypeArgumentList, diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage5.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage5.kt new file mode 100644 index 00000000000..1a93a425a9e --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage5.kt @@ -0,0 +1,12 @@ +// "Replace with 'A(s = "", i = { i }, i2 = 33)'" "true" + +open class A(val s: String, val i: () -> Int, val i2: Int) { + @Deprecated("Replace with primary constructor", ReplaceWith("A(s = \"\", i = { i }, i2 = 33)")) + constructor(i: Int) : this("", { i }, i) +} + +class B : A(i = 42) + +fun a() { + A(42) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage5.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage5.kt.after new file mode 100644 index 00000000000..9c35f071d9e --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage5.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'A(s = "", i = { i }, i2 = 33)'" "true" + +open class A(val s: String, val i: () -> Int, val i2: Int) { + @Deprecated("Replace with primary constructor", ReplaceWith("A(s = \"\", i = { i }, i2 = 33)")) + constructor(i: Int) : this("", { i }, i) +} + +class B : A(s = "", i = { 42 }, i2 = 33) + +fun a() { + A(42) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage6.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage6.kt new file mode 100644 index 00000000000..df4c0f7b635 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage6.kt @@ -0,0 +1,15 @@ +// "Replace usages of 'constructor A(Int)' in whole project" "true" + +open class A(val s: String, val i: () -> Int, val i2: Int) { + @Deprecated("Replace with primary constructor", ReplaceWith("C(s = \"\", a = { i }, m = i)")) + constructor(i: Int) : this("", { i }, i) +} + +open class C(val m: Int, val s: String, a: () -> Int) + +class B : A(i = 31) + +fun b() { + val b = 30 + A(b) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage6.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage6.kt.after new file mode 100644 index 00000000000..5ee2a0fdb28 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage6.kt.after @@ -0,0 +1,15 @@ +// "Replace usages of 'constructor A(Int)' in whole project" "true" + +open class A(val s: String, val i: () -> Int, val i2: Int) { + @Deprecated("Replace with primary constructor", ReplaceWith("C(s = \"\", a = { i }, m = i)")) + constructor(i: Int) : this("", { i }, i) +} + +open class C(val m: Int, val s: String, a: () -> Int) + +class B : C(s = "", a = { 31 }, m = 31) + +fun b() { + val b = 30 + C(s = "", a = { b }, m = b) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage7.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage7.kt new file mode 100644 index 00000000000..50258656cdb --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage7.kt @@ -0,0 +1,12 @@ +// "Replace usages of 'constructor A(Int)' in whole project" "true" + +open class A(val b: String, val i: () -> Int) { + @Deprecated("Replace with primary constructor", ReplaceWith("A(b = \"\") { i }")) + constructor(i: Int) : this("", { i }) +} + +class B : A(i = 33) + +fun a() { + A(42) +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage7.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage7.kt.after new file mode 100644 index 00000000000..b88e0f883f2 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage7.kt.after @@ -0,0 +1,12 @@ +// "Replace usages of 'constructor A(Int)' in whole project" "true" + +open class A(val b: String, val i: () -> Int) { + @Deprecated("Replace with primary constructor", ReplaceWith("A(b = \"\") { i }")) + constructor(i: Int) : this("", { i }) +} + +class B : A(b = "", { 33 }) + +fun a() { + A(b = "") { 42 } +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/secondaryConstructor.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/secondaryConstructor.kt new file mode 100644 index 00000000000..d843bb1fe9a --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/secondaryConstructor.kt @@ -0,0 +1,10 @@ +// "class org.jetbrains.kotlin.idea.quickfix.replaceWith.DeprecatedSymbolUsageFix" "false" +abstract class NewClass(val i: () -> Int) + +@Deprecated("Text", ReplaceWith("NewClass({i})")) +abstract class OldClass(val i: Int) + +class F : OldClass { + constructor(i: Int) : super(i) + constructor(i: () -> Int) : super(i()) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.1.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.1.kt new file mode 100644 index 00000000000..6ddcff13c8c --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.1.kt @@ -0,0 +1,10 @@ +import newPack.NewClass + +class GF : NewClass({ 24 }) + +class CDw : NewClass({ 1111 }) + +fun foos() { + val b = 432 + NewClass({ b }) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.JavaClass.java b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.JavaClass.java new file mode 100644 index 00000000000..5baf4589551 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.JavaClass.java @@ -0,0 +1,8 @@ +import oldPack.OldClass; + +public class Hoos extends OldClass { + + public Hoos(int i) { + super(i); + } +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.NewDeclaration.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.NewDeclaration.kt new file mode 100644 index 00000000000..bba4e4b2d5c --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.NewDeclaration.kt @@ -0,0 +1,3 @@ +package newPack + +open class NewClass(val i: () -> Int) \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.OldDeclaration.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.OldDeclaration.kt new file mode 100644 index 00000000000..83f4d07c22d --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.OldDeclaration.kt @@ -0,0 +1,4 @@ +package pack + +@Deprecated("Replace with NewClass", ReplaceWith("NewClass({ i })", "newPack.NewClass")) +open class OldClass(val i: Int) \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.kt new file mode 100644 index 00000000000..4cf869cec31 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.after.kt @@ -0,0 +1,13 @@ +// "Replace usages of 'OldClass' in whole project" "true" + +import newPack.NewClass + +class B : NewClass({ 42 }) + +class C : NewClass({ 42 }) + +fun foo() { + val b = 42 + NewClass({ b }) +} + diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.1.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.1.kt new file mode 100644 index 00000000000..31cfedb8408 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.1.kt @@ -0,0 +1,10 @@ +import pack.OldClass + +class GF : OldClass(24) + +class CDw : OldClass(1111) + +fun foos() { + val b = 432 + OldClass(b) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.JavaClass.java b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.JavaClass.java new file mode 100644 index 00000000000..5baf4589551 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.JavaClass.java @@ -0,0 +1,8 @@ +import oldPack.OldClass; + +public class Hoos extends OldClass { + + public Hoos(int i) { + super(i); + } +} diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.Main.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.Main.kt new file mode 100644 index 00000000000..9ed4f2efa2a --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.Main.kt @@ -0,0 +1,13 @@ +// "Replace usages of 'OldClass' in whole project" "true" + +import pack.OldClass + +class B : OldClass(42) + +class C : OldClass(42) + +fun foo() { + val b = 42 + OldClass(b) +} + diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.NewDeclaration.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.NewDeclaration.kt new file mode 100644 index 00000000000..bba4e4b2d5c --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.NewDeclaration.kt @@ -0,0 +1,3 @@ +package newPack + +open class NewClass(val i: () -> Int) \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.OldDeclaration.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.OldDeclaration.kt new file mode 100644 index 00000000000..83f4d07c22d --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.OldDeclaration.kt @@ -0,0 +1,4 @@ +package pack + +@Deprecated("Replace with NewClass", ReplaceWith("NewClass({ i })", "newPack.NewClass")) +open class OldClass(val i: Int) \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classConstructor.kt b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classConstructor.kt new file mode 100644 index 00000000000..3908527450a --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classConstructor.kt @@ -0,0 +1,12 @@ +// "Replace with 'A({t})'" "true" + +open class A constructor(t: () -> T) { + @Deprecated("F", ReplaceWith("A({t})")) + constructor(t: T) : this({ t }) +} + +class B(t: TElement) : A(t) + +fun b() { + A(42) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classConstructor.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classConstructor.kt.after new file mode 100644 index 00000000000..8896983cde5 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classConstructor.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'A({t})'" "true" + +open class A constructor(t: () -> T) { + @Deprecated("F", ReplaceWith("A({t})")) + constructor(t: T) : this({ t }) +} + +class B(t: TElement) : A({ t }) + +fun b() { + A(42) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject/classConstructor.kt b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject/classConstructor.kt new file mode 100644 index 00000000000..f2ce2393b16 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject/classConstructor.kt @@ -0,0 +1,13 @@ +// "Replace usages of 'constructor A(T, T = ...)' in whole project" "true" +// ERROR: Unresolved reference: T + +open class A constructor(t: () -> T, f: () -> T = t) { + @Deprecated("F", ReplaceWith("A({t})")) + constructor(t: T, f: T = t) : this({ t }) +} + +class B(t: TElement) : A(t) + +fun b() { + A(42) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject/classConstructor.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject/classConstructor.kt.after new file mode 100644 index 00000000000..c01e089b59c --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject/classConstructor.kt.after @@ -0,0 +1,13 @@ +// "Replace usages of 'constructor A(T, T = ...)' in whole project" "true" +// ERROR: Unresolved reference: T + +open class A constructor(t: () -> T, f: () -> T = t) { + @Deprecated("F", ReplaceWith("A({t})")) + constructor(t: T, f: T = t) : this({ t }) +} + +class B(t: TElement) : A({ t }) + +fun b() { + A({ 42 }) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index 32f4be549bc..ed3a3361ba6 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -2583,6 +2583,11 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes public void testNoParenthesesAnnotation() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/noParenthesesAnnotation.before.Main.kt"); } + + @TestMetadata("superTypeCall.before.Main.kt") + public void testSuperTypeCall() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/wholeProject/superTypeCall.before.Main.kt"); + } } } @@ -2800,6 +2805,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes public void testPlatformType() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/platformType.before.Main.kt"); } + + @TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class WholeProject extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, this, testDataFilePath); + } + + public void testAllFilesPresentInWholeProject() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), null, true); + } + } } @TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/vararg") diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index f0a6af63fc9..6526a79a578 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -6467,6 +6467,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage4.kt"); } + @TestMetadata("constructorUsage5.kt") + public void testConstructorUsage5() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage5.kt"); + } + + @TestMetadata("constructorUsage6.kt") + public void testConstructorUsage6() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage6.kt"); + } + + @TestMetadata("constructorUsage7.kt") + public void testConstructorUsage7() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage7.kt"); + } + @TestMetadata("constructorUsageWithTypeArgument.kt") public void testConstructorUsageWithTypeArgument() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsageWithTypeArgument.kt"); @@ -6582,6 +6597,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/qualifiedClassNameInPattern.kt"); } + @TestMetadata("secondaryConstructor.kt") + public void testSecondaryConstructor() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/secondaryConstructor.kt"); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/simple.kt"); @@ -7076,6 +7096,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); } + @TestMetadata("classConstructor.kt") + public void testClassConstructor() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classConstructor.kt"); + } + @TestMetadata("classLiteral.kt") public void testClassLiteral() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/classLiteral.kt"); @@ -7135,6 +7160,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { public void testTypeReference() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/typeReference.kt"); } + + @TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class WholeProject extends AbstractQuickFixTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInWholeProject() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); + } + + @TestMetadata("classConstructor.kt") + public void testClassConstructor() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/wholeProject/classConstructor.kt"); + } + } } @TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage/vararg")