FIR: Use platform specific overridability rules for platform members

^KT-54570 Fixed
This commit is contained in:
Denis.Zharkov
2022-10-21 17:57:24 +02:00
committed by Space Team
parent 1e368bcd86
commit 52eb535a7d
11 changed files with 154 additions and 8 deletions
@@ -24265,6 +24265,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt");
}
@Test
@TestMetadata("smartCastToClassWithRawSupertype.kt")
public void testSmartCastToClassWithRawSupertype() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/smartCastToClassWithRawSupertype.kt");
}
@Test
@TestMetadata("starProjectionToRaw.kt")
public void testStarProjectionToRaw() throws Exception {
@@ -24265,6 +24265,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt");
}
@Test
@TestMetadata("smartCastToClassWithRawSupertype.kt")
public void testSmartCastToClassWithRawSupertype() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/smartCastToClassWithRawSupertype.kt");
}
@Test
@TestMetadata("starProjectionToRaw.kt")
public void testStarProjectionToRaw() throws Exception {
@@ -24265,6 +24265,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt");
}
@Test
@TestMetadata("smartCastToClassWithRawSupertype.kt")
public void testSmartCastToClassWithRawSupertype() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/smartCastToClassWithRawSupertype.kt");
}
@Test
@TestMetadata("starProjectionToRaw.kt")
public void testStarProjectionToRaw() throws Exception {
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.java.FirJvmDefaultModeComponent
import org.jetbrains.kotlin.fir.java.JvmSupertypeUpdater
import org.jetbrains.kotlin.fir.java.enhancement.FirAnnotationTypeQualifierResolver
import org.jetbrains.kotlin.fir.java.enhancement.FirEnhancedSymbolsStorage
import org.jetbrains.kotlin.fir.java.scopes.JavaOverridabilityRules
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.PlatformSupertypeUpdater
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.GeneratedClassIndex
import org.jetbrains.kotlin.fir.scopes.FirOverrideService
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
import org.jetbrains.kotlin.fir.scopes.PlatformSpecificOverridabilityRules
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.FirDynamicMembersStorage
import org.jetbrains.kotlin.fir.scopes.impl.FirIntersectionOverrideStorage
@@ -88,6 +90,7 @@ fun FirSession.registerCommonJavaComponents(javaModuleResolver: JavaModuleResolv
FirJvmDefaultModeComponent(languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode))
)
register(PlatformSupertypeUpdater::class, JvmSupertypeUpdater(this))
register(PlatformSpecificOverridabilityRules::class, JavaOverridabilityRules(this))
}
// -------------------------- Resolve components --------------------------
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2022 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.java.scopes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.scopes.PlatformSpecificOverridabilityRules
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
class JavaOverridabilityRules(session: FirSession) : PlatformSpecificOverridabilityRules {
private val javaOverrideChecker =
JavaOverrideChecker(session, JavaTypeParameterStack.EMPTY, baseScopes = null, considerReturnTypeKinds = true)
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean? {
if (!overrideCandidate.isFromJava() || !baseDeclaration.isFromJava()) return null
return javaOverrideChecker.isOverriddenFunction(overrideCandidate, baseDeclaration)
}
override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean? {
if (!overrideCandidate.isFromJava() || !baseDeclaration.isFromJava()) return null
return javaOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
}
private fun FirCallableDeclaration.isFromJava(): Boolean = unwrapFakeOverrides().origin == FirDeclarationOrigin.Enhancement
}
@@ -11,11 +11,11 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.resolve.substitution.ConeRawScopeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.scopes.scopeForClass
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.FirScopeWithFakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope
import org.jetbrains.kotlin.fir.scopes.impl.dynamicMembersStorage
import org.jetbrains.kotlin.fir.scopes.impl.getOrBuildScopeForIntegerConstantOperatorType
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
@@ -89,7 +89,7 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
is ConeFlexibleType -> lowerBound.scope(useSiteSession, scopeSession, requiredPhase)
is ConeIntersectionType -> FirTypeIntersectionScope.prepareIntersectionScope(
useSiteSession,
FirStandardOverrideChecker(useSiteSession),
FirIntersectionScopeOverrideChecker(useSiteSession),
intersectedTypes.mapNotNullTo(mutableListOf()) {
it.scope(useSiteSession, scopeSession, requiredPhase)
},
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2022 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.scopes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker
/**
* That class is expected to work just the same as FirStandardOverrideChecker for regular members,
* but when it comes to the platform originated member, it's more correct to use platform specific rules, too
*
* Initial reason for that checker introduction is smart-cast to raw type:
* it makes initial type's member incompatible with raw-type's one when regular overridability rules are used,
* while in Java class they would be treated equally.
*/
class FirIntersectionScopeOverrideChecker(session: FirSession) : FirOverrideChecker {
private val standardOverrideChecker = FirStandardOverrideChecker(session)
private val platformSpecificOverridabilityRules = session.platformSpecificOverridabilityRules
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
platformSpecificOverridabilityRules?.isOverriddenFunction(overrideCandidate, baseDeclaration)?.let { return it }
return standardOverrideChecker.isOverriddenFunction(overrideCandidate, baseDeclaration)
}
override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean {
platformSpecificOverridabilityRules?.isOverriddenProperty(overrideCandidate, baseDeclaration)?.let { return it }
return standardOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2022 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.scopes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
interface PlatformSpecificOverridabilityRules : FirSessionComponent {
// Thus functions return "null" in case the status should be defined via standard platform-independent rules
fun isOverriddenFunction(
overrideCandidate: FirSimpleFunction,
baseDeclaration: FirSimpleFunction
): Boolean?
fun isOverriddenProperty(
overrideCandidate: FirCallableDeclaration,
baseDeclaration: FirProperty
): Boolean?
}
val FirSession.platformSpecificOverridabilityRules: PlatformSpecificOverridabilityRules? by FirSession.nullableSessionComponentAccessor()
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.FirDefaultStarImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -153,7 +152,7 @@ class MemberScopeTowerLevel(
val overridableGroups = session.overrideService.createOverridableGroups(
candidatesFromOriginalType + candidatesFromSmartcast,
FirStandardOverrideChecker(session)
FirIntersectionScopeOverrideChecker(session)
)
val candidates = mutableListOf<MemberWithBaseScope<T>>()
@@ -0,0 +1,24 @@
// FIR_IDENTICAL
// SKIP_TXT
// !DIAGNOSTICS: -UNUSED_VARIABLE
// FILE: Key.java
public interface Key<E> {}
// FILE: UserDataHolder.java
public interface UserDataHolder {
<T> T getUserData(@NotNull Key<T> key);
}
// FILE: GenericInterface.java
public abstract class GenericClass<E> extends UserDataHolder {}
// FILE: NonGenericClassWithRawSuperType.java
public abstract class NonGenericClassWithRawSuperType extends GenericClass {}
// FILE: main.kt
fun foo(k: Key<Boolean>, a: NonGenericClassWithRawSuperType, b: GenericClass<*>) {
b.getUserData<Boolean>(k)
if (b is NonGenericClassWithRawSuperType) {
b.getUserData<Boolean>(k)
}
}
@@ -24271,6 +24271,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt");
}
@Test
@TestMetadata("smartCastToClassWithRawSupertype.kt")
public void testSmartCastToClassWithRawSupertype() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/smartCastToClassWithRawSupertype.kt");
}
@Test
@TestMetadata("starProjectionToRaw.kt")
public void testStarProjectionToRaw() throws Exception {