K2: implement generating open class for some delegation specifiers (for test DelegationSpecifier in K2CreateClassFromUsageTest) (part of KTIJ-28671 K2: CreateClassFromUsageFix)

GitOrigin-RevId: d74118f682e9b5bd118de32136f13bba91887f65
This commit is contained in:
Alexey Kudravtsev
2024-06-27 14:08:14 +02:00
committed by intellij-monorepo-bot
parent 0a0826a9e3
commit 3ddfc2f8b6
9 changed files with 24 additions and 13 deletions

View File

@@ -23,6 +23,7 @@ class CreateKotlinClassAction(
val kind: ClassKind,
private val applicableParents: List<PsiElement>,
val inner: Boolean,
val open: Boolean,
val name: String,
private val superClassName: String?,
private val paramList: String,
@@ -90,13 +91,13 @@ class CreateKotlinClassAction(
kind,
className,
applicableParents,
false,
open,
inner,
isInsideInnerOrLocalClass(targetParent), null
)
declaration.typeParameterList?.delete()
val editor = CreateKotlinCallablePsiEditor(file.project, callableInfo)
val anchor = element; //element.getParentOfType<KtClassOrObject>(false) ?: element
val anchor = element
val insertContainer: PsiElement = targetParent
editor.showEditor(declaration, anchor, false, targetParent, insertContainer)
}

View File

@@ -1,4 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
@@ -13,8 +14,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.types.*
import org.jetbrains.kotlin.idea.codeinsight.utils.isEnum
import org.jetbrains.kotlin.idea.codeinsight.utils.isInheritable
import org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage.CreateKotlinClassAction
import org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage.ExpectedKotlinType
import org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage.K2CreateFunctionFromUsageUtil.convertToClass
import org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage.K2CreateFunctionFromUsageUtil.getExpectedKotlinType
import org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage.K2CreateFunctionFromUsageUtil.resolveExpression
@@ -36,7 +35,7 @@ object K2CreateClassFromUsageBuilder {
var expectedType: ExpectedKotlinType?
var superClassName:String?
var paramList: String?
var returnTypeString: String = ""
var returnTypeString = ""
var superClass: KtClass?
analyze(refExpr) {
expectedType = refExpr.getExpectedKotlinType()
@@ -57,11 +56,13 @@ object K2CreateClassFromUsageBuilder {
}
else true
}
val open = isInsideExtendsList(refExpr)
CreateKotlinClassAction(
refExpr,
kind,
applicableParents,
false,
open,
refExpr.getReferencedName(),
superClassName,
paramList!!,
@@ -71,6 +72,15 @@ object K2CreateClassFromUsageBuilder {
}
}
private fun isInsideExtendsList(element: PsiElement): Boolean {
return element.findParentOfType<KtSuperTypeList>(strict = false) != null
}
private fun isInExtendsClauseOfAnnotationOrEnumOrInline(element: KtExpression): Boolean {
val superTypeList = element.findParentOfType<KtSuperTypeList>(strict = false) ?: return false
val ktClass = superTypeList.findParentOfType<KtClass>(strict = false) ?: return false
return ktClass.isAnnotation() || ktClass.isEnum() || ktClass.isInline()
}
private fun renderParamList(ktClass: KtClass?, isAny: Boolean): String {
if (ktClass == null || isAny) return ""
val prefix = if (ktClass.isAnnotation()) "val " else ""
@@ -137,6 +147,7 @@ object K2CreateClassFromUsageBuilder {
ClassKind.ENUM_ENTRY -> false
ClassKind.DEFAULT -> false
ClassKind.ENUM_CLASS -> !hasTypeArguments && !inTypeBound
ClassKind.PLAIN_CLASS -> !isInExtendsClauseOfAnnotationOrEnumOrInline(fullCallExpr) // annotation/enum/inline class can't extend a class
else -> true
}
}
@@ -225,5 +236,5 @@ object K2CreateClassFromUsageBuilder {
return type.convertToClass()?.isInheritable() == true
}
private fun KtType.containsStarProjections(): Boolean = this is KaNonErrorClassType && ownTypeArguments.any { it is org.jetbrains.kotlin.analysis.api.types.KaStarTypeProjection || it.type?.containsStarProjections() == true}
private fun KtType.containsStarProjections(): Boolean = this is KaNonErrorClassType && ownTypeArguments.any { it is KaStarTypeProjection || it.type?.containsStarProjections() == true}
}

View File

@@ -1,7 +1,6 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage
import K2CreateClassFromUsageBuilder
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KaFirDiagnostic

View File

@@ -1,7 +1,6 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.codeinsight.quickFixes.createFromUsage
import K2CreateClassFromUsageBuilder
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider
import com.intellij.psi.PsiReference

View File

@@ -1,7 +1,6 @@
// "Create class 'A'" "true"
package p
// TARGET_PARENT:
class Foo: <caret>A() {
}

View File

@@ -1,7 +1,6 @@
// "Create class 'A'" "true"
package p
// TARGET_PARENT:
class Foo: A() {
}

View File

@@ -1,7 +1,6 @@
// "Create interface 'A'" "true"
package p
// TARGET_PARENT:
class Foo: <caret>A {
}

View File

@@ -1,7 +1,6 @@
// "Create interface 'A'" "true"
package p
// TARGET_PARENT:
class Foo: A {
}