[FIR] Implement deprecation warning for synthetic without java base getter

Also implement new resolution behavior under language feature

^KT-63076 Fixed
^KT-64358
This commit is contained in:
Dmitriy Novozhilov
2023-12-15 17:08:53 +02:00
committed by Space Team
parent d5b0a5b220
commit fa33c5dc79
23 changed files with 384 additions and 35 deletions
@@ -5518,6 +5518,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirJvmErrors.SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN) { firDiagnostic ->
SyntheticPropertyWithoutJavaOriginImpl(
firSymbolBuilder.functionLikeBuilder.buildFunctionSymbol(firDiagnostic.a),
firDiagnostic.b,
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE) { firDiagnostic ->
ImplementingFunctionInterfaceImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -3839,6 +3839,12 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = NoReflectionInClassPath::class
}
interface SyntheticPropertyWithoutJavaOrigin : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = SyntheticPropertyWithoutJavaOrigin::class
val originalSymbol: KtFunctionLikeSymbol
val functionName: Name
}
interface ImplementingFunctionInterface : KtFirDiagnostic<KtClassOrObject> {
override val diagnosticClass get() = ImplementingFunctionInterface::class
}
@@ -4635,6 +4635,13 @@ internal class NoReflectionInClassPathImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.NoReflectionInClassPath
internal class SyntheticPropertyWithoutJavaOriginImpl(
override val originalSymbol: KtFunctionLikeSymbol,
override val functionName: Name,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.SyntheticPropertyWithoutJavaOrigin
internal class ImplementingFunctionInterfaceImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
@@ -22443,6 +22443,24 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlinGetter_mixedOrigin_2.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_k1Like.kt")
public void testSyntheticPropertyFromKotlin_k1Like() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_k1Like.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_warning.kt")
public void testSyntheticPropertyFromKotlin_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_warning.kt");
}
@Test
@TestMetadata("syntheticPropertyThroughJava.kt")
public void testSyntheticPropertyThroughJava() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyThroughJava.kt");
}
@Test
@TestMetadata("unitVsVoid.kt")
public void testUnitVsVoid() throws Exception {
@@ -22443,6 +22443,24 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlinGetter_mixedOrigin_2.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_k1Like.kt")
public void testSyntheticPropertyFromKotlin_k1Like() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_k1Like.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_warning.kt")
public void testSyntheticPropertyFromKotlin_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_warning.kt");
}
@Test
@TestMetadata("syntheticPropertyThroughJava.kt")
public void testSyntheticPropertyThroughJava() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyThroughJava.kt");
}
@Test
@TestMetadata("unitVsVoid.kt")
public void testUnitVsVoid() throws Exception {
@@ -22437,6 +22437,24 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlinGetter_mixedOrigin_2.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_k1Like.kt")
public void testSyntheticPropertyFromKotlin_k1Like() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_k1Like.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_warning.kt")
public void testSyntheticPropertyFromKotlin_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_warning.kt");
}
@Test
@TestMetadata("syntheticPropertyThroughJava.kt")
public void testSyntheticPropertyThroughJava() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyThroughJava.kt");
}
@Test
@TestMetadata("unitVsVoid.kt")
public void testUnitVsVoid() throws Exception {
@@ -22443,6 +22443,24 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlinGetter_mixedOrigin_2.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_k1Like.kt")
public void testSyntheticPropertyFromKotlin_k1Like() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_k1Like.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_warning.kt")
public void testSyntheticPropertyFromKotlin_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_warning.kt");
}
@Test
@TestMetadata("syntheticPropertyThroughJava.kt")
public void testSyntheticPropertyThroughJava() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyThroughJava.kt");
}
@Test
@TestMetadata("unitVsVoid.kt")
public void testUnitVsVoid() throws Exception {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticL
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -192,5 +193,9 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
)
val JAVA_SAM_INTERFACE_CONSTRUCTOR_REFERENCE by error<PsiElement>()
val NO_REFLECTION_IN_CLASS_PATH by warning<PsiElement>()
val SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN by warning<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
parameter<FirNamedFunctionSymbol>("originalSymbol")
parameter<Name>("functionName")
}
}
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -127,6 +128,7 @@ object FirJvmErrors {
val SPREAD_ON_SIGNATURE_POLYMORPHIC_CALL: KtDiagnosticFactoryForDeprecation0 by deprecationError0<PsiElement>(ProhibitSpreadOnSignaturePolymorphicCall, SourceElementPositioningStrategies.SPREAD_OPERATOR)
val JAVA_SAM_INTERFACE_CONSTRUCTOR_REFERENCE: KtDiagnosticFactory0 by error0<PsiElement>()
val NO_REFLECTION_IN_CLASS_PATH: KtDiagnosticFactory0 by warning0<PsiElement>()
val SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN: KtDiagnosticFactory2<FirNamedFunctionSymbol, Name> by warning2<PsiElement, FirNamedFunctionSymbol, Name>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
init {
RootDiagnosticRendererFactory.registerFactory(FirJvmErrorsDefaultMessages)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
import org.jetbrains.kotlin.diagnostics.KtDiagnosticRenderers.NOT_RENDERED
import org.jetbrains.kotlin.diagnostics.KtDiagnosticRenderers.TO_STRING
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.NAME
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
@@ -79,6 +80,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZ
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_ABSTRACT
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_SUSPEND
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS
@@ -296,5 +298,14 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
"Call uses reflection API which is not found in compilation classpath. " +
"Make sure you have kotlin-reflect.jar in the classpath."
)
map.put(
SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN,
"This synthetic property is based on the getter function ''{0}'' from Kotlin. " +
"In the future, synthetic properties will be available only if the base getter function came from Java. " +
"Consider replacing this property access with a ''{1}()'' function call.",
SYMBOL,
NAME
)
}
}
@@ -22,6 +22,11 @@ object JvmExpressionCheckers : ExpressionCheckers() {
FirQualifiedAccessJavaNullabilityWarningChecker,
)
override val propertyAccessExpressionCheckers: Set<FirPropertyAccessExpressionChecker>
get() = setOf(
FirSyntheticPropertyWithoutJavaOriginChecker,
)
override val callableReferenceAccessCheckers: Set<FirCallableReferenceAccessChecker>
get() = setOf(
FirUnsupportedSyntheticCallableReferenceChecker,
@@ -0,0 +1,39 @@
/*
* 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.fir.analysis.jvm.checkers.expression
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirPropertyAccessExpressionChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.noJavaOrigin
object FirSyntheticPropertyWithoutJavaOriginChecker : FirPropertyAccessExpressionChecker() {
override fun check(expression: FirPropertyAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ForbidSyntheticPropertiesWithoutBaseJavaGetter)) return
val syntheticProperty = expression.toResolvedCallableSymbol() as? FirSimpleSyntheticPropertySymbol ?: return
val containingAssignment = context.callsOrAssignments.getOrNull(context.callsOrAssignments.size - 2) as? FirVariableAssignment
val isAssignment = containingAssignment?.lValue === expression
val originalFunction = when (isAssignment) {
false -> syntheticProperty.getterSymbol?.delegateFunctionSymbol
true -> syntheticProperty.setterSymbol?.delegateFunctionSymbol
} ?: return
if (syntheticProperty.noJavaOrigin) {
reporter.reportOn(
expression.source,
FirJvmErrors.SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN,
originalFunction, originalFunction.name,
context
)
}
}
}
@@ -5,21 +5,19 @@
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.config.LanguageFeature.ForbidSyntheticPropertiesWithoutBaseJavaGetter
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope.SyntheticGetterCompatibility.*
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name
@@ -126,7 +124,8 @@ class FirSyntheticPropertiesScope private constructor(
if (getterReturnType?.isUnit == true && CompilerConeAttributes.EnhancedNullability !in getterReturnType.attributes) return
// Should have Java among overridden _and_ don't have isHiddenEverywhereBesideSuperCalls among them
if (!getterSymbol.mayBeUsedAsGetterForSyntheticProperty()) return
val getterCompatibility = getterSymbol.computeGetterCompatibility()
if (getterCompatibility == Incompatible) return
var matchingSetter: FirSimpleFunction? = null
if (needCheckForSetter && getterReturnType != null) {
@@ -144,12 +143,13 @@ class FirSyntheticPropertiesScope private constructor(
})
}
val property = buildSyntheticProperty(propertyName, getter, matchingSetter)
val property = buildSyntheticProperty(propertyName, getter, matchingSetter, getterCompatibility)
getter.originalForSubstitutionOverride?.let {
property.originalForSubstitutionOverrideAttr = buildSyntheticProperty(
propertyName,
it,
matchingSetter?.originalForSubstitutionOverride ?: matchingSetter
matchingSetter?.originalForSubstitutionOverride ?: matchingSetter,
getterCompatibility
)
}
val syntheticSymbol = property.symbol
@@ -161,7 +161,12 @@ class FirSyntheticPropertiesScope private constructor(
processor(syntheticSymbol)
}
private fun buildSyntheticProperty(propertyName: Name, getter: FirSimpleFunction, setter: FirSimpleFunction?): FirSyntheticProperty {
private fun buildSyntheticProperty(
propertyName: Name,
getter: FirSimpleFunction,
setter: FirSimpleFunction?,
getterCompatibility: SyntheticGetterCompatibility,
): FirSyntheticProperty {
val classLookupTag = getter.symbol.originalOrSelf().dispatchReceiverClassLookupTagOrNull()
val packageName = classLookupTag?.classId?.packageFqName ?: getter.symbol.callableId.packageName
val className = classLookupTag?.classId?.relativeClassName
@@ -176,6 +181,10 @@ class FirSyntheticPropertiesScope private constructor(
delegateGetter = getter
delegateSetter = setter
deprecationsProvider = getDeprecationsProviderFromAccessors(session, getter, setter)
}.apply {
if (getterCompatibility != HasJavaOrigin) {
noJavaOrigin = true
}
}
}
@@ -235,23 +244,62 @@ class FirSyntheticPropertiesScope private constructor(
|| processOverrides(getterSymbol, setterSymbolToCompare = setterSymbol)
}
private fun FirNamedFunctionSymbol.mayBeUsedAsGetterForSyntheticProperty(): Boolean {
var result = false
var isHiddenEverywhereBesideSuperCalls = false
baseScope.processOverriddenFunctionsAndSelf(this) {
val unwrapped = it.unwrapFakeOverrides().fir
if (unwrapped.origin == FirDeclarationOrigin.Enhancement) {
result = true
}
private enum class SyntheticGetterCompatibility {
Incompatible,
HasKotlinOrigin,
HasJavaOrigin
}
if (unwrapped.isHiddenEverywhereBesideSuperCalls == true) {
/**
* This method computes if getter method can be used as base for synthetic property based on overridden hierarchy
* There are three kinds of compatibility:
* - `Incompatible` (obvious)
* - `HasJavaOrigin` indicates that this getter is based on root java function (ok to create property)
* - `HasKotlinOrigin` shows that there is no base java getter overridden. Property will be created only with some LV (KT-64358)
*/
private fun FirNamedFunctionSymbol.computeGetterCompatibility(): SyntheticGetterCompatibility {
val kotlinBaseAllowed = !session.languageVersionSettings.supportsFeature(ForbidSyntheticPropertiesWithoutBaseJavaGetter)
var isHiddenEverywhereBesideSuperCalls = false
var result = Incompatible
val visited = mutableSetOf<MemberWithBaseScope<FirNamedFunctionSymbol>>()
fun checkJavaOrigin(symbol: FirNamedFunctionSymbol, scope: FirTypeScope) {
if (symbol.fir.isHiddenEverywhereBesideSuperCalls == true) {
isHiddenEverywhereBesideSuperCalls = true
}
ProcessorAction.NEXT
val overriddenWithScope = scope.getDirectOverriddenFunctionsWithBaseScope(symbol)
if (symbol.origin == FirDeclarationOrigin.Enhancement) {
/**
* If there is no overridden then we found java root and want to stick with it
* Otherwise we are in the middle of the hierarchy, so leaf potentially can be from Kotlin
*/
val potentialResult = when {
overriddenWithScope.isEmpty() -> HasJavaOrigin
kotlinBaseAllowed -> HasKotlinOrigin
else -> Incompatible
}
result = maxOf(result, potentialResult)
}
overriddenWithScope.forEach {
if (!visited.add(it)) return@forEach
checkJavaOrigin(it.member, it.baseScope)
}
}
checkJavaOrigin(this, baseScope)
return when {
isHiddenEverywhereBesideSuperCalls -> Incompatible
result != Incompatible -> result
!kotlinBaseAllowed -> Incompatible
// This branch is needed for compatibility reasons, see KT-64358
isJavaTypeOnThePath(this.dispatchReceiverType) -> HasKotlinOrigin
else -> Incompatible
}
result = result || isJavaTypeOnThePath(this.dispatchReceiverType)
return result && !isHiddenEverywhereBesideSuperCalls
}
/*
@@ -310,3 +358,10 @@ class FirSyntheticPropertiesScope private constructor(
}
}
}
private object NoJavaOriginKey : FirDeclarationDataKey()
private var FirSyntheticProperty.noJavaOrigin: Boolean? by FirDeclarationDataRegistry.data(NoJavaOriginKey)
val FirSimpleSyntheticPropertySymbol.noJavaOrigin: Boolean
get() = (fir as FirSyntheticProperty).noJavaOrigin == true
@@ -36,22 +36,22 @@ fun test_1(a: A) {
}
fun test_2(b: B) {
b.x1
b.x2
b.x3
b.x4
b.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x1<!>
b.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x2<!>
b.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x3<!>
b.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x4<!>
}
fun test_3(c: C) {
c.x1
c.x2
c.x3
c.x4
c.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x1<!>
c.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x2<!>
c.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x3<!>
c.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x4<!>
}
fun test_4(d: D) {
d.x1
d.x2
d.x3
d.x4
d.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x1<!>
d.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x2<!>
d.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x3<!>
d.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>x4<!>
}
@@ -0,0 +1,28 @@
// FIR_IDENTICAL
// LANGUAGE: +ForbidSyntheticPropertiesWithoutBaseJavaGetter
// FILE: Base.kt
open class Base {
fun getFoo(): String = ""
fun setFoo(value: String) {}
fun getBar(): String = ""
}
// FILE: Derived.java
public class Derived extends Base {
public void setBar(String value) {}
}
// FILE: main.kt
class Impl : Derived()
fun test_1(x: Impl) {
x.<!UNRESOLVED_REFERENCE!>foo<!>
x.<!UNRESOLVED_REFERENCE!>foo<!> = "a"
}
fun test_2(x: Impl) {
x.<!UNRESOLVED_REFERENCE!>bar<!>
x.<!UNRESOLVED_REFERENCE!>bar<!> = "a"
}
@@ -0,0 +1,27 @@
// LANGUAGE: -ForbidSyntheticPropertiesWithoutBaseJavaGetter
// FILE: Base.kt
open class Base {
fun getFoo(): String = ""
fun setFoo(value: String) {}
fun getBar(): String = ""
}
// FILE: Derived.java
public class Derived extends Base {
public void setBar(String value) {}
}
// FILE: main.kt
class Impl : Derived()
fun test_1(x: Impl) {
x.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN("fun getFoo(): String; getFoo")!>foo<!>
x.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN("fun setFoo(value: String): Unit; setFoo")!>foo<!> = "a"
}
fun test_2(x: Impl) {
x.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN("fun getBar(): String; getBar")!>bar<!>
x.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN("fun setBar(value: String!): Unit; setBar")!>bar<!> = "a"
}
@@ -0,0 +1,27 @@
// LANGUAGE: -ForbidSyntheticPropertiesWithoutBaseJavaGetter
// FILE: Base.kt
open class Base {
fun getFoo(): String = ""
fun setFoo(value: String) {}
fun getBar(): String = ""
}
// FILE: Derived.java
public class Derived extends Base {
public void setBar(String value) {}
}
// FILE: main.kt
class Impl : Derived()
fun test_1(x: Impl) {
x.<!UNRESOLVED_REFERENCE!>foo<!>
x.<!UNRESOLVED_REFERENCE!>foo<!> = "a"
}
fun test_2(x: Impl) {
x.<!UNRESOLVED_REFERENCE!>bar<!>
x.<!UNRESOLVED_REFERENCE!>bar<!> = "a"
}
@@ -0,0 +1,19 @@
// ISSUE: KT-59550
// FILE: Base.kt
abstract class Base(private val foo: String) {
fun getFoo(): String = foo
}
// FILE: Intermediate.java
public class Intermediate extends Base {
public Intermediate(String foo) {
super(foo);
}
}
// FILE: main.kt
class Final(val i: Intermediate) : Intermediate(i.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>foo<!>)
fun test(x: Final) {
x.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>foo<!>
}
@@ -0,0 +1,19 @@
// ISSUE: KT-59550
// FILE: Base.kt
abstract class Base(private val foo: String) {
fun getFoo(): String = foo
}
// FILE: Intermediate.java
public class Intermediate extends Base {
public Intermediate(String foo) {
super(foo);
}
}
// FILE: main.kt
class Final(val i: Intermediate) : Intermediate(i.foo)
fun test(x: Final) {
x.foo
}
@@ -14,7 +14,7 @@ fun foo(k: KotlinClass2) {
useInt(k.something2)
useInt(k.getSomethingKotlin1())
useInt(k.getSomethingKotlin2())
k.somethingKotlin1
k.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>somethingKotlin1<!>
k.<!UNRESOLVED_REFERENCE!>somethingKotlin2<!>
}
@@ -8,7 +8,7 @@ open class KotlinClass {
fun foo(javaClass: JavaClass) {
useInt(javaClass.getSomething1())
useInt(javaClass.something1)
useInt(javaClass.<!SYNTHETIC_PROPERTY_WITHOUT_JAVA_ORIGIN!>something1<!>)
javaClass.setSomething2(javaClass.getSomething2() + 1)
javaClass.something2 = javaClass.something2 + 1
@@ -22443,6 +22443,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlinGetter_mixedOrigin_2.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_k1Like.kt")
public void testSyntheticPropertyFromKotlin_k1Like() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_k1Like.kt");
}
@Test
@TestMetadata("syntheticPropertyFromKotlin_warning.kt")
public void testSyntheticPropertyFromKotlin_warning() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyFromKotlin_warning.kt");
}
@Test
@TestMetadata("syntheticPropertyThroughJava.kt")
public void testSyntheticPropertyThroughJava() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/syntheticPropertyThroughJava.kt");
}
@Test
@TestMetadata("unitVsVoid.kt")
public void testUnitVsVoid() throws Exception {
@@ -376,6 +376,7 @@ enum class LanguageFeature(
IntrinsicConstEvaluation(sinceVersion = null, kind = UNSTABLE_FEATURE), // KT-49303
DisableCheckingChangedProgressionsResolve(sinceVersion = null, kind = OTHER), // KT-49276
ContextSensitiveEnumResolutionInWhen(sinceVersion = null, kind = UNSTABLE_FEATURE), // KT-52774
ForbidSyntheticPropertiesWithoutBaseJavaGetter(sinceVersion = null, kind = OTHER), // KT-64358
;
init {