mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] k2 create actual for expect: enable tests and support secondary constructor delegation
KTIJ-32214 GitOrigin-RevId: 61a6d3fca03399055473c907c582d0c1c62d48dc
This commit is contained in:
committed by
intellij-monorepo-bot
parent
37b656741d
commit
2e8fa8e94a
+51
-37
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KaRendererAnn
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.base.contextReceivers.KaContextReceiversRenderer
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.base.contextReceivers.renderers.KaContextReceiverLabelRenderer
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.declarations.KaDeclarationRenderer
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.declarations.bodies.KaFunctionLikeBodyRenderer
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KaDeclarationRendererForSource
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.renderers.KaRendererKeywordFilter
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.renderers.KaRendererOtherModifiersProvider
|
||||
@@ -47,11 +48,11 @@ import org.jetbrains.kotlin.types.Variance
|
||||
import javax.swing.Icon
|
||||
|
||||
@ApiStatus.Internal
|
||||
data class KtClassMemberInfo internal constructor(
|
||||
data class KtClassMemberInfo(
|
||||
val symbolPointer: KaSymbolPointer<KaCallableSymbol>,
|
||||
@NlsSafe val memberText: String?,
|
||||
val memberText: @NlsSafe String?,
|
||||
val memberIcon: Icon?,
|
||||
@NlsContexts.Label val containingSymbolText: String?,
|
||||
val containingSymbolText: @NlsContexts.Label String?,
|
||||
val containingSymbolIcon: Icon?,
|
||||
val isProperty: Boolean,
|
||||
) {
|
||||
@@ -61,7 +62,7 @@ data class KtClassMemberInfo internal constructor(
|
||||
symbol: KaCallableSymbol,
|
||||
memberText: @NlsSafe String? = null,
|
||||
memberIcon: Icon? = null,
|
||||
@NlsContexts.Label containingSymbolText: String? = null,
|
||||
containingSymbolText: @NlsContexts.Label String? = null,
|
||||
containingSymbolIcon: Icon? = null,
|
||||
): KtClassMemberInfo = KtClassMemberInfo(
|
||||
symbolPointer = symbol.createPointer(),
|
||||
@@ -229,11 +230,24 @@ context(KaSession)
|
||||
private fun createRenderer(
|
||||
targetClass: KtClassOrObject?,
|
||||
mode: MemberGenerateMode,
|
||||
symbol: KaDeclarationSymbol
|
||||
topDeclarationSymbol: KaDeclarationSymbol
|
||||
): KaDeclarationRenderer {
|
||||
val containingKtFile = targetClass?.containingKtFile
|
||||
|
||||
val renderer = KaDeclarationRendererForSource.WITH_QUALIFIED_NAMES.with {
|
||||
functionLikeBodyRenderer = object : KaFunctionLikeBodyRenderer {
|
||||
override fun renderBody(
|
||||
analysisSession: KaSession,
|
||||
symbol: KaFunctionSymbol,
|
||||
printer: PrettyPrinter
|
||||
) {
|
||||
if (symbol is KaConstructorSymbol &&
|
||||
!symbol.isPrimary &&
|
||||
(symbol.containingSymbol as? KaClassSymbol)?.declaredMemberScope?.constructors?.any { it.isPrimary } == true) {
|
||||
printer.append(" : this()")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mode == MemberGenerateMode.OVERRIDE) {
|
||||
annotationRenderer = annotationRenderer.with {
|
||||
annotationFilter = KaRendererAnnotationsFilter { annotation, _ -> keepAnnotation(annotation, containingKtFile) }
|
||||
@@ -251,7 +265,7 @@ private fun createRenderer(
|
||||
}
|
||||
|
||||
if (mode != MemberGenerateMode.ACTUAL) {
|
||||
modalityProvider = modalityProvider.onlyIf { s -> s != symbol }
|
||||
modalityProvider = modalityProvider.onlyIf { s -> s != topDeclarationSymbol }
|
||||
}
|
||||
|
||||
valueParameterRenderer = object: KaValueParameterSymbolRenderer {
|
||||
@@ -284,13 +298,13 @@ private fun createRenderer(
|
||||
//copy from KaRendererOtherModifiersProvider.ALL with `actual` and `override` specifics
|
||||
override fun getOtherModifiers(
|
||||
analysisSession: KaSession,
|
||||
s: KaDeclarationSymbol
|
||||
symbol: KaDeclarationSymbol
|
||||
): List<KtModifierKeywordToken> = buildList {
|
||||
if (mode == MemberGenerateMode.OVERRIDE && containingSymbol?.isActual == true) {
|
||||
//include actual modifier explicitly when containing class has modifier
|
||||
fun shouldHaveActualModifier(): Boolean {
|
||||
if (s.isActual) return true
|
||||
val containingInterface = s.containingSymbol
|
||||
if (symbol.isActual) return true
|
||||
val containingInterface = symbol.containingSymbol
|
||||
return containingInterface is KaClassSymbol &&
|
||||
containingSymbol.getExpectsForActual().any { (it as? KaClassSymbol)?.isSubClassOf(containingInterface) == true }
|
||||
}
|
||||
@@ -299,54 +313,54 @@ private fun createRenderer(
|
||||
}
|
||||
}
|
||||
|
||||
if (s is KaNamedFunctionSymbol) {
|
||||
if (s.isExternal) add(KtTokens.EXTERNAL_KEYWORD)
|
||||
if (s.isOverride) add(KtTokens.OVERRIDE_KEYWORD)
|
||||
if (s.isInline) add(KtTokens.INLINE_KEYWORD)
|
||||
if (s.isInfix) add(KtTokens.INFIX_KEYWORD)
|
||||
if (s.isOperator) add(KtTokens.OPERATOR_KEYWORD)
|
||||
if (s.isSuspend) add(KtTokens.SUSPEND_KEYWORD)
|
||||
if (symbol is KaNamedFunctionSymbol) {
|
||||
if (symbol.isExternal) add(KtTokens.EXTERNAL_KEYWORD)
|
||||
if (symbol.isOverride) add(KtTokens.OVERRIDE_KEYWORD)
|
||||
if (symbol.isInline) add(KtTokens.INLINE_KEYWORD)
|
||||
if (symbol.isInfix) add(KtTokens.INFIX_KEYWORD)
|
||||
if (symbol.isOperator) add(KtTokens.OPERATOR_KEYWORD)
|
||||
if (symbol.isSuspend) add(KtTokens.SUSPEND_KEYWORD)
|
||||
}
|
||||
|
||||
if (s is KaPropertySymbol) {
|
||||
if (s.isOverride) add(KtTokens.OVERRIDE_KEYWORD)
|
||||
if (symbol is KaPropertySymbol) {
|
||||
if (symbol.isOverride) add(KtTokens.OVERRIDE_KEYWORD)
|
||||
}
|
||||
|
||||
if (s is KaValueParameterSymbol) {
|
||||
if (s.isVararg) add(KtTokens.VARARG_KEYWORD)
|
||||
if (s.isCrossinline) add(KtTokens.CROSSINLINE_KEYWORD)
|
||||
if (s.isNoinline) add(KtTokens.NOINLINE_KEYWORD)
|
||||
if (symbol is KaValueParameterSymbol) {
|
||||
if (symbol.isVararg) add(KtTokens.VARARG_KEYWORD)
|
||||
if (symbol.isCrossinline) add(KtTokens.CROSSINLINE_KEYWORD)
|
||||
if (symbol.isNoinline) add(KtTokens.NOINLINE_KEYWORD)
|
||||
}
|
||||
|
||||
if (s is KaKotlinPropertySymbol) {
|
||||
if (s.isConst) add(KtTokens.CONST_KEYWORD)
|
||||
if (s.isLateInit) add(KtTokens.LATEINIT_KEYWORD)
|
||||
if (symbol is KaKotlinPropertySymbol) {
|
||||
if (symbol.isConst) add(KtTokens.CONST_KEYWORD)
|
||||
if (symbol.isLateInit) add(KtTokens.LATEINIT_KEYWORD)
|
||||
}
|
||||
|
||||
if (s is KaNamedClassSymbol) {
|
||||
if (s.isExternal) add(KtTokens.EXTERNAL_KEYWORD)
|
||||
if (s.isInline) {
|
||||
if ((s.psi as? KtClassOrObject)?.modifierList?.hasValueModifier() == true) {
|
||||
if (symbol is KaNamedClassSymbol) {
|
||||
if (symbol.isExternal) add(KtTokens.EXTERNAL_KEYWORD)
|
||||
if (symbol.isInline) {
|
||||
if ((symbol.psi as? KtClassOrObject)?.modifierList?.hasValueModifier() == true) {
|
||||
add(KtTokens.VALUE_KEYWORD)
|
||||
} else {
|
||||
add(KtTokens.INLINE_KEYWORD)
|
||||
}
|
||||
}
|
||||
if (s.isData) add(KtTokens.DATA_KEYWORD)
|
||||
if (s.isFun) add(KtTokens.FUN_KEYWORD)
|
||||
if (s.isInner) add(KtTokens.INNER_KEYWORD)
|
||||
if (symbol.isData) add(KtTokens.DATA_KEYWORD)
|
||||
if (symbol.isFun) add(KtTokens.FUN_KEYWORD)
|
||||
if (symbol.isInner) add(KtTokens.INNER_KEYWORD)
|
||||
}
|
||||
|
||||
if (s is KaTypeParameterSymbol) {
|
||||
if (s.isReified) add(KtTokens.REIFIED_KEYWORD)
|
||||
when (s.variance) {
|
||||
if (symbol is KaTypeParameterSymbol) {
|
||||
if (symbol.isReified) add(KtTokens.REIFIED_KEYWORD)
|
||||
when (symbol.variance) {
|
||||
Variance.INVARIANT -> {}
|
||||
Variance.IN_VARIANCE -> add(KtTokens.IN_KEYWORD)
|
||||
Variance.OUT_VARIANCE -> add(KtTokens.OUT_KEYWORD)
|
||||
}
|
||||
}
|
||||
|
||||
if (s == symbol && mode == MemberGenerateMode.OVERRIDE) {
|
||||
if (symbol == topDeclarationSymbol && mode == MemberGenerateMode.OVERRIDE) {
|
||||
//include additional override modifier
|
||||
add(KtTokens.OVERRIDE_KEYWORD)
|
||||
}
|
||||
@@ -360,7 +374,7 @@ private fun createRenderer(
|
||||
}
|
||||
|
||||
@OptIn(KaExperimentalApi::class)
|
||||
inline fun KaDeclarationRenderer.Builder.withoutLabel() {
|
||||
fun KaDeclarationRenderer.Builder.withoutLabel() {
|
||||
contextReceiversRenderer = contextReceiversRenderer.with {
|
||||
contextReceiverLabelRenderer = WITHOUT_LABEL
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// My: to be implemented
|
||||
// DISABLE_ERRORS
|
||||
// IGNORE_K2
|
||||
|
||||
package my
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// My: to be implemented
|
||||
// DISABLE_ERRORS
|
||||
// IGNORE_K2
|
||||
|
||||
package my
|
||||
|
||||
import other.Another
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class <caret>Constructors(s: String) {
|
||||
constructor(i: Int)
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class <caret>Constructors(s: String) {
|
||||
expect class <selection><caret></selection>Constructors(s: String) {
|
||||
constructor(i: Int)
|
||||
}
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect interface <caret>I {
|
||||
fun f(p: Int = 1)
|
||||
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect interface I {
|
||||
expect interface <selection><caret></selection>I {
|
||||
fun f(p: Int = 1)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class <caret>C {
|
||||
fun f(p: Int = 1)
|
||||
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class C {
|
||||
expect class <selection><caret></selection>C {
|
||||
fun f(p: Int = 1)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class <caret>WithConstructor(s: String = "Hello")
|
||||
+3
-2
@@ -1,4 +1,5 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class <caret>WithConstructor(s: String = "Hello")
|
||||
expect class <selection><caret></selection>WithConstructor(s: String = "Hello")
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// IGNORE_K2
|
||||
|
||||
|
||||
expect sealed class CommonSealedClass()
|
||||
class SInheritor1 : CommonSealedClass()
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// IGNORE_K2
|
||||
|
||||
|
||||
expect sealed class CommonSealedClass()
|
||||
class SInheritor1 : CommonSealedClass()
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Add remaining branches" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: Expected class 'CommonSealedClass' has no actual declaration in module testModule_Common
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
|
||||
|
||||
expect sealed class CommonSealedClass()
|
||||
class SInheritor1 : CommonSealedClass()
|
||||
class SInheritor2 : CommonSealedClass()
|
||||
|
||||
fun hello(c: CommonSealedClass): Int = <selection><caret></selection>when(c) {
|
||||
is SInheritor1 -> TODO()
|
||||
is SInheritor2 -> TODO()
|
||||
}
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class <caret>WithPrimaryConstructor(x: Int, s: String)
|
||||
+3
-2
@@ -1,4 +1,5 @@
|
||||
// "Add missing actual declarations" "true"
|
||||
// IGNORE_K2
|
||||
// K2_ACTION: "Create actual in 'testModule_JVM'" "true"
|
||||
// K2_TOOL: org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinNoActualForExpectInspection
|
||||
|
||||
expect class WithPrimaryConstructor(x: Int, s: String)
|
||||
expect class <selection><caret></selection>WithPrimaryConstructor(x: Int, s: String)
|
||||
Reference in New Issue
Block a user