"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 -> {
|
||||
with((callableInfo as ClassWithPrimaryConstructorInfo).classInfo) {
|
||||
val classWithPrimaryConstructorInfo = callableInfo as ClassWithPrimaryConstructorInfo
|
||||
with(classWithPrimaryConstructorInfo.classInfo) {
|
||||
val classBody = when (kind) {
|
||||
ClassKind.ANNOTATION_CLASS, ClassKind.ENUM_ENTRY -> ""
|
||||
else -> "{\n\n}"
|
||||
@@ -551,8 +552,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
ClassKind.PLAIN_CLASS, ClassKind.INTERFACE -> "<>"
|
||||
else -> ""
|
||||
}
|
||||
val ctor =
|
||||
classWithPrimaryConstructorInfo.primaryConstructorVisibility?.name?.let { " $it constructor" } ?: ""
|
||||
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.util.ArrayUtil
|
||||
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.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassInfo
|
||||
@@ -215,7 +216,8 @@ class FunctionInfo(
|
||||
class ClassWithPrimaryConstructorInfo(
|
||||
val classInfo: ClassInfo,
|
||||
expectedTypeInfo: TypeInfo,
|
||||
modifierList: KtModifierList? = null
|
||||
modifierList: KtModifierList? = null,
|
||||
val primaryConstructorVisibility: Visibility? = null
|
||||
) : CallableInfo(
|
||||
classInfo.name,
|
||||
TypeInfo.Empty,
|
||||
|
||||
+14
-1
@@ -5,8 +5,11 @@
|
||||
|
||||
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.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.TypeInfo
|
||||
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 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(
|
||||
name = name,
|
||||
targetParents = filteredParents,
|
||||
expectedTypeInfo = expectedTypeInfo,
|
||||
inner = inner,
|
||||
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 org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix
|
||||
@@ -67,7 +68,8 @@ data class ClassInfo(
|
||||
val inner: Boolean = false,
|
||||
val open: Boolean = false,
|
||||
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 {
|
||||
targetParents.filter {
|
||||
@@ -221,7 +223,8 @@ open class CreateClassFromUsageFix<E : KtElement> protected constructor(
|
||||
val constructorInfo = ClassWithPrimaryConstructorInfo(
|
||||
classInfo,
|
||||
// Need for #KT-22137
|
||||
if (expectedTypeInfo.isUnit) TypeInfo.Empty else expectedTypeInfo
|
||||
if (expectedTypeInfo.isUnit) TypeInfo.Empty else expectedTypeInfo,
|
||||
primaryConstructorVisibility = classInfo.primaryConstructorVisibility
|
||||
)
|
||||
val builder = CallableBuilderConfiguration(
|
||||
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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testQuotedName() throws Exception {
|
||||
runTest("idea/testData/quickfix/createFromUsage/createClass/callExpression/quotedName.kt");
|
||||
|
||||
Reference in New Issue
Block a user