"Create class from usage": add visibility to primary constructor if needed
#KT-29844 Fixed
This commit is contained in:
committed by
igoriakovlev
parent
b1e8238ea2
commit
efa981db36
+5
-2
@@ -531,7 +531,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR -> {
|
CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR -> {
|
||||||
with((callableInfo as ClassWithPrimaryConstructorInfo).classInfo) {
|
val classWithPrimaryConstructorInfo = callableInfo as ClassWithPrimaryConstructorInfo
|
||||||
|
with(classWithPrimaryConstructorInfo.classInfo) {
|
||||||
val classBody = when (kind) {
|
val classBody = when (kind) {
|
||||||
ClassKind.ANNOTATION_CLASS, ClassKind.ENUM_ENTRY -> ""
|
ClassKind.ANNOTATION_CLASS, ClassKind.ENUM_ENTRY -> ""
|
||||||
else -> "{\n\n}"
|
else -> "{\n\n}"
|
||||||
@@ -551,8 +552,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
ClassKind.PLAIN_CLASS, ClassKind.INTERFACE -> "<>"
|
ClassKind.PLAIN_CLASS, ClassKind.INTERFACE -> "<>"
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
|
val ctor =
|
||||||
|
classWithPrimaryConstructorInfo.primaryConstructorVisibility?.name?.let { " $it constructor" } ?: ""
|
||||||
psiFactory.createDeclaration<KtClassOrObject>(
|
psiFactory.createDeclaration<KtClassOrObject>(
|
||||||
"$openMod$innerMod${kind.keyword} $safeName$typeParamList$paramList$returnTypeString $classBody"
|
"$openMod$innerMod${kind.keyword} $safeName$typeParamList$ctor$paramList$returnTypeString $classBody"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
|
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassInfo
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassInfo
|
||||||
@@ -215,7 +216,8 @@ class FunctionInfo(
|
|||||||
class ClassWithPrimaryConstructorInfo(
|
class ClassWithPrimaryConstructorInfo(
|
||||||
val classInfo: ClassInfo,
|
val classInfo: ClassInfo,
|
||||||
expectedTypeInfo: TypeInfo,
|
expectedTypeInfo: TypeInfo,
|
||||||
modifierList: KtModifierList? = null
|
modifierList: KtModifierList? = null,
|
||||||
|
val primaryConstructorVisibility: Visibility? = null
|
||||||
) : CallableInfo(
|
) : CallableInfo(
|
||||||
classInfo.name,
|
classInfo.name,
|
||||||
TypeInfo.Empty,
|
TypeInfo.Empty,
|
||||||
|
|||||||
+14
-1
@@ -5,8 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass
|
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
||||||
|
import org.jetbrains.kotlin.idea.intentions.getCallableDescriptor
|
||||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
|
||||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
|
||||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getTypeInfoForTypeArguments
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getTypeInfoForTypeArguments
|
||||||
@@ -88,13 +91,23 @@ object CreateClassFromConstructorCallActionFactory : CreateClassFromUsageFactory
|
|||||||
|
|
||||||
val typeArgumentInfos = if (inAnnotationEntry) Collections.emptyList() else callExpr.getTypeInfoForTypeArguments()
|
val typeArgumentInfos = if (inAnnotationEntry) Collections.emptyList() else callExpr.getTypeInfoForTypeArguments()
|
||||||
|
|
||||||
|
val argumentClassVisibilities = valueArguments.mapNotNull {
|
||||||
|
(it.getArgumentExpression()?.getCallableDescriptor() as? ClassConstructorDescriptor)?.containingDeclaration?.visibility
|
||||||
|
}
|
||||||
|
val primaryConstructorVisibility = when {
|
||||||
|
Visibilities.PRIVATE in argumentClassVisibilities -> Visibilities.PRIVATE
|
||||||
|
Visibilities.INTERNAL in argumentClassVisibilities -> Visibilities.INTERNAL
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
return ClassInfo(
|
return ClassInfo(
|
||||||
name = name,
|
name = name,
|
||||||
targetParents = filteredParents,
|
targetParents = filteredParents,
|
||||||
expectedTypeInfo = expectedTypeInfo,
|
expectedTypeInfo = expectedTypeInfo,
|
||||||
inner = inner,
|
inner = inner,
|
||||||
typeArguments = typeArgumentInfos,
|
typeArguments = typeArgumentInfos,
|
||||||
parameterInfos = parameterInfos
|
parameterInfos = parameterInfos,
|
||||||
|
primaryConstructorVisibility = primaryConstructorVisibility
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -16,6 +16,7 @@ import com.intellij.openapi.ui.DialogWrapper
|
|||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import org.jetbrains.annotations.Nls
|
import org.jetbrains.annotations.Nls
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix
|
import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix
|
||||||
@@ -67,7 +68,8 @@ data class ClassInfo(
|
|||||||
val inner: Boolean = false,
|
val inner: Boolean = false,
|
||||||
val open: Boolean = false,
|
val open: Boolean = false,
|
||||||
val typeArguments: List<TypeInfo> = Collections.emptyList(),
|
val typeArguments: List<TypeInfo> = Collections.emptyList(),
|
||||||
val parameterInfos: List<ParameterInfo> = Collections.emptyList()
|
val parameterInfos: List<ParameterInfo> = Collections.emptyList(),
|
||||||
|
val primaryConstructorVisibility: Visibility? = null
|
||||||
) {
|
) {
|
||||||
val applicableParents by lazy {
|
val applicableParents by lazy {
|
||||||
targetParents.filter {
|
targetParents.filter {
|
||||||
@@ -221,7 +223,8 @@ open class CreateClassFromUsageFix<E : KtElement> protected constructor(
|
|||||||
val constructorInfo = ClassWithPrimaryConstructorInfo(
|
val constructorInfo = ClassWithPrimaryConstructorInfo(
|
||||||
classInfo,
|
classInfo,
|
||||||
// Need for #KT-22137
|
// Need for #KT-22137
|
||||||
if (expectedTypeInfo.isUnit) TypeInfo.Empty else expectedTypeInfo
|
if (expectedTypeInfo.isUnit) TypeInfo.Empty else expectedTypeInfo,
|
||||||
|
primaryConstructorVisibility = classInfo.primaryConstructorVisibility
|
||||||
)
|
)
|
||||||
val builder = CallableBuilderConfiguration(
|
val builder = CallableBuilderConfiguration(
|
||||||
Collections.singletonList(constructorInfo),
|
Collections.singletonList(constructorInfo),
|
||||||
|
|||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create class 'Bar'" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
internal class Foo
|
||||||
|
|
||||||
|
val bar = <caret>Bar(Foo())
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create class 'Bar'" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
internal class Foo
|
||||||
|
|
||||||
|
val bar = Bar(Foo())
|
||||||
|
|
||||||
|
class Bar internal constructor(foo: Foo) {
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create class 'Bar'" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
private class Foo
|
||||||
|
|
||||||
|
val bar = <caret>Bar(Foo())
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create class 'Bar'" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
private class Foo
|
||||||
|
|
||||||
|
val bar = Bar(Foo())
|
||||||
|
|
||||||
|
class Bar private constructor(foo: Foo) {
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create class 'Bar'" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
class Foo
|
||||||
|
|
||||||
|
val bar = <caret>Bar(Foo())
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create class 'Bar'" "true"
|
||||||
|
// DISABLE-ERRORS
|
||||||
|
class Foo
|
||||||
|
|
||||||
|
val bar = Bar(Foo())
|
||||||
|
|
||||||
|
class Bar(foo: Foo) {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3294,6 +3294,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/notApplicableInReturn.kt");
|
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/notApplicableInReturn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parameterClassIsInternal.kt")
|
||||||
|
public void testParameterClassIsInternal() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/parameterClassIsInternal.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parameterClassIsPrivate.kt")
|
||||||
|
public void testParameterClassIsPrivate() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/parameterClassIsPrivate.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parameterClassIsPublic.kt")
|
||||||
|
public void testParameterClassIsPublic() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/parameterClassIsPublic.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("quotedName.kt")
|
@TestMetadata("quotedName.kt")
|
||||||
public void testQuotedName() throws Exception {
|
public void testQuotedName() throws Exception {
|
||||||
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/quotedName.kt");
|
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/quotedName.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user