diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt index 353b030f851..00c3c595960 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableMemberFromUsageFactory.kt @@ -21,9 +21,13 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionFactoryWithDelegate import org.jetbrains.kotlin.idea.quickfix.LowPriorityQuickFixWithDelegateFactory import org.jetbrains.kotlin.idea.quickfix.QuickFixWithDelegateFactory +import org.jetbrains.kotlin.idea.quickfix.createFromUsage.CreateFromUsageFixBase import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallableInfo +import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.PropertyInfo +import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateParameterFromUsageFix import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList +import java.util.* public abstract class CreateCallableMemberFromUsageFactory( val extensionsSupported: Boolean = true @@ -32,7 +36,7 @@ public abstract class CreateCallableMemberFromUsageFactory( originalElementPointer: SmartPsiElementPointer, lowPriority: Boolean, quickFixDataFactory: () -> List?, - quickFixFactory: (E, List) -> CreateCallableFromUsageFixBase + quickFixFactory: (E, List) -> CreateFromUsageFixBase? ): QuickFixWithDelegateFactory { val delegateFactory = { val data = quickFixDataFactory().orEmpty() @@ -52,14 +56,24 @@ public abstract class CreateCallableMemberFromUsageFactory( diagnostic: Diagnostic, quickFixDataFactory: () -> List? ): List { - val memberFix = newCallableQuickFix(originalElementPointer, false, quickFixDataFactory) { element, data -> - CreateCallableFromUsageFix(element, data) - } - if (!extensionsSupported) return listOf(memberFix) + val fixes = ArrayList(3) - val extensionFix = newCallableQuickFix(originalElementPointer, true, quickFixDataFactory) { element, data -> - CreateExtensionCallableFromUsageFix(element, data) + newCallableQuickFix(originalElementPointer, false, quickFixDataFactory) { element, data -> + CreateCallableFromUsageFix(element, data) + }.let { fixes.add(it) } + + newCallableQuickFix(originalElementPointer, false, quickFixDataFactory) f@ { element, data -> + (data.singleOrNull() as? PropertyInfo)?.let { + CreateParameterFromUsageFix.createFixForPrimaryConstructorPropertyParameter(element, it) + } + }.let { fixes.add(it) } + + if (extensionsSupported) { + newCallableQuickFix(originalElementPointer, true, quickFixDataFactory) { element, data -> + CreateExtensionCallableFromUsageFix(element, data) + }.let { fixes.add(it) } } - return listOf(memberFix, extensionFix) + + return fixes } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt index cd7dfb21f64..8be836eb0ff 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes import org.jetbrains.kotlin.descriptors.ConstructorDescriptor @@ -52,11 +51,8 @@ object CreateParameterByRefActionFactory : CreateParameterFromUsageFactory? { - val result = (diagnostic.psiFile as? KtFile)?.analyzeFullyAndGetResult() ?: return null + fun extractFixData(element: KtSimpleNameExpression): CreateParameterData? { + val result = (element.containingFile as? KtFile)?.analyzeFullyAndGetResult() ?: return null val context = result.bindingContext val moduleDescriptor = result.moduleDescriptor @@ -129,6 +125,8 @@ object CreateParameterByRefActionFactory : CreateParameterFromUsageFactory( +public open class CreateParameterFromUsageFix( val functionDescriptor: FunctionDescriptor, val parameterInfo: JetParameterInfo, val defaultValueContext: E ) : CreateFromUsageFixBase(defaultValueContext) { override fun getText(): String { - return JetBundle.message("create.parameter.from.usage", parameterInfo.name) + return with(parameterInfo) { + if (valOrVar != JetValVar.None) "Create property '$name' as constructor parameter" else "Create parameter '$name'" + } } override fun startInWriteAction() = false @@ -48,4 +58,46 @@ public class CreateParameterFromUsageFix( runChangeSignature(project, functionDescriptor, config, defaultValueContext, text) } -} + + companion object { + public fun createFixForPrimaryConstructorPropertyParameter( + element: E, + info: PropertyInfo + ) : CreateParameterFromUsageFix? { + val receiverClassDescriptor: ClassDescriptor + + val builder = CallableBuilderConfiguration(listOf(info), element, element.getContainingJetFile(), null, false).createBuilder() + val receiverTypeCandidate = builder.computeTypeCandidates(info.receiverTypeInfo).firstOrNull() + if (receiverTypeCandidate != null) { + builder.placement = CallablePlacement.WithReceiver(receiverTypeCandidate) + receiverClassDescriptor = receiverTypeCandidate.theType.constructor.declarationDescriptor as? ClassDescriptor ?: return null + } + else { + if (element !is KtSimpleNameExpression) return null + + val classOrObject = element.getStrictParentOfType() ?: return null + receiverClassDescriptor = classOrObject.resolveToDescriptorIfAny() as? ClassDescriptor ?: return null + + val paramInfo = CreateParameterByRefActionFactory.extractFixData(element)?.parameterInfo + if (paramInfo?.callableDescriptor == receiverClassDescriptor.unsubstitutedPrimaryConstructor) return null + } + + if (receiverClassDescriptor.kind != ClassKind.CLASS) return null + val receiverClass = receiverClassDescriptor.source.getPsi() as? KtClass ?: return null + if (!receiverClass.canRefactor()) return null + val constructorDescriptor = receiverClassDescriptor.unsubstitutedPrimaryConstructor ?: return null + + val paramType = info.returnTypeInfo.getPossibleTypes(builder).firstOrNull() ?: return null + if (paramType.hasTypeParametersToAdd(constructorDescriptor, builder.currentFileContext)) return null + + val paramInfo = JetParameterInfo( + callableDescriptor = constructorDescriptor, + name = info.name, + type = paramType, + valOrVar = if (info.writable) JetValVar.Var else JetValVar.Val + ) + + return CreateParameterFromUsageFix(constructorDescriptor, paramInfo, element) + } + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classWithReceiver.kt b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classWithReceiver.kt index 99c1bfbb9f2..5011b43dfa0 100644 --- a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classWithReceiver.kt +++ b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classWithReceiver.kt @@ -1,6 +1,7 @@ // "Create class 'A'" "false" // ACTION: Create extension property 'A' // ACTION: Create member property 'A' +// ACTION: Create property 'A' as constructor parameter // ERROR: Unresolved reference: A package p diff --git a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/enumEntryWithReceiver.kt b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/enumEntryWithReceiver.kt index 92934afc440..a48fdff85b0 100644 --- a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/enumEntryWithReceiver.kt +++ b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/enumEntryWithReceiver.kt @@ -1,6 +1,7 @@ // "Create enum constant 'A'" "false" // ACTION: Create extension property 'A' // ACTION: Create member property 'A' +// ACTION: Create property 'A' as constructor parameter // ERROR: Unresolved reference: A package p diff --git a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/objectWithReceiver.kt b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/objectWithReceiver.kt index e15ec758183..e95f812db4b 100644 --- a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/objectWithReceiver.kt +++ b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/objectWithReceiver.kt @@ -1,6 +1,7 @@ // "Create object 'A'" "false" // ACTION: Create extension property 'A' // ACTION: Create member property 'A' +// ACTION: Create property 'A' as constructor parameter // ERROR: Unresolved reference: A package p diff --git a/idea/testData/quickfix/createFromUsage/createVariable/localVariable/qualifiedInFun.kt b/idea/testData/quickfix/createFromUsage/createVariable/localVariable/qualifiedInFun.kt index 7f61eb2ed0b..838b89c9c90 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/localVariable/qualifiedInFun.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/localVariable/qualifiedInFun.kt @@ -1,6 +1,7 @@ // "Create local variable 'foo'" "false" // ACTION: Create extension property 'foo' // ACTION: Create member property 'foo' +// ACTION: Create property 'foo' as constructor parameter // ERROR: Unresolved reference: foo class A diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt index 867e7d0620a..75168522ba4 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A { fun test(n: Int) { diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt.after index 3508164c774..a87c4afb58b 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt.after +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/assignedInFunInClass.kt.after @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A(var foo: Int) { fun test(n: Int) { diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt index e90766c9a65..20a217fdbf9 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A { val test: Int get() { diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt.after index 8af7378905f..83a8e1df866 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt.after +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt.after @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A(val foo: Int) { val test: Int get() { diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt index 06901093425..20fc4862088 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A { val test: T get() { diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt.after index ee85e2962f9..a5c39d92cf1 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt.after +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInGenClass.kt.after @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A(val foo: T) { val test: T get() { diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt index 14505aa82c5..f22050f0d23 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A { val test: Int get() = foo diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt.after index c0cdd17b671..610b163cdec 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt.after +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorWithExpressionBodyInClass.kt.after @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" class A(val foo: Int) { val test: Int get() = foo diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt index 4e59e50c408..56749ffde4e 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" // ERROR: No value passed for parameter foo // ERROR: No value passed for parameter foo // ERROR: No value passed for parameter foo diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after index 840a21eeea3..86e9867c3db 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after @@ -1,4 +1,4 @@ -// "Create parameter 'foo'" "true" +// "Create property 'foo' as constructor parameter" "true" // ERROR: No value passed for parameter foo // ERROR: No value passed for parameter foo // ERROR: No value passed for parameter foo diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/qualifiedInFun.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/qualifiedInFun.kt index 084c6e96f35..71b4ba02f21 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/qualifiedInFun.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/qualifiedInFun.kt @@ -1,6 +1,7 @@ // "Create parameter 'foo'" "false" // ACTION: Create extension property 'foo' // ACTION: Create member property 'foo' +// ACTION: Create property 'foo' as constructor parameter // ERROR: Unresolved reference: foo class A diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt new file mode 100644 index 00000000000..89dbd9c73df --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt @@ -0,0 +1,11 @@ +// "Create property 'foo' as constructor parameter" "false" +// ACTION: Convert to expression body +// ACTION: Create parameter 'foo' +// ACTION: Create local variable 'foo' +// ERROR: Unresolved reference: foo + +fun test() { + fun nestedTest(): Int { + return foo + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberValNoReceiver.kt new file mode 100644 index 00000000000..be299e0fd2b --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberValNoReceiver.kt @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A { + class B { + fun test(): Int { + return foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberValNoReceiver.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberValNoReceiver.kt.after new file mode 100644 index 00000000000..47db8236997 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberValNoReceiver.kt.after @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A { + class B(val foo: Int) { + fun test(): Int { + return foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberVarNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberVarNoReceiver.kt new file mode 100644 index 00000000000..eca84fb40cd --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberVarNoReceiver.kt @@ -0,0 +1,10 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A { + class B { + fun test(): Int { + foo = 1 + return foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberVarNoReceiver.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberVarNoReceiver.kt.after new file mode 100644 index 00000000000..27fb7116032 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberVarNoReceiver.kt.after @@ -0,0 +1,10 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A { + class B(var foo: Int) { + fun test(): Int { + foo = 1 + return foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt new file mode 100644 index 00000000000..7130468dff8 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt @@ -0,0 +1,14 @@ +// "Create property 'foo' as constructor parameter" "false" +// ACTION: Convert to expression body +// ACTION: Create local variable 'foo' +// ACTION: Create parameter 'foo' +// ACTION: Create property 'foo' +// ERROR: Unresolved reference: foo + +class A { + object B { + fun test(): Int { + return foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/staticValOnJavaClass.before.Dependency.java b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/staticValOnJavaClass.before.Dependency.java new file mode 100644 index 00000000000..cfa2a621482 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/staticValOnJavaClass.before.Dependency.java @@ -0,0 +1,3 @@ +class J { + +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/staticValOnJavaClass.before.Main.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/staticValOnJavaClass.before.Main.kt new file mode 100644 index 00000000000..245406fc648 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/staticValOnJavaClass.before.Main.kt @@ -0,0 +1,8 @@ +// "Create member property 'foo' as constructor parameter" "false" +// ACTION: Create member property 'foo' +// ERROR: Unresolved reference: foo + +fun test() { + val a: Int = J.foo +} + diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInClass.kt new file mode 100644 index 00000000000..b48b4f3d4e6 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInClass.kt @@ -0,0 +1,7 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T) { + fun test(): A { + return this.foo + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInClass.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInClass.kt.after new file mode 100644 index 00000000000..a7160ed5550 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInClass.kt.after @@ -0,0 +1,7 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T, val foo: A) { + fun test(): A { + return this.foo + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInExtension.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInExtension.kt new file mode 100644 index 00000000000..185c2d67213 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInExtension.kt @@ -0,0 +1,7 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T) + +fun A.test(): A { + return this.foo +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInExtension.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInExtension.kt.after new file mode 100644 index 00000000000..21b64d96f1d --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInExtension.kt.after @@ -0,0 +1,7 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T, val foo: A) + +fun A.test(): A { + return this.foo +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass1.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass1.kt new file mode 100644 index 00000000000..3b6b332697e --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass1.kt @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T) { + inner class B(val m: U) { + fun test(): A { + return this.foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass1.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass1.kt.after new file mode 100644 index 00000000000..e2bf322a2db --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass1.kt.after @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T) { + inner class B(val m: U, val foo: A) { + fun test(): A { + return this.foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass2.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass2.kt new file mode 100644 index 00000000000..684c9622f00 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass2.kt @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T) { + inner class B(val m: U) { + fun test(): A { + return this@A.foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass2.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass2.kt.after new file mode 100644 index 00000000000..1518fc477eb --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass2.kt.after @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "true" + +class A(val n: T, val foo: A) { + inner class B(val m: U) { + fun test(): A { + return this@A.foo + } + } +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt new file mode 100644 index 00000000000..f634f28908f --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt @@ -0,0 +1,10 @@ +// "Create property 'foo' as constructor parameter" "false" +// ACTION: Create property 'foo' +// ACTION: Convert to expression body +// ACTION: Create local variable 'foo' +// ACTION: Create parameter 'foo' +// ERROR: Unresolved reference: foo + +fun test(): Int { + return foo +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnCompanionObject.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnCompanionObject.kt new file mode 100644 index 00000000000..3e8820e291a --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnCompanionObject.kt @@ -0,0 +1,14 @@ +// "Create member property 'foo' as constructor parameter" "false" +// ACTION: Create member property 'foo' +// ACTION: Create extension property 'foo' +// ERROR: Unresolved reference: foo + +class A(val n: T) { + companion object { + + } +} + +fun test() { + val a: Int = A.foo +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Dependency.java b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Dependency.java new file mode 100644 index 00000000000..1b4568a8f26 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Dependency.java @@ -0,0 +1,3 @@ +class A { + +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt new file mode 100644 index 00000000000..95f4584b0a8 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "false" +// ACTION: Create member property 'foo' +// ACTION: Convert to expression body +// ACTION: Create extension property 'foo' +// ERROR: Unresolved reference: foo + +fun test(): String? { + return A().foo +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnLibType.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnLibType.kt new file mode 100644 index 00000000000..b1b040ff90b --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnLibType.kt @@ -0,0 +1,9 @@ +// "Create property 'foo' as constructor parameter" "false" +// ACTION: Create extension property 'foo' +// ERROR: Unresolved reference: foo + +class A(val n: T) + +fun test() { + val a: A = 2.foo +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnUserType.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnUserType.kt new file mode 100644 index 00000000000..ad66759bb05 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnUserType.kt @@ -0,0 +1,8 @@ +// "Create property 'foo' as constructor parameter" "true" +// ERROR: No value passed for parameter foo + +class A(val n: T) + +fun test() { + val a: A = A(1).foo +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnUserType.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnUserType.kt.after new file mode 100644 index 00000000000..9c0cec55f3f --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnUserType.kt.after @@ -0,0 +1,8 @@ +// "Create property 'foo' as constructor parameter" "true" +// ERROR: No value passed for parameter foo + +class A(val n: T, val foo: A) + +fun test() { + val a: A = A(1, ).foo +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/varOnUserType.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/varOnUserType.kt new file mode 100644 index 00000000000..9592a5a7aed --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/varOnUserType.kt @@ -0,0 +1,8 @@ +// "Create property 'foo' as constructor parameter" "true" +// ERROR: No value passed for parameter foo + +class A(val n: T) + +fun test() { + A(1).foo = "1" +} diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/varOnUserType.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/varOnUserType.kt.after new file mode 100644 index 00000000000..920179e26b3 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/varOnUserType.kt.after @@ -0,0 +1,8 @@ +// "Create property 'foo' as constructor parameter" "true" +// ERROR: No value passed for parameter foo + +class A(val n: T, var foo: String) + +fun test() { + A(1, ).foo = "1" +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index e91634c49b6..dc36c88dc1a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -849,6 +849,27 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } } + @TestMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class PrimaryParameter extends AbstractQuickFixMultiFileTest { + public void testAllFilesPresentInPrimaryParameter() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter"), Pattern.compile("^(\\w+)\\.before\\.Main\\.\\w+$"), true); + } + + @TestMetadata("staticValOnJavaClass.before.Main.kt") + public void testStaticValOnJavaClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/staticValOnJavaClass.before.Main.kt"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("valOnJavaType.before.Main.kt") + public void testValOnJavaType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt"); + doTestWithExtraFile(fileName); + } + } + @TestMetadata("idea/testData/quickfix/createFromUsage/createVariable/property") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 6478bc2e812..a71ead9d6aa 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -2835,6 +2835,93 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class PrimaryParameter extends AbstractQuickFixTest { + public void testAllFilesPresentInPrimaryParameter() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("localValNoReceiver.kt") + public void testLocalValNoReceiver() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("memberValNoReceiver.kt") + public void testMemberValNoReceiver() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberValNoReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("memberVarNoReceiver.kt") + public void testMemberVarNoReceiver() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/memberVarNoReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("objectMemberValNoReceiver.kt") + public void testObjectMemberValNoReceiver() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("thisInClass.kt") + public void testThisInClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInClass.kt"); + doTest(fileName); + } + + @TestMetadata("thisInExtension.kt") + public void testThisInExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInExtension.kt"); + doTest(fileName); + } + + @TestMetadata("thisInNestedClass1.kt") + public void testThisInNestedClass1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass1.kt"); + doTest(fileName); + } + + @TestMetadata("thisInNestedClass2.kt") + public void testThisInNestedClass2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/thisInNestedClass2.kt"); + doTest(fileName); + } + + @TestMetadata("topLevelValNoReceiver.kt") + public void testTopLevelValNoReceiver() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("valOnCompanionObject.kt") + public void testValOnCompanionObject() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnCompanionObject.kt"); + doTest(fileName); + } + + @TestMetadata("valOnLibType.kt") + public void testValOnLibType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnLibType.kt"); + doTest(fileName); + } + + @TestMetadata("valOnUserType.kt") + public void testValOnUserType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnUserType.kt"); + doTest(fileName); + } + + @TestMetadata("varOnUserType.kt") + public void testVarOnUserType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/varOnUserType.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/createFromUsage/createVariable/property") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)