[FIR] Implement deprecation for calls to overrides of hidden
#KT-65438
This commit is contained in:
committed by
Space Team
parent
e16f80c578
commit
c6b2675089
+36
-7
@@ -20,19 +20,15 @@ import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo
|
|||||||
import org.jetbrains.kotlin.fir.declarations.RequireKotlinDeprecationInfo
|
import org.jetbrains.kotlin.fir.declarations.RequireKotlinDeprecationInfo
|
||||||
import org.jetbrains.kotlin.fir.declarations.getDeprecation
|
import org.jetbrains.kotlin.fir.declarations.getDeprecation
|
||||||
import org.jetbrains.kotlin.fir.declarations.getOwnDeprecation
|
import org.jetbrains.kotlin.fir.declarations.getOwnDeprecation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.toReference
|
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.references.resolved
|
import org.jetbrains.kotlin.fir.references.resolved
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeCallToDeprecatedOverrideOfHidden
|
||||||
import org.jetbrains.kotlin.fir.resolve.firClassLike
|
import org.jetbrains.kotlin.fir.resolve.firClassLike
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor
|
import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||||
@@ -69,6 +65,39 @@ object FirDeprecationChecker : FirBasicExpressionChecker(MppCheckerKind.Common)
|
|||||||
} else {
|
} else {
|
||||||
reportApiStatusIfNeeded(source, referencedSymbol, context, reporter, callSite = expression)
|
reportApiStatusIfNeeded(source, referencedSymbol, context, reporter, callSite = expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reportCallToDeprecatedOverrideOfHidden(expression, source, referencedSymbol, reporter, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reportCallToDeprecatedOverrideOfHidden(
|
||||||
|
expression: FirStatement,
|
||||||
|
source: KtSourceElement?,
|
||||||
|
referencedSymbol: FirBasedSymbol<*>,
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
context: CheckerContext,
|
||||||
|
) {
|
||||||
|
if (expression !is FirQualifiedAccessExpression) return
|
||||||
|
if (ConeCallToDeprecatedOverrideOfHidden in expression.nonFatalDiagnostics) {
|
||||||
|
val unwrappedSymbol = (referencedSymbol as? FirSyntheticPropertySymbol)?.getterSymbol?.delegateFunctionSymbol
|
||||||
|
?: referencedSymbol as? FirCallableSymbol
|
||||||
|
val callableName = unwrappedSymbol?.callableId?.callableName?.asString()
|
||||||
|
val message = getDeprecatedOverrideOfHiddenMessage(callableName)
|
||||||
|
reporter.reportOn(source, FirErrors.DEPRECATION, referencedSymbol, message, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val DeprecatedOverrideOfHiddenReplacements = mapOf(
|
||||||
|
"getFirst" to "first()",
|
||||||
|
"getLast" to "last()",
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun getDeprecatedOverrideOfHiddenMessage(callableName: String?): String {
|
||||||
|
val getFirstOrLastReplacement = DeprecatedOverrideOfHiddenReplacements[callableName]
|
||||||
|
return if (getFirstOrLastReplacement != null) {
|
||||||
|
"This declaration will be renamed in a future version of Kotlin. Please consider using the '$getFirstOrLastReplacement' stdlib extension if the collection supports fast random access."
|
||||||
|
} else {
|
||||||
|
"This declaration is redundant in Kotlin and might be removed soon."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if this is an access to a delegated property inside the delegated property itself.
|
/** Checks if this is an access to a delegated property inside the delegated property itself.
|
||||||
|
|||||||
+21
-7
@@ -330,8 +330,8 @@ var FirCallableDeclaration.isHiddenEverywhereBesideSuperCalls: HiddenEverywhereB
|
|||||||
IsHiddenEverywhereBesideSuperCalls
|
IsHiddenEverywhereBesideSuperCalls
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class HiddenEverywhereBesideSuperCallsStatus(val affectsOverrides: Boolean) {
|
enum class HiddenEverywhereBesideSuperCallsStatus {
|
||||||
HIDDEN(true), HIDDEN_IN_DECLARING_CLASS_ONLY(false)
|
HIDDEN, HIDDEN_IN_DECLARING_CLASS_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
private object IsHiddenToOvercomeSignatureClash : FirDeclarationDataKey()
|
private object IsHiddenToOvercomeSignatureClash : FirDeclarationDataKey()
|
||||||
@@ -340,11 +340,25 @@ var FirCallableDeclaration.isHiddenToOvercomeSignatureClash: Boolean? by FirDecl
|
|||||||
IsHiddenToOvercomeSignatureClash
|
IsHiddenToOvercomeSignatureClash
|
||||||
)
|
)
|
||||||
|
|
||||||
fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean, isOverridden: Boolean): Boolean {
|
enum class CallToPotentiallyHiddenSymbolResult {
|
||||||
|
Hidden, Visible, VisibleWithDeprecation,
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean, isOverridden: Boolean): CallToPotentiallyHiddenSymbolResult {
|
||||||
val fir = fir
|
val fir = fir
|
||||||
return when {
|
if (fir.isHiddenToOvercomeSignatureClash == true) {
|
||||||
fir.isHiddenToOvercomeSignatureClash == true -> true
|
return CallToPotentiallyHiddenSymbolResult.Hidden
|
||||||
!isSuperCall && fir.isHiddenEverywhereBesideSuperCalls?.let { it.affectsOverrides || !isOverridden } == true -> true
|
}
|
||||||
else -> false
|
|
||||||
|
val status = fir.isHiddenEverywhereBesideSuperCalls ?: return CallToPotentiallyHiddenSymbolResult.Visible
|
||||||
|
|
||||||
|
return when (status) {
|
||||||
|
// If the declaration is HIDDEN, we don't need a deprecation on supercalls because what are we warning the user about?
|
||||||
|
// The declaration can't get any more hidden.
|
||||||
|
HiddenEverywhereBesideSuperCallsStatus.HIDDEN -> if (isSuperCall) CallToPotentiallyHiddenSymbolResult.Visible else CallToPotentiallyHiddenSymbolResult.Hidden
|
||||||
|
// However, on HIDDEN_IN_DECLARING_CLASS_ONLY,
|
||||||
|
// we report a deprecation warning on super calls because we might want to rename the method in the future
|
||||||
|
// (getFirst -> first).
|
||||||
|
HiddenEverywhereBesideSuperCallsStatus.HIDDEN_IN_DECLARING_CLASS_ONLY -> if (isSuperCall || isOverridden) CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation else CallToPotentiallyHiddenSymbolResult.Hidden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
if (getterReturnType?.isUnit == true && CompilerConeAttributes.EnhancedNullability !in getterReturnType.attributes) return
|
if (getterReturnType?.isUnit == true && CompilerConeAttributes.EnhancedNullability !in getterReturnType.attributes) return
|
||||||
|
|
||||||
// Should have Java among overridden _and_ don't have isHiddenEverywhereBesideSuperCalls among them
|
// Should have Java among overridden _and_ don't have isHiddenEverywhereBesideSuperCalls among them
|
||||||
val getterCompatibility = getterSymbol.computeGetterCompatibility()
|
val (getterCompatibility, deprecatedOverrideOfHidden) = getterSymbol.computeGetterCompatibility()
|
||||||
if (getterCompatibility == Incompatible) return
|
if (getterCompatibility == Incompatible) return
|
||||||
|
|
||||||
var matchingSetter: FirSimpleFunction? = null
|
var matchingSetter: FirSimpleFunction? = null
|
||||||
@@ -143,13 +143,14 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val property = buildSyntheticProperty(propertyName, getter, matchingSetter, getterCompatibility)
|
val property = buildSyntheticProperty(propertyName, getter, matchingSetter, getterCompatibility, deprecatedOverrideOfHidden)
|
||||||
getter.originalForSubstitutionOverride?.let {
|
getter.originalForSubstitutionOverride?.let {
|
||||||
property.originalForSubstitutionOverrideAttr = buildSyntheticProperty(
|
property.originalForSubstitutionOverrideAttr = buildSyntheticProperty(
|
||||||
propertyName,
|
propertyName,
|
||||||
it,
|
it,
|
||||||
matchingSetter?.originalForSubstitutionOverride ?: matchingSetter,
|
matchingSetter?.originalForSubstitutionOverride ?: matchingSetter,
|
||||||
getterCompatibility
|
getterCompatibility,
|
||||||
|
deprecatedOverrideOfHidden,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val syntheticSymbol = property.symbol
|
val syntheticSymbol = property.symbol
|
||||||
@@ -166,6 +167,7 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
getter: FirSimpleFunction,
|
getter: FirSimpleFunction,
|
||||||
setter: FirSimpleFunction?,
|
setter: FirSimpleFunction?,
|
||||||
getterCompatibility: SyntheticGetterCompatibility,
|
getterCompatibility: SyntheticGetterCompatibility,
|
||||||
|
deprecatedOverrideOfHidden: Boolean,
|
||||||
): FirSyntheticProperty {
|
): FirSyntheticProperty {
|
||||||
val classLookupTag = getter.symbol.originalOrSelf().dispatchReceiverClassLookupTagOrNull()
|
val classLookupTag = getter.symbol.originalOrSelf().dispatchReceiverClassLookupTagOrNull()
|
||||||
val packageName = classLookupTag?.classId?.packageFqName ?: getter.symbol.callableId.packageName
|
val packageName = classLookupTag?.classId?.packageFqName ?: getter.symbol.callableId.packageName
|
||||||
@@ -185,6 +187,9 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
if (getterCompatibility != HasJavaOrigin) {
|
if (getterCompatibility != HasJavaOrigin) {
|
||||||
noJavaOrigin = true
|
noJavaOrigin = true
|
||||||
}
|
}
|
||||||
|
if (deprecatedOverrideOfHidden) {
|
||||||
|
this.deprecatedOverrideOfHidden = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +255,7 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
HasJavaOrigin
|
HasJavaOrigin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private data class GetterCompatibilityResult(val compatibility: SyntheticGetterCompatibility, val deprecatedOverrideOfHidden: Boolean)
|
||||||
/**
|
/**
|
||||||
* This method computes if getter method can be used as base for synthetic property based on overridden hierarchy
|
* This method computes if getter method can be used as base for synthetic property based on overridden hierarchy
|
||||||
* There are three kinds of compatibility:
|
* There are three kinds of compatibility:
|
||||||
@@ -257,16 +263,20 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
* - `HasJavaOrigin` indicates that this getter is based on root java function (ok to create property)
|
* - `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)
|
* - `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 {
|
private fun FirNamedFunctionSymbol.computeGetterCompatibility(): GetterCompatibilityResult {
|
||||||
val kotlinBaseAllowed = !session.languageVersionSettings.supportsFeature(ForbidSyntheticPropertiesWithoutBaseJavaGetter)
|
val kotlinBaseAllowed = !session.languageVersionSettings.supportsFeature(ForbidSyntheticPropertiesWithoutBaseJavaGetter)
|
||||||
|
|
||||||
var isHiddenEverywhereBesideSuperCalls = false
|
var isHiddenEverywhereBesideSuperCalls = false
|
||||||
|
var isDeprecatedOverrideOfHidden = false
|
||||||
var result = Incompatible
|
var result = Incompatible
|
||||||
|
|
||||||
val visited = mutableSetOf<MemberWithBaseScope<FirNamedFunctionSymbol>>()
|
val visited = mutableSetOf<MemberWithBaseScope<FirNamedFunctionSymbol>>()
|
||||||
fun checkJavaOrigin(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, isOverridden: Boolean) {
|
fun checkJavaOrigin(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, isOverridden: Boolean) {
|
||||||
if (symbol.isHidden(isSuperCall = false, isOverridden = isOverridden)) {
|
val hidden = symbol.isHidden(isSuperCall = false, isOverridden = isOverridden)
|
||||||
isHiddenEverywhereBesideSuperCalls = true
|
when (hidden) {
|
||||||
|
CallToPotentiallyHiddenSymbolResult.Hidden -> isHiddenEverywhereBesideSuperCalls = true
|
||||||
|
CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation -> isDeprecatedOverrideOfHidden = true
|
||||||
|
CallToPotentiallyHiddenSymbolResult.Visible -> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
val overriddenWithScope = scope.getDirectOverriddenFunctionsWithBaseScope(symbol)
|
val overriddenWithScope = scope.getDirectOverriddenFunctionsWithBaseScope(symbol)
|
||||||
@@ -292,7 +302,7 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
|
|
||||||
checkJavaOrigin(this, baseScope, isOverridden = false)
|
checkJavaOrigin(this, baseScope, isOverridden = false)
|
||||||
|
|
||||||
return when {
|
val syntheticGetterCompatibility = when {
|
||||||
isHiddenEverywhereBesideSuperCalls -> Incompatible
|
isHiddenEverywhereBesideSuperCalls -> Incompatible
|
||||||
result != Incompatible -> result
|
result != Incompatible -> result
|
||||||
!kotlinBaseAllowed -> Incompatible
|
!kotlinBaseAllowed -> Incompatible
|
||||||
@@ -300,6 +310,7 @@ class FirSyntheticPropertiesScope private constructor(
|
|||||||
isJavaTypeOnThePath(this.dispatchReceiverType) -> HasKotlinOrigin
|
isJavaTypeOnThePath(this.dispatchReceiverType) -> HasKotlinOrigin
|
||||||
else -> Incompatible
|
else -> Incompatible
|
||||||
}
|
}
|
||||||
|
return GetterCompatibilityResult(syntheticGetterCompatibility, isDeprecatedOverrideOfHidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -365,3 +376,9 @@ private var FirSyntheticProperty.noJavaOrigin: Boolean? by FirDeclarationDataReg
|
|||||||
val FirSimpleSyntheticPropertySymbol.noJavaOrigin: Boolean
|
val FirSimpleSyntheticPropertySymbol.noJavaOrigin: Boolean
|
||||||
get() = (fir as FirSyntheticProperty).noJavaOrigin == true
|
get() = (fir as FirSyntheticProperty).noJavaOrigin == true
|
||||||
|
|
||||||
|
private object DeprecatedOverrideOfHidden : FirDeclarationDataKey()
|
||||||
|
private var FirSyntheticProperty.deprecatedOverrideOfHidden: Boolean? by FirDeclarationDataRegistry.data(DeprecatedOverrideOfHidden)
|
||||||
|
|
||||||
|
val FirSimpleSyntheticPropertySymbol.deprecatedOverrideOfHidden: Boolean
|
||||||
|
get() = (fir as FirSyntheticProperty).deprecatedOverrideOfHidden == true
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom
|
|||||||
import org.jetbrains.kotlin.fir.resolve.inference.csBuilder
|
import org.jetbrains.kotlin.fir.resolve.inference.csBuilder
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.addNonFatalDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
@@ -391,6 +392,10 @@ class FirCallResolver(
|
|||||||
replaceDispatchReceiver(candidate.dispatchReceiverExpression())
|
replaceDispatchReceiver(candidate.dispatchReceiverExpression())
|
||||||
replaceExtensionReceiver(candidate.chosenExtensionReceiverExpression())
|
replaceExtensionReceiver(candidate.chosenExtensionReceiverExpression())
|
||||||
replaceContextReceiverArguments(candidate.contextReceiverArguments())
|
replaceContextReceiverArguments(candidate.contextReceiverArguments())
|
||||||
|
|
||||||
|
if (CallToDeprecatedOverrideOfHidden in candidate.diagnostics) {
|
||||||
|
addNonFatalDiagnostic(ConeCallToDeprecatedOverrideOfHidden)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transformer.storeTypeFromCallee(qualifiedAccess, isLhsOfAssignment = callSite is FirVariableAssignment)
|
transformer.storeTypeFromCallee(qualifiedAccess, isLhsOfAssignment = callSite is FirVariableAssignment)
|
||||||
|
|||||||
+26
-8
@@ -755,7 +755,7 @@ internal object CheckHiddenDeclaration : ResolutionStage() {
|
|||||||
/** Actual declarations are checked by [FirDeprecationChecker] */
|
/** Actual declarations are checked by [FirDeprecationChecker] */
|
||||||
if (symbol.isActual) return
|
if (symbol.isActual) return
|
||||||
val deprecation = symbol.getDeprecation(context.session, callInfo.callSite)
|
val deprecation = symbol.getDeprecation(context.session, callInfo.callSite)
|
||||||
if (deprecation?.deprecationLevel == DeprecationLevelValue.HIDDEN || isHiddenForThisCallSite(symbol, callInfo, candidate, context.session)) {
|
if (deprecation?.deprecationLevel == DeprecationLevelValue.HIDDEN || isHiddenForThisCallSite(symbol, callInfo, candidate, context.session, sink)) {
|
||||||
sink.yieldDiagnostic(HiddenCandidate)
|
sink.yieldDiagnostic(HiddenCandidate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -764,25 +764,43 @@ internal object CheckHiddenDeclaration : ResolutionStage() {
|
|||||||
symbol: FirCallableSymbol<*>,
|
symbol: FirCallableSymbol<*>,
|
||||||
callInfo: CallInfo,
|
callInfo: CallInfo,
|
||||||
candidate: Candidate,
|
candidate: Candidate,
|
||||||
session: FirSession
|
session: FirSession,
|
||||||
|
sink: CheckerSink,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val isSuperCall = callInfo.callSite.isSuperCall(session)
|
/**
|
||||||
|
* The logic for synthetic properties itself is in [FirSyntheticPropertiesScope.computeGetterCompatibility].
|
||||||
|
*/
|
||||||
|
if (symbol is FirSimpleSyntheticPropertySymbol && symbol.deprecatedOverrideOfHidden) {
|
||||||
|
sink.reportDiagnostic(CallToDeprecatedOverrideOfHidden)
|
||||||
|
}
|
||||||
|
|
||||||
if (symbol.fir.dispatchReceiverType == null || symbol !is FirNamedFunctionSymbol) return false
|
if (symbol.fir.dispatchReceiverType == null || symbol !is FirNamedFunctionSymbol) return false
|
||||||
if (symbol.isHidden(isSuperCall, isOverridden = false)) return true
|
val isSuperCall = callInfo.callSite.isSuperCall(session)
|
||||||
|
if (symbol.isHidden(isSuperCall, isOverridden = false) == CallToPotentiallyHiddenSymbolResult.Hidden) return true
|
||||||
|
|
||||||
val scope = candidate.originScope as? FirTypeScope ?: return false
|
val scope = candidate.originScope as? FirTypeScope ?: return false
|
||||||
|
|
||||||
var result = false
|
var hidden = false
|
||||||
|
var deprecated = false
|
||||||
scope.processOverriddenFunctions(symbol) {
|
scope.processOverriddenFunctions(symbol) {
|
||||||
if (it.isHidden(isSuperCall, isOverridden = true)) {
|
val result = it.isHidden(isSuperCall, isOverridden = true)
|
||||||
result = true
|
if (result != CallToPotentiallyHiddenSymbolResult.Visible) {
|
||||||
|
if (result == CallToPotentiallyHiddenSymbolResult.Hidden) {
|
||||||
|
hidden = true
|
||||||
|
} else if (result == CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation) {
|
||||||
|
deprecated = true
|
||||||
|
}
|
||||||
ProcessorAction.STOP
|
ProcessorAction.STOP
|
||||||
} else {
|
} else {
|
||||||
ProcessorAction.NEXT
|
ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
if (deprecated) {
|
||||||
|
sink.reportDiagnostic(CallToDeprecatedOverrideOfHidden)
|
||||||
|
}
|
||||||
|
|
||||||
|
return hidden
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirElement.isSuperCall(session: FirSession): Boolean =
|
private fun FirElement.isSuperCall(session: FirSession): Boolean =
|
||||||
|
|||||||
+13
-9
@@ -328,9 +328,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
result.replaceConeTypeOrNull(resultType)
|
result.replaceConeTypeOrNull(resultType)
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, context.file.source)
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, context.file.source)
|
||||||
|
|
||||||
if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) {
|
result.addNonFatalDiagnostics(calleeReference)
|
||||||
result.addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility)
|
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,12 +382,20 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
return arrayOfCallTransformer.transformFunctionCall(result, session)
|
return arrayOfCallTransformer.transformFunctionCall(result, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) {
|
result.addNonFatalDiagnostics(calleeReference)
|
||||||
result.addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility)
|
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirQualifiedAccessExpression.addNonFatalDiagnostics(calleeReference: FirNamedReferenceWithCandidate) {
|
||||||
|
if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) {
|
||||||
|
addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CallToDeprecatedOverrideOfHidden in calleeReference.candidate.diagnostics) {
|
||||||
|
addNonFatalDiagnostic(ConeCallToDeprecatedOverrideOfHidden)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirCall.transformWithExpectedTypes(expectedArgumentsTypeMapping: ExpectedArgumentType.ArgumentsMap?) {
|
private fun FirCall.transformWithExpectedTypes(expectedArgumentsTypeMapping: ExpectedArgumentType.ArgumentsMap?) {
|
||||||
class SamConversionInsertionTransformer : FirTransformer<Nothing?>() {
|
class SamConversionInsertionTransformer : FirTransformer<Nothing?>() {
|
||||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): E {
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): E {
|
||||||
@@ -579,9 +585,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
replaceCalleeReference(resolvedReference)
|
replaceCalleeReference(resolvedReference)
|
||||||
replaceDispatchReceiver(dispatchReceiver)
|
replaceDispatchReceiver(dispatchReceiver)
|
||||||
replaceExtensionReceiver(extensionReceiver)
|
replaceExtensionReceiver(extensionReceiver)
|
||||||
if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) {
|
addNonFatalDiagnostics(calleeReference)
|
||||||
addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -163,4 +163,6 @@ object TypeParameterAsExpression : ResolutionDiagnostic(INAPPLICABLE)
|
|||||||
class TypeVariableAsExplicitReceiver(
|
class TypeVariableAsExplicitReceiver(
|
||||||
val explicitReceiver: FirExpression,
|
val explicitReceiver: FirExpression,
|
||||||
val typeParameter: FirTypeParameter,
|
val typeParameter: FirTypeParameter,
|
||||||
) : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
|
) : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
|
||||||
|
|
||||||
|
object CallToDeprecatedOverrideOfHidden : ResolutionDiagnostic(RESOLVED)
|
||||||
+5
@@ -404,3 +404,8 @@ object ConeResolutionResultOverridesOtherToPreserveCompatibility : ConeDiagnosti
|
|||||||
get() = "Resolution result overrides another result to preserve compatibility, result maybe changed in future versions"
|
get() = "Resolution result overrides another result to preserve compatibility, result maybe changed in future versions"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object ConeCallToDeprecatedOverrideOfHidden : ConeDiagnostic {
|
||||||
|
override val reason: String
|
||||||
|
get() = "Call to deprecated override of hidden"
|
||||||
|
}
|
||||||
+1
-1
@@ -9,5 +9,5 @@ interface A : MutableCollection<String> {
|
|||||||
fun foo(x: MutableCollection<Int>, y: Collection<String>, z: A) {
|
fun foo(x: MutableCollection<Int>, y: Collection<String>, z: A) {
|
||||||
x.<!UNRESOLVED_REFERENCE!>nonExistingMethod<!>(1).<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><<!CANNOT_INFER_PARAMETER_TYPE!>String<!>>() }
|
x.<!UNRESOLVED_REFERENCE!>nonExistingMethod<!>(1).<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><<!CANNOT_INFER_PARAMETER_TYPE!>String<!>>() }
|
||||||
y.<!UNRESOLVED_REFERENCE!>nonExistingMethod<!>("")
|
y.<!UNRESOLVED_REFERENCE!>nonExistingMethod<!>("")
|
||||||
z.<!UNRESOLVED_REFERENCE!>nonExistingMethod<!>("")
|
z.<!DEPRECATION!>nonExistingMethod<!>("")
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+9
-9
@@ -1,11 +1,11 @@
|
|||||||
fun foo(ll: java.util.LinkedList<String>, al: ArrayList<String>, ad: ArrayDeque<String>, jad: java.util.ArrayDeque<String>) {
|
fun foo(ll: java.util.LinkedList<String>, al: ArrayList<String>, ad: ArrayDeque<String>, jad: java.util.ArrayDeque<String>) {
|
||||||
ll.addFirst("")
|
ll.addFirst("")
|
||||||
ll.addLast("")
|
ll.addLast("")
|
||||||
ll.getFirst()
|
ll.<!DEPRECATION!>getFirst<!>()
|
||||||
ll.first // synthetic property for getFirst()
|
ll.<!DEPRECATION!>first<!> // synthetic property for getFirst()
|
||||||
ll.first() // stdlib extension on List
|
ll.first() // stdlib extension on List
|
||||||
ll.getLast()
|
ll.<!DEPRECATION!>getLast<!>()
|
||||||
ll.last
|
ll.<!DEPRECATION!>last<!>
|
||||||
ll.last()
|
ll.last()
|
||||||
ll.removeFirst()
|
ll.removeFirst()
|
||||||
ll.removeLast()
|
ll.removeLast()
|
||||||
@@ -13,11 +13,11 @@ fun foo(ll: java.util.LinkedList<String>, al: ArrayList<String>, ad: ArrayDeque<
|
|||||||
|
|
||||||
al.addFirst("")
|
al.addFirst("")
|
||||||
al.addLast("")
|
al.addLast("")
|
||||||
al.getFirst()
|
al.<!DEPRECATION!>getFirst<!>()
|
||||||
al.first
|
al.<!DEPRECATION!>first<!>
|
||||||
al.first()
|
al.first()
|
||||||
al.getLast()
|
al.<!DEPRECATION!>getLast<!>()
|
||||||
al.last
|
al.<!DEPRECATION!>last<!>
|
||||||
al.last()
|
al.last()
|
||||||
al.removeFirst()
|
al.removeFirst()
|
||||||
al.removeLast()
|
al.removeLast()
|
||||||
@@ -46,4 +46,4 @@ fun foo(ll: java.util.LinkedList<String>, al: ArrayList<String>, ad: ArrayDeque<
|
|||||||
jad.removeFirst()
|
jad.removeFirst()
|
||||||
jad.removeLast()
|
jad.removeLast()
|
||||||
jad.reversed()
|
jad.reversed()
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -1,3 +1,7 @@
|
|||||||
|
/newListMethods.fir.kt:(253,261): warning: 'fun getFirst(): T!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'first()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(302,309): warning: 'fun getLast(): T!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'last()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
/newListMethods.fir.kt:(596,604): error: Unresolved reference 'getFirst'.
|
/newListMethods.fir.kt:(596,604): error: Unresolved reference 'getFirst'.
|
||||||
|
|
||||||
/newListMethods.fir.kt:(613,618): error: Function invocation 'first()' expected.
|
/newListMethods.fir.kt:(613,618): error: Function invocation 'first()' expected.
|
||||||
@@ -5,3 +9,19 @@
|
|||||||
/newListMethods.fir.kt:(704,711): error: Unresolved reference 'getLast'.
|
/newListMethods.fir.kt:(704,711): error: Unresolved reference 'getLast'.
|
||||||
|
|
||||||
/newListMethods.fir.kt:(720,724): error: Function invocation 'last()' expected.
|
/newListMethods.fir.kt:(720,724): error: Function invocation 'last()' expected.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(838,846): warning: 'fun getFirst(): String!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'first()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(855,860): warning: 'val first: String!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'first()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(881,888): warning: 'fun getLast(): String!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'last()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(897,901): warning: 'val last: String!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'last()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(1015,1023): warning: 'fun getFirst(): String' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'first()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(1032,1037): warning: 'val first: String' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'first()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(1058,1065): warning: 'fun getLast(): String' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'last()' stdlib extension if the collection supports fast random access.
|
||||||
|
|
||||||
|
/newListMethods.fir.kt:(1074,1078): warning: 'val last: String' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'last()' stdlib extension if the collection supports fast random access.
|
||||||
|
|||||||
+10
-10
@@ -10,8 +10,8 @@ class A<T> : ArrayList<T>() {
|
|||||||
super.addLast(t)
|
super.addLast(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFirst(): T = super.getFirst()
|
override fun getFirst(): T = super.<!DEPRECATION!>getFirst<!>()
|
||||||
override fun getLast(): T = super.getLast()
|
override fun getLast(): T = super.<!DEPRECATION!>getLast<!>()
|
||||||
|
|
||||||
override fun removeFirst(): T = super.removeFirst()
|
override fun removeFirst(): T = super.removeFirst()
|
||||||
override fun removeLast(): T = super.removeLast()
|
override fun removeLast(): T = super.removeLast()
|
||||||
@@ -34,11 +34,11 @@ fun foo(x: MutableList<String>, y: ArrayList<String>, z: A<String>) {
|
|||||||
|
|
||||||
y.addFirst("")
|
y.addFirst("")
|
||||||
y.addLast("")
|
y.addLast("")
|
||||||
y.getFirst()
|
y.<!DEPRECATION!>getFirst<!>()
|
||||||
y.first
|
y.<!DEPRECATION!>first<!>
|
||||||
y.first()
|
y.first()
|
||||||
y.getLast()
|
y.<!DEPRECATION!>getLast<!>()
|
||||||
y.last
|
y.<!DEPRECATION!>last<!>
|
||||||
y.last()
|
y.last()
|
||||||
y.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeFirst; typeCall: function")!>removeFirst()<!>
|
y.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeFirst; typeCall: function")!>removeFirst()<!>
|
||||||
y.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeLast; typeCall: function")!>removeLast()<!>
|
y.<!DEBUG_INFO_CALL("fqName: java.util.ArrayList.removeLast; typeCall: function")!>removeLast()<!>
|
||||||
@@ -46,11 +46,11 @@ fun foo(x: MutableList<String>, y: ArrayList<String>, z: A<String>) {
|
|||||||
|
|
||||||
z.addFirst("")
|
z.addFirst("")
|
||||||
z.addLast("")
|
z.addLast("")
|
||||||
z.getFirst()
|
z.<!DEPRECATION!>getFirst<!>()
|
||||||
z.first
|
z.<!DEPRECATION!>first<!>
|
||||||
z.first()
|
z.first()
|
||||||
z.getLast()
|
z.<!DEPRECATION!>getLast<!>()
|
||||||
z.last
|
z.<!DEPRECATION!>last<!>
|
||||||
z.last()
|
z.last()
|
||||||
z.<!DEBUG_INFO_CALL("fqName: A.removeFirst; typeCall: function")!>removeFirst()<!>
|
z.<!DEBUG_INFO_CALL("fqName: A.removeFirst; typeCall: function")!>removeFirst()<!>
|
||||||
z.<!DEBUG_INFO_CALL("fqName: A.removeLast; typeCall: function")!>removeLast()<!>
|
z.<!DEBUG_INFO_CALL("fqName: A.removeLast; typeCall: function")!>removeLast()<!>
|
||||||
|
|||||||
Reference in New Issue
Block a user