diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt index eb02b9da38f..039f34d9828 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt @@ -26,9 +26,11 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.light.classes.symbol.* import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase +import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForInterfaceDefaultImpls import org.jetbrains.kotlin.light.classes.symbol.modifierLists.GranularModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with +import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterForDefaultImplsReceiver import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightSetterParameter import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightTypeParameterList @@ -168,7 +170,7 @@ internal class SymbolLightAccessorMethod private constructor( val isStatic = if (suppressStatic) { false } else { - isTopLevel || isStatic() + isTopLevel || containingClass is SymbolLightClassForInterfaceDefaultImpls || isStatic() } mapOf(modifier to isStatic) @@ -299,7 +301,7 @@ internal class SymbolLightAccessorMethod private constructor( override fun hashCode(): Int = propertyAccessorDeclaration?.hashCode() ?: containingPropertyDeclaration.hashCode() private val _parametersList by lazyPub { - val parameterPopulator: (LightParameterListBuilder) -> Unit = if (!isGetter) { + val baseParameterPopulator: (LightParameterListBuilder) -> Unit = if (!isGetter) { { builder -> withAccessorSymbol { accessorSymbol -> val setterParameter = (accessorSymbol as? KtPropertySetterSymbol)?.parameter ?: return@withAccessorSymbol @@ -317,6 +319,13 @@ internal class SymbolLightAccessorMethod private constructor( { } } + val parameterPopulator: (LightParameterListBuilder) -> Unit = { builder -> + if (containingClass is SymbolLightClassForInterfaceDefaultImpls) { + builder.addParameter(SymbolLightParameterForDefaultImplsReceiver(this@SymbolLightAccessorMethod)) + } + baseParameterPopulator(builder) + } + SymbolLightParameterList( parent = this@SymbolLightAccessorMethod, callableWithReceiverSymbolPointer = containingPropertySymbolPointer, diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethod.kt index 97ed165ef5e..b899cdbfe12 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethod.kt @@ -5,9 +5,7 @@ package org.jetbrains.kotlin.light.classes.symbol.methods -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiIdentifier -import com.intellij.psi.PsiParameterList +import com.intellij.psi.* import com.intellij.psi.impl.light.LightReferenceListBuilder import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol @@ -21,10 +19,12 @@ import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier import org.jetbrains.kotlin.light.classes.symbol.annotations.computeThrowsList import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase +import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForInterfaceDefaultImpls import org.jetbrains.kotlin.light.classes.symbol.compareSymbolPointers import org.jetbrains.kotlin.light.classes.symbol.isOriginEquivalentTo import org.jetbrains.kotlin.light.classes.symbol.isValid import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameter +import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterForDefaultImplsReceiver import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightSuspendContinuationParameter import org.jetbrains.kotlin.light.classes.symbol.withSymbol @@ -81,6 +81,10 @@ internal abstract class SymbolLightMethod private parent = this@SymbolLightMethod, callableWithReceiverSymbolPointer = functionSymbolPointer, ) { builder -> + if (this@SymbolLightMethod.containingClass is SymbolLightClassForInterfaceDefaultImpls) { + builder.addParameter(SymbolLightParameterForDefaultImplsReceiver(this@SymbolLightMethod)) + } + withFunctionSymbol { functionSymbol -> functionSymbol.valueParameters.mapIndexed { index, parameter -> val needToSkip = argumentsSkipMask?.get(index) == true diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt index d0931a70c03..9efbbaed4dc 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightSimpleMethod.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.light.classes.symbol.* import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase +import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForInterfaceDefaultImpls import org.jetbrains.kotlin.light.classes.symbol.modifierLists.GranularModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with @@ -77,10 +78,10 @@ internal class SymbolLightSimpleMethod( private fun computeModifiers(modifier: String): Map? = when (modifier) { in GranularModifiersBox.MODALITY_MODIFIERS -> { ifInlineOnly { return modifiersForInlineOnlyCase() } - val modality = if (isTopLevel) { - PsiModifier.FINAL - } else { - withFunctionSymbol { functionSymbol -> + val modality = when { + isTopLevel -> PsiModifier.FINAL + containingClass is SymbolLightClassForInterfaceDefaultImpls -> null + else -> withFunctionSymbol { functionSymbol -> functionSymbol.computeSimpleModality()?.takeUnless { it.isSuppressedFinalModifier(containingClass, functionSymbol) } } } @@ -98,7 +99,9 @@ internal class SymbolLightSimpleMethod( val isStatic = if (suppressStatic) { false } else { - isTopLevel || withFunctionSymbol { it.isStatic || it.hasJvmStaticAnnotation() } + isTopLevel + || containingClass is SymbolLightClassForInterfaceDefaultImpls + || withFunctionSymbol { it.isStatic || it.hasJvmStaticAnnotation() } } mapOf(modifier to isStatic) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameterForDefaultImplsReceiver.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameterForDefaultImplsReceiver.kt new file mode 100644 index 00000000000..1405c0e71bd --- /dev/null +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightParameterForDefaultImplsReceiver.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.light.classes.symbol.parameters + +import com.intellij.psi.PsiIdentifier +import com.intellij.psi.PsiModifierList +import com.intellij.psi.PsiType +import org.jetbrains.annotations.NotNull +import org.jetbrains.kotlin.asJava.classes.lazyPub +import org.jetbrains.kotlin.light.classes.symbol.annotations.ComputeAllAtOnceAnnotationsBox +import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightSimpleAnnotation +import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForInterface +import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase +import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList +import org.jetbrains.kotlin.light.classes.symbol.nonExistentType +import org.jetbrains.kotlin.psi.KtParameter + +internal class SymbolLightParameterForDefaultImplsReceiver(containingDeclaration: SymbolLightMethodBase) : + SymbolLightParameterBase(containingDeclaration) { + private val _type by lazyPub { + (method.containingClass.containingClass as SymbolLightClassForInterface).withClassOrObjectSymbol { + it.buildSelfClassType().asPsiType(containingDeclaration, allowErrorTypes = true) ?: nonExistentType() + } + } + + override fun getNameIdentifier(): PsiIdentifier? = null + + override fun getName(): String = "\$this" + + override fun getType(): PsiType = _type + + override fun equals(other: Any?): Boolean = + other === this || other is SymbolLightParameterForDefaultImplsReceiver && other.parent == parent + + override fun hashCode(): Int = parent.hashCode() + + override fun isVarArgs(): Boolean = false + + private val _modifierList: PsiModifierList by lazyPub { + SymbolLightClassModifierList( + this, + annotationsBox = ComputeAllAtOnceAnnotationsBox { modifierList -> + listOf(SymbolLightSimpleAnnotation(NotNull::class.java.name, modifierList)) + }) + } + + override fun getModifierList(): PsiModifierList = _modifierList + + override fun hasModifierProperty(name: String): Boolean = false + + override val kotlinOrigin: KtParameter? + get() = null +} \ No newline at end of file diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.descriptors.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.descriptors.java new file mode 100644 index 00000000000..7a59a8a2b34 --- /dev/null +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.descriptors.java @@ -0,0 +1,37 @@ +public abstract interface C /* p.C*/ extends p.B { + @org.jetbrains.annotations.NotNull() + public abstract java.lang.String c();// c() + + @org.jetbrains.annotations.NotNull() + public abstract java.lang.String more();// more() + + public abstract int getProp3();// getProp3() + + public abstract void setProp3(int);// setProp3(int) + + public static final class DefaultImpls /* p.C.DefaultImpls*/ { + @org.jetbrains.annotations.NotNull() + public static java.lang.String a(@org.jetbrains.annotations.NotNull() p.C);// a(p.C) + + @org.jetbrains.annotations.NotNull() + public static java.lang.String b(@org.jetbrains.annotations.NotNull() p.C);// b(p.C) + + @org.jetbrains.annotations.NotNull() + public static java.lang.String c(@org.jetbrains.annotations.NotNull() p.C);// c(p.C) + + @p.Anno() + public static void setProp1(@org.jetbrains.annotations.NotNull() p.C, int);// setProp1(p.C, int) + + @p.Anno() + public static void setProp2(@org.jetbrains.annotations.NotNull() p.C, int);// setProp2(p.C, int) + + @p.Anno() + public static void setProp3(@org.jetbrains.annotations.NotNull() p.C, int);// setProp3(p.C, int) + + public static int getProp1(@org.jetbrains.annotations.NotNull() p.C);// getProp1(p.C) + + public static int getProp2(@org.jetbrains.annotations.NotNull() p.C);// getProp2(p.C) + + public static int getProp3(@org.jetbrains.annotations.NotNull() p.C);// getProp3(p.C) + } +} \ No newline at end of file diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.fir.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.fir.java index 2755c22079c..6043df98a49 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.fir.java +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.fir.java @@ -1,12 +1,28 @@ -public abstract interface C /* p.C*/ extends p.B { +public abstract interface C /* p.C*/ extends p.B { + @java.lang.Deprecated() + @p.Anno() + public static void getProp3$annotations();// getProp3$annotations() + @org.jetbrains.annotations.NotNull() public abstract java.lang.String c();// c() @org.jetbrains.annotations.NotNull() public abstract java.lang.String more();// more() + public abstract int getProp3();// getProp3() + + public abstract void setProp3(int);// setProp3(int) + public static final class DefaultImpls /* p.C.DefaultImpls*/ { + @java.lang.Deprecated() + @p.Anno() + public static void getProp3$annotations();// getProp3$annotations() + @org.jetbrains.annotations.NotNull() - public java.lang.String c();// c() + public static java.lang.String c(@org.jetbrains.annotations.NotNull() p.C);// c(p.C) + + public static int getProp3(@org.jetbrains.annotations.NotNull() p.C);// getProp3(p.C) + + public static void setProp3(@org.jetbrains.annotations.NotNull() p.C, int);// setProp3(p.C, int) } } diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.java index d4c3e72a1ee..fbdc0e91828 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.java +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.java @@ -1,18 +1,34 @@ -public abstract interface C /* p.C*/ extends p.B { +public abstract interface C /* p.C*/ extends p.B { @org.jetbrains.annotations.NotNull() public abstract java.lang.String c();// c() @org.jetbrains.annotations.NotNull() public abstract java.lang.String more();// more() + public abstract int getProp3();// getProp3() + + public abstract void setProp3(int);// setProp3(int) + public static final class DefaultImpls /* p.C.DefaultImpls*/ { @org.jetbrains.annotations.NotNull() - public static java.lang.String a(@org.jetbrains.annotations.NotNull() p.C);// a(p.C) + public static java.lang.String a(@org.jetbrains.annotations.NotNull() p.C);// a(p.C) @org.jetbrains.annotations.NotNull() - public static java.lang.String b(@org.jetbrains.annotations.NotNull() p.C);// b(p.C) + public static java.lang.String b(@org.jetbrains.annotations.NotNull() p.C);// b(p.C) @org.jetbrains.annotations.NotNull() - public static java.lang.String c(@org.jetbrains.annotations.NotNull() p.C);// c(p.C) + public static java.lang.String c(@org.jetbrains.annotations.NotNull() p.C);// c(p.C) + + public static int getProp1(@org.jetbrains.annotations.NotNull() p.C);// getProp1(p.C) + + public static int getProp2(@org.jetbrains.annotations.NotNull() p.C);// getProp2(p.C) + + public static int getProp3(@org.jetbrains.annotations.NotNull() p.C);// getProp3(p.C) + + public static void setProp1(@org.jetbrains.annotations.NotNull() p.C, int);// setProp1(p.C, int) + + public static void setProp2(@org.jetbrains.annotations.NotNull() p.C, int);// setProp2(p.C, int) + + public static void setProp3(@org.jetbrains.annotations.NotNull() p.C, int);// setProp3(p.C, int) } } diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.kt b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.kt index 82fae01cf94..bee9870780a 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.kt +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/ExtendingInterfaceWithDefaultImpls.kt @@ -1,16 +1,34 @@ // p.C +// !GENERATE_PROPERTY_ANNOTATIONS_METHODS package p +annotation class Anno + interface A { + @Anno + var prop1: Int + get() = 0 + set(value) {} + fun a() = "a" } interface B: A { + @Anno + var prop2: Int + get() = 0 + set(value) {} + fun b() = "b" } -interface C : B { +interface C : B { fun c() = "c" + @Anno + var prop3: Int + get() = 0 + set(value) {} + fun more(): String } diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/PrivateInTrait.fir.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/PrivateInTrait.fir.java index c126aa13469..be610017bec 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/PrivateInTrait.fir.java +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/PrivateInTrait.fir.java @@ -6,10 +6,10 @@ public abstract interface PrivateInTrait /* PrivateInTrait*/ { private abstract void setNn(java.lang.String);// setNn(java.lang.String) public static final class DefaultImpls /* PrivateInTrait.DefaultImpls*/ { - private final java.lang.String getN();// getN() + private static final java.lang.String getN(@org.jetbrains.annotations.NotNull() PrivateInTrait);// getN(PrivateInTrait) - private final java.lang.String getNn();// getNn() + private static final java.lang.String getNn(@org.jetbrains.annotations.NotNull() PrivateInTrait);// getNn(PrivateInTrait) - private final void setNn(java.lang.String);// setNn(java.lang.String) + private static final void setNn(@org.jetbrains.annotations.NotNull() PrivateInTrait, java.lang.String);// setNn(PrivateInTrait, java.lang.String) } }