[FIR] KT-54410: Report API_NOT_AVAILABLE for classifiers

Callable symbols with SinceKotlin are filtered out by a
resolution stage, but in K1 classifiers and property accessors
report API_NOT_AVAILABLE. K2 filters out properties with
unavailable accessors, but does nothing for classifiers.
This change fixes it.

^KT-54410 Fixed
This commit is contained in:
Nikolay Lunyak
2023-01-18 19:13:42 +02:00
committed by Space Team
parent fd52cc4224
commit 9be819087a
22 changed files with 144 additions and 12 deletions
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
@@ -361,6 +362,7 @@ internal object FirToKtConversionCreator {
FirModuleData::class, FirModuleData::class,
ExpectActualCompatibility.Incompatible::class, ExpectActualCompatibility.Incompatible::class,
DeprecationInfo::class, DeprecationInfo::class,
ApiVersion::class,
CallableId::class, CallableId::class,
ClassKind::class, ClassKind::class,
) )
@@ -313,6 +313,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.API_NOT_AVAILABLE) { firDiagnostic ->
ApiNotAvailableImpl(
firDiagnostic.a,
firDiagnostic.b,
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.UNRESOLVED_REFERENCE_WRONG_RECEIVER) { firDiagnostic -> add(FirErrors.UNRESOLVED_REFERENCE_WRONG_RECEIVER) { firDiagnostic ->
UnresolvedReferenceWrongReceiverImpl( UnresolvedReferenceWrongReceiverImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtVariableSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
@@ -256,6 +257,12 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val message: String abstract val message: String
} }
abstract class ApiNotAvailable : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = ApiNotAvailable::class
abstract val sinceKotlinVersion: ApiVersion
abstract val currentVersion: ApiVersion
}
abstract class UnresolvedReferenceWrongReceiver : KtFirDiagnostic<PsiElement>() { abstract class UnresolvedReferenceWrongReceiver : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = UnresolvedReferenceWrongReceiver::class override val diagnosticClass get() = UnresolvedReferenceWrongReceiver::class
abstract val candidates: List<KtSymbol> abstract val candidates: List<KtSymbol>
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtVariableSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
@@ -294,6 +295,13 @@ internal class DeprecationImpl(
override val token: KtLifetimeToken, override val token: KtLifetimeToken,
) : KtFirDiagnostic.Deprecation(), KtAbstractFirDiagnostic<PsiElement> ) : KtFirDiagnostic.Deprecation(), KtAbstractFirDiagnostic<PsiElement>
internal class ApiNotAvailableImpl(
override val sinceKotlinVersion: ApiVersion,
override val currentVersion: ApiVersion,
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.ApiNotAvailable(), KtAbstractFirDiagnostic<PsiElement>
internal class UnresolvedReferenceWrongReceiverImpl( internal class UnresolvedReferenceWrongReceiverImpl(
override val candidates: List<KtSymbol>, override val candidates: List<KtSymbol>,
override val firDiagnostic: KtPsiDiagnostic, override val firDiagnostic: KtPsiDiagnostic,
@@ -35349,6 +35349,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt");
} }
@Test
@TestMetadata("kt54410.kt")
public void testKt54410() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/kt54410.kt");
}
@Test @Test
@TestMetadata("kt8050.kt") @TestMetadata("kt8050.kt")
public void testKt8050() throws Exception { public void testKt8050() throws Exception {
@@ -35445,6 +35445,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt");
} }
@Test
@TestMetadata("kt54410.kt")
public void testKt54410() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/kt54410.kt");
}
@Test @Test
@TestMetadata("kt8050.kt") @TestMetadata("kt8050.kt")
public void testKt8050() throws Exception { public void testKt8050() throws Exception {
@@ -35349,6 +35349,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt");
} }
@Test
@TestMetadata("kt54410.kt")
public void testKt54410() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/kt54410.kt");
}
@Test @Test
@TestMetadata("kt8050.kt") @TestMetadata("kt8050.kt")
public void testKt8050() throws Exception { public void testKt8050() throws Exception {
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
@@ -120,6 +121,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<String>("message") parameter<String>("message")
} }
val API_NOT_AVAILABLE by error<PsiElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
parameter<ApiVersion>("sinceKotlinVersion")
parameter<ApiVersion>("currentVersion")
}
val UNRESOLVED_REFERENCE_WRONG_RECEIVER by error<PsiElement> { val UNRESOLVED_REFERENCE_WRONG_RECEIVER by error<PsiElement> {
parameter<Collection<Symbol>>("candidates") parameter<Collection<Symbol>>("candidates")
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageFeature.ForbidExposingTypesInPrimaryConstructorProperties import org.jetbrains.kotlin.config.LanguageFeature.ForbidExposingTypesInPrimaryConstructorProperties
import org.jetbrains.kotlin.config.LanguageFeature.ForbidUsingExtensionPropertyTypeParameterInDelegate import org.jetbrains.kotlin.config.LanguageFeature.ForbidUsingExtensionPropertyTypeParameterInDelegate
@@ -151,6 +152,7 @@ object FirErrors {
val NO_THIS by error0<PsiElement>() val NO_THIS by error0<PsiElement>()
val DEPRECATION_ERROR by error2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val DEPRECATION_ERROR by error2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATION by warning2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val DEPRECATION by warning2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val API_NOT_AVAILABLE by error2<PsiElement, ApiVersion, ApiVersion>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
val UNRESOLVED_REFERENCE_WRONG_RECEIVER by error1<PsiElement, Collection<FirBasedSymbol<*>>>() val UNRESOLVED_REFERENCE_WRONG_RECEIVER by error1<PsiElement, Collection<FirBasedSymbol<*>>>()
val UNRESOLVED_IMPORT by error1<PsiElement, String>(SourceElementPositioningStrategies.IMPORT_LAST_NAME) val UNRESOLVED_IMPORT by error1<PsiElement, String>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
@@ -38,7 +38,7 @@ object FirImportsChecker : FirFileChecker() {
checkOperatorRename(import, context, reporter) checkOperatorRename(import, context, reporter)
} }
} }
checkDeprecatedImport(import, context, reporter) checkImportApiStatus(import, context, reporter)
} }
checkConflictingImports(declaration.imports, context, reporter) checkConflictingImports(declaration.imports, context, reporter)
} }
@@ -241,11 +241,11 @@ object FirImportsChecker : FirFileChecker() {
else ImportStatus.UNRESOLVED else ImportStatus.UNRESOLVED
} }
private fun checkDeprecatedImport(import: FirImport, context: CheckerContext, reporter: DiagnosticReporter) { private fun checkImportApiStatus(import: FirImport, context: CheckerContext, reporter: DiagnosticReporter) {
val importedFqName = import.importedFqName ?: return val importedFqName = import.importedFqName ?: return
if (importedFqName.isRoot || importedFqName.shortName().asString().isEmpty()) return if (importedFqName.isRoot || importedFqName.shortName().asString().isEmpty()) return
val classId = (import as? FirResolvedImport)?.resolvedParentClassId ?: ClassId.topLevel(importedFqName) val classId = (import as? FirResolvedImport)?.resolvedParentClassId ?: ClassId.topLevel(importedFqName)
val classLike: FirRegularClassSymbol = classId.resolveToClass(context) ?: return val classLike: FirRegularClassSymbol = classId.resolveToClass(context) ?: return
FirDeprecationChecker.reportDeprecationIfNeeded(import.source, classLike, null, context, reporter) FirDeprecationChecker.reportApiStatusIfNeeded(import.source, classLike, null, context, reporter)
} }
} }
@@ -14,11 +14,11 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
object FirDeprecatedQualifierChecker : FirResolvedQualifierChecker() { object FirDeprecatedQualifierChecker : FirResolvedQualifierChecker() {
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
expression.nonFatalDiagnostics.filterIsInstance<ConeDeprecated>().forEach { diagnostic -> expression.nonFatalDiagnostics.filterIsInstance<ConeDeprecated>().forEach { diagnostic ->
FirDeprecationChecker.reportDeprecation(diagnostic.source, diagnostic.symbol, diagnostic.deprecationInfo, reporter, context) FirDeprecationChecker.reportApiStatus(diagnostic.source, diagnostic.symbol, diagnostic.deprecationInfo, reporter, context)
} }
if (expression.resolvedToCompanionObject) { if (expression.resolvedToCompanionObject) {
val companionSymbol = (expression.symbol as? FirRegularClassSymbol)?.companionObjectSymbol ?: return val companionSymbol = (expression.symbol as? FirRegularClassSymbol)?.companionObjectSymbol ?: return
FirDeprecationChecker.reportDeprecationIfNeeded(expression.source, companionSymbol, null, context, reporter) FirDeprecationChecker.reportApiStatusIfNeeded(expression.source, companionSymbol, null, context, reporter)
} }
} }
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo
import org.jetbrains.kotlin.fir.declarations.getDeprecation import org.jetbrains.kotlin.fir.declarations.getDeprecation
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
@@ -39,10 +40,10 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
val reference = resolvable.calleeReference.resolved ?: return val reference = resolvable.calleeReference.resolved ?: return
val referencedSymbol = reference.resolvedSymbol val referencedSymbol = reference.resolvedSymbol
reportDeprecationIfNeeded(reference.source, referencedSymbol, expression, context, reporter) reportApiStatusIfNeeded(reference.source, referencedSymbol, expression, context, reporter)
} }
internal fun reportDeprecationIfNeeded( internal fun reportApiStatusIfNeeded(
source: KtSourceElement?, source: KtSourceElement?,
referencedSymbol: FirBasedSymbol<*>, referencedSymbol: FirBasedSymbol<*>,
callSite: FirElement?, callSite: FirElement?,
@@ -50,10 +51,24 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
val deprecation = getWorstDeprecation(callSite, referencedSymbol, context) ?: return val deprecation = getWorstDeprecation(callSite, referencedSymbol, context) ?: return
reportDeprecation(source, referencedSymbol, deprecation, reporter, context) reportApiStatus(source, referencedSymbol, deprecation, reporter, context)
} }
internal fun reportDeprecation( internal fun reportApiStatus(
source: KtSourceElement?,
referencedSymbol: FirBasedSymbol<*>,
deprecationInfo: DeprecationInfo,
reporter: DiagnosticReporter,
context: CheckerContext,
) {
if (deprecationInfo is FutureApiDeprecationInfo) {
reportApiNotAvailable(source, deprecationInfo, reporter, context)
} else {
reportDeprecation(source, referencedSymbol, deprecationInfo, reporter, context)
}
}
private fun reportDeprecation(
source: KtSourceElement?, source: KtSourceElement?,
referencedSymbol: FirBasedSymbol<*>, referencedSymbol: FirBasedSymbol<*>,
deprecationInfo: DeprecationInfo, deprecationInfo: DeprecationInfo,
@@ -67,6 +82,21 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
reporter.reportOn(source, diagnostic, referencedSymbol, deprecationInfo.message ?: "", context) reporter.reportOn(source, diagnostic, referencedSymbol, deprecationInfo.message ?: "", context)
} }
private fun reportApiNotAvailable(
source: KtSourceElement?,
deprecationInfo: FutureApiDeprecationInfo,
reporter: DiagnosticReporter,
context: CheckerContext,
) {
reporter.reportOn(
source,
FirErrors.API_NOT_AVAILABLE,
deprecationInfo.sinceVersion,
context.languageVersionSettings.apiVersion,
context,
)
}
private fun getWorstDeprecation( private fun getWorstDeprecation(
callSite: FirElement?, callSite: FirElement?,
symbol: FirBasedSymbol<*>, symbol: FirBasedSymbol<*>,
@@ -21,6 +21,6 @@ object FirDeprecatedTypeChecker : FirTypeRefChecker() {
val resolved = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return val resolved = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return
val symbol = resolved.lookupTag.toSymbol(context.session) ?: return val symbol = resolved.lookupTag.toSymbol(context.session) ?: return
FirDeprecationChecker.reportDeprecationIfNeeded(source, symbol, null, context, reporter) FirDeprecationChecker.reportApiStatusIfNeeded(source, symbol, null, context, reporter)
} }
} }
@@ -75,6 +75,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_USED_A
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_WITH_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_WITH_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.API_NOT_AVAILABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_PASSED_TWICE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_PASSED_TWICE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_TYPE_MISMATCH import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS
@@ -640,6 +641,12 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING) map.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING)
map.put(DEPRECATION, "''{0}'' is deprecated. {1}", SYMBOL, STRING) map.put(DEPRECATION, "''{0}'' is deprecated. {1}", SYMBOL, STRING)
map.put(DEPRECATION_ERROR, "''{0}'' is deprecated. {1}", SYMBOL, STRING) map.put(DEPRECATION_ERROR, "''{0}'' is deprecated. {1}", SYMBOL, STRING)
map.put(
API_NOT_AVAILABLE,
"This declaration is only available since Kotlin {0} and cannot be used with the specified API version {1}",
TO_STRING,
TO_STRING,
)
map.put(ASSIGNMENT_IN_EXPRESSION_CONTEXT, "Assignments are not expressions, and only expressions are allowed in this context") map.put(ASSIGNMENT_IN_EXPRESSION_CONTEXT, "Assignments are not expressions, and only expressions are allowed in this context")
map.put(EXPRESSION_EXPECTED, "Only expressions are allowed here") map.put(EXPRESSION_EXPECTED, "Only expressions are allowed here")
@@ -58,13 +58,21 @@ sealed interface DeprecationAnnotationInfo {
fun computeDeprecationInfo(apiVersion: ApiVersion): DeprecationInfo? fun computeDeprecationInfo(apiVersion: ApiVersion): DeprecationInfo?
} }
data class FutureApiDeprecationInfo(
override val deprecationLevel: DeprecationLevelValue,
override val propagatesToOverrides: Boolean,
val sinceVersion: ApiVersion,
) : DeprecationInfo() {
override val message: String? get() = null
}
class SinceKotlinInfo(val sinceVersion: ApiVersion) : DeprecationAnnotationInfo { class SinceKotlinInfo(val sinceVersion: ApiVersion) : DeprecationAnnotationInfo {
override fun computeDeprecationInfo(apiVersion: ApiVersion): DeprecationInfo? { override fun computeDeprecationInfo(apiVersion: ApiVersion): DeprecationInfo? {
return runUnless(sinceVersion <= apiVersion) { return runUnless(sinceVersion <= apiVersion) {
SimpleDeprecationInfo( FutureApiDeprecationInfo(
deprecationLevel = DeprecationLevelValue.HIDDEN, deprecationLevel = DeprecationLevelValue.HIDDEN,
propagatesToOverrides = true, propagatesToOverrides = true,
message = null sinceVersion = sinceVersion,
) )
} }
} }
@@ -619,6 +619,11 @@ object LightTreePositioningStrategies {
} }
return super.mark(node, startOffset, endOffset, tree) return super.mark(node, startOffset, endOffset, tree)
} }
if (node.tokenType == KtNodeTypes.IMPORT_DIRECTIVE) {
tree.collectDescendantsOfType(node, KtNodeTypes.REFERENCE_EXPRESSION).lastOrNull()?.let {
return mark(it, it.startOffset, it.endOffset, tree)
}
}
if (node.tokenType == KtNodeTypes.TYPE_REFERENCE) { if (node.tokenType == KtNodeTypes.TYPE_REFERENCE) {
val typeElement = tree.findChildByType(node, KtTokenSets.TYPE_ELEMENT_TYPES) val typeElement = tree.findChildByType(node, KtTokenSets.TYPE_ELEMENT_TYPES)
if (typeElement != null) { if (typeElement != null) {
@@ -851,6 +851,10 @@ object PositioningStrategies {
is KtElement -> return mark(selectorExpression) is KtElement -> return mark(selectorExpression)
} }
} }
if (element is KtImportDirective) {
element.alias?.nameIdentifier?.let { return mark(it) }
element.importedReference?.let { return mark(it) }
}
if (element is KtTypeReference) { if (element is KtTypeReference) {
element.typeElement?.getReferencedTypeExpression()?.let { return mark(it) } element.typeElement?.getReferencedTypeExpression()?.let { return mark(it) }
} }
@@ -14,6 +14,8 @@ enum class CandidateApplicability {
/** /**
* Candidate is removed from resolve due to SinceKotlin with later version or Deprecation with hidden level. * Candidate is removed from resolve due to SinceKotlin with later version or Deprecation with hidden level.
* Note that SinceKotlin does not filter out classifier symbols and property accessors. Those
* should lead to API_NOT_AVAILABLE.
* Provokes UNRESOLVED_REFERENCE. * Provokes UNRESOLVED_REFERENCE.
*/ */
HIDDEN, HIDDEN,
@@ -0,0 +1,8 @@
// API_VERSION: 1.7
import kotlin.io.path.<!API_NOT_AVAILABLE!>OnErrorResult<!>
fun fun0 (): Unit {
val something1 = <!NO_COMPANION_OBJECT!>OnErrorResult<!>.<!OPT_IN_USAGE_ERROR!>TERMINATE<!>
val something2 = kotlin.io.path.<!API_NOT_AVAILABLE, OPT_IN_USAGE_ERROR!>OnErrorResult<!>.<!OPT_IN_USAGE_ERROR!>TERMINATE<!>
}
@@ -0,0 +1,8 @@
// API_VERSION: 1.7
import kotlin.io.path.<!API_NOT_AVAILABLE!>OnErrorResult<!>
fun fun0 (): Unit {
val something1 = <!API_NOT_AVAILABLE, OPT_IN_USAGE_ERROR!>OnErrorResult<!>.<!OPT_IN_USAGE_ERROR!>TERMINATE<!>
val something2 = kotlin.io.path.<!API_NOT_AVAILABLE, OPT_IN_USAGE_ERROR!>OnErrorResult<!>.<!OPT_IN_USAGE_ERROR!>TERMINATE<!>
}
@@ -0,0 +1,3 @@
package
public fun fun0(): kotlin.Unit
@@ -35445,6 +35445,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/jvmFieldAndJavaGetter.kt");
} }
@Test
@TestMetadata("kt54410.kt")
public void testKt54410() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/kt54410.kt");
}
@Test @Test
@TestMetadata("kt8050.kt") @TestMetadata("kt8050.kt")
public void testKt8050() throws Exception { public void testKt8050() throws Exception {