Shift ReferencesToSyntheticJavaProperties feature release from 1.9 to 2.1

Other related tests:
- testGenericJavaProperty
- testFunInterfaceConstructorReference

Meta issue: KT-8575
Review: https://jetbrains.team/p/kt/reviews/9595

UnsupportedSyntheticCallableReferenceChecker only existed for K1,
because we wanted to release the feature for 1.9 and the feature should
have been working for K2 unconditionally. But since, we're postponing
the release until 2.1, we also need to port the checker from K1 to K2
This commit is contained in:
Nikita Bobko
2023-04-13 14:36:39 +02:00
committed by Space Team
parent 521a272acb
commit 5a96754aec
13 changed files with 63 additions and 44 deletions
@@ -51,15 +51,15 @@ abstract class AbstractSymbolLightClassesEqualityTestBase(
assertions: AssertionsService,
): PsiElementVisitor = object : JavaElementVisitor() {
override fun visitClass(aClass: PsiClass) {
compareArrayElementsWithInvalidation(aClass, PsiClass::methods)
compareArrayElementsWithInvalidation(aClass, PsiClass::fields)
compareArrayElementsWithInvalidation(aClass, PsiClass::innerClasses)
compareArrayElementsWithInvalidation(aClass, PsiClass::getMethods)
compareArrayElementsWithInvalidation(aClass, PsiClass::getFields)
compareArrayElementsWithInvalidation(aClass, PsiClass::getInnerClasses)
super.visitClass(aClass)
}
override fun visitEnumConstant(enumConstant: PsiEnumConstant) {
compareElementsWithInvalidation(enumConstant, PsiEnumConstant::initializingClass)
compareElementsWithInvalidation(enumConstant, PsiEnumConstant::getInitializingClass)
super.visitEnumConstant(enumConstant)
}
@@ -1,4 +1,5 @@
// ISSUE: KT-56243
// !LANGUAGE: +ReferencesToSyntheticJavaProperties
// FILE: JavaInv.java
public class JavaInv<T> {
@@ -23,6 +23,7 @@ object JvmExpressionCheckers : ExpressionCheckers() {
override val callableReferenceAccessCheckers: Set<FirCallableReferenceAccessChecker>
get() = setOf(
FirJavaShadowedFieldReferenceChecker,
FirUnsupportedSyntheticCallableReferenceChecker,
)
override val functionCallCheckers: Set<FirFunctionCallChecker>
@@ -0,0 +1,45 @@
/*
* 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.FirExpressionChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableReference
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
/**
* This is K2 implementation.
* For K1 implementation see: [org.jetbrains.kotlin.resolve.jvm.checkers.UnsupportedSyntheticCallableReferenceChecker]
*/
object FirUnsupportedSyntheticCallableReferenceChecker : FirExpressionChecker<FirCallableReferenceAccess>() {
override fun check(expression: FirCallableReferenceAccess, context: CheckerContext, reporter: DiagnosticReporter) {
val parent = context.containingElements.let {
check(it.last() === expression)
it[it.lastIndex - 1]
}
// We allow resolution of top-level callable references to synthetic Java extension properties in the delegate position. See KT-47299
if (parent is FirProperty && parent.delegate === expression) return
if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.ReferencesToSyntheticJavaProperties) &&
expression.toResolvedCallableReference()?.resolvedSymbol is FirSyntheticPropertySymbol
) {
reporter.reportOn(
expression.calleeReference.source,
FirErrors.UNSUPPORTED_FEATURE,
LanguageFeature.ReferencesToSyntheticJavaProperties to context.session.languageVersionSettings,
context
)
}
}
}
@@ -27,12 +27,16 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.util.extractCallableReferenceExpression
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
/**
* This is K1 implementation.
* For K2 implementation see: [org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirUnsupportedSyntheticCallableReferenceChecker]
*/
class UnsupportedSyntheticCallableReferenceChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
// TODO: support references to synthetic Java extension properties (KT-8575)
val callableReferenceExpression = resolvedCall.call.extractCallableReferenceExpression() ?: return
// We allow resolve of top-level callable reference to synthetic Java extension properties in delegate position
// We allow resolution of top-level callable references to synthetic Java extension properties in the delegate position. See KT-47299
if (callableReferenceExpression.unwrapParenthesesLabelsAndAnnotationsDeeply() is KtPropertyDelegate) return
if (resolvedCall.resultingDescriptor is SyntheticJavaPropertyDescriptor) {
@@ -1,4 +1,5 @@
// TARGET_BACKEND: JVM
// !LANGUAGE: +ReferencesToSyntheticJavaProperties
// FILE: J.java
@@ -1,4 +1,5 @@
// TARGET_BACKEND: JVM
// !LANGUAGE: +ReferencesToSyntheticJavaProperties
// FILE: SuperClass.java
public class SuperClass {
@@ -1,4 +1,5 @@
// TARGET_BACKEND: JVM
// !LANGUAGE: +ReferencesToSyntheticJavaProperties
// WITH_STDLIB
// FILE: J.java
@@ -1,21 +0,0 @@
// !LANGUAGE: -ReferencesToSyntheticJavaProperties
// FILE: Customer.java
public class Customer {
private String name;
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// FILE: test.kt
val customerName = Customer::name
@@ -1,4 +1,5 @@
// !LANGUAGE: -ReferencesToSyntheticJavaProperties
// FIR_IDENTICAL
// FILE: Customer.java
public class Customer {
@@ -1,17 +0,0 @@
// !LANGUAGE: -ReferencesToSyntheticJavaProperties
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
// FILE: KotlinFile.kt
fun call(c: Any) {}
fun test() {
JavaClass::foo
call(JavaClass::foo)
}
// FILE: JavaClass.java
public class JavaClass {
public String getFoo() {}
}
@@ -1,5 +1,6 @@
// !LANGUAGE: -ReferencesToSyntheticJavaProperties
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
// FIR_IDENTICAL
// FILE: KotlinFile.kt
@@ -273,7 +273,6 @@ enum class LanguageFeature(
DataObjects(KOTLIN_1_9), // KT-4107
ProhibitAccessToEnumCompanionMembersInEnumConstructorCall(KOTLIN_1_9, kind = BUG_FIX), // KT-49110
RefineTypeCheckingOnAssignmentsToJavaFields(KOTLIN_1_9, kind = BUG_FIX), // KT-46727
ReferencesToSyntheticJavaProperties(KOTLIN_1_9), // KT-8575
ValueClassesSecondaryConstructorWithBody(sinceVersion = KOTLIN_1_9, kind = UNSTABLE_FEATURE), // KT-55333
NativeJsProhibitLateinitIsInitializedIntrinsicWithoutPrivateAccess(KOTLIN_1_9, kind = BUG_FIX), // KT-27002
@@ -291,6 +290,8 @@ enum class LanguageFeature(
// 2.1
ReferencesToSyntheticJavaProperties(KOTLIN_2_1), // KT-8575
// End of 2.* language features --------------------------------------------------
// This feature effectively might be removed because we decided to disable it until K2 and there it will be unconditionally enabled.