Implement basic use-site scopes and override mapping
This commit also introduces separate scope processors: processFunctionsByName and processPropertiesByName, in addition to existing processClassifiersByName Ad-hock call resolver starts to discover ambiguities, which leads to some ambiguity problems in MPP tests with deep supertype hierarchy Related to KT-29636
This commit is contained in:
committed by
Mikhail Glukhikh
parent
6ea2abfc46
commit
840750ee40
+102
-25
@@ -7,13 +7,18 @@ package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.FirResolvedCallableReference
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassUseSiteScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
@@ -30,39 +35,111 @@ class FirAccessResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(rev
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession = session): FirClassUseSiteScope {
|
||||
val superTypeScope = FirCompositeScope(mutableListOf())
|
||||
val declaredScope = FirClassDeclaredMemberScope(this, useSiteSession)
|
||||
lookupSuperTypes(this, lookupInterfaces = true).asReversed()
|
||||
.mapNotNullTo(superTypeScope.scopes) { useSiteSuperType ->
|
||||
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
|
||||
val symbol = useSiteSuperType.symbol
|
||||
if (symbol is FirClassSymbol) {
|
||||
symbol.fir.buildUseSiteScope(useSiteSession)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
return FirClassUseSiteScope(useSiteSession, superTypeScope, declaredScope, true)
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
return withScopeCleanup {
|
||||
val useSiteSession = regularClass.session
|
||||
lookupSuperTypes(regularClass, lookupInterfaces = true).asReversed()
|
||||
.mapNotNullTo(towerScope.scopes) { useSiteSuperType ->
|
||||
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
|
||||
val symbol = useSiteSuperType.symbol
|
||||
if (symbol is FirClassSymbol) {
|
||||
FirClassDeclaredMemberScope(symbol.fir, useSiteSession)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
towerScope.scopes += FirClassDeclaredMemberScope(regularClass, useSiteSession)
|
||||
towerScope.scopes += regularClass.buildUseSiteScope()
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
}
|
||||
|
||||
var lookupFunctions = false
|
||||
var lookupProperties = false
|
||||
|
||||
inline fun <T> withNewSettings(block: () -> T): T {
|
||||
val prevFunctions = lookupFunctions
|
||||
val prevProperties = lookupProperties
|
||||
val result = block()
|
||||
|
||||
lookupFunctions = prevFunctions
|
||||
lookupProperties = prevProperties
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
|
||||
return withNewSettings {
|
||||
lookupFunctions = true
|
||||
lookupProperties = false
|
||||
super.transformFunctionCall(functionCall, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun transformQualifiedAccessExpression(
|
||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||
data: Nothing?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return withNewSettings {
|
||||
lookupProperties = true
|
||||
lookupFunctions = false
|
||||
super.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformCallableReferenceAccess(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
data: Nothing?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return withNewSettings {
|
||||
lookupProperties = true
|
||||
lookupFunctions = true
|
||||
super.transformCallableReferenceAccess(callableReferenceAccess, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun transformAssignment(assignment: FirAssignment, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
return withNewSettings {
|
||||
lookupProperties = true
|
||||
lookupFunctions = false
|
||||
super.transformAssignment(assignment, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun transformNamedReference(namedReference: FirNamedReference, data: Nothing?): CompositeTransformResult<FirNamedReference> {
|
||||
if (namedReference is FirResolvedCallableReference) return namedReference.compose()
|
||||
val name = namedReference.name
|
||||
var symbol: ConeCallableSymbol? = null
|
||||
towerScope.processClassifiersByName(name, FirPosition.OTHER) {
|
||||
symbol = it as? ConeCallableSymbol
|
||||
// I'm lucky today!!! (the first symbol we have found is the one we need)
|
||||
it is ConeCallableSymbol
|
||||
val referents = mutableListOf<ConeCallableSymbol>()
|
||||
fun collect(it: ConeCallableSymbol): ProcessorAction {
|
||||
referents.add(it)
|
||||
return NEXT
|
||||
}
|
||||
val callableSymbol = symbol ?: return FirErrorNamedReference(
|
||||
namedReference.session, namedReference.psi, "Unresolved name: $name"
|
||||
).compose()
|
||||
return FirResolvedCallableReferenceImpl(
|
||||
namedReference.session, namedReference.psi,
|
||||
name, callableSymbol
|
||||
).compose()
|
||||
|
||||
if (lookupFunctions)
|
||||
towerScope.processFunctionsByName(name, ::collect)
|
||||
if (lookupProperties)
|
||||
towerScope.processPropertiesByName(name, ::collect)
|
||||
|
||||
return when (referents.size) {
|
||||
0 -> FirErrorNamedReference(
|
||||
namedReference.session, namedReference.psi, "Unresolved name: $name"
|
||||
).compose()
|
||||
1 -> FirResolvedCallableReferenceImpl(
|
||||
namedReference.session, namedReference.psi,
|
||||
name, referents.single()
|
||||
).compose()
|
||||
else -> FirErrorNamedReference(
|
||||
namedReference.session, namedReference.psi, "Ambiguity: $name, ${referents.map { it.callableId }}"
|
||||
).compose()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -13,10 +16,34 @@ interface FirScope {
|
||||
name: Name,
|
||||
position: FirPosition,
|
||||
processor: (ConeSymbol) -> Boolean
|
||||
): Boolean
|
||||
): Boolean = true
|
||||
|
||||
fun processFunctionsByName(
|
||||
name: Name,
|
||||
processor: (ConeFunctionSymbol) -> ProcessorAction
|
||||
): ProcessorAction = NEXT
|
||||
|
||||
fun processPropertiesByName(
|
||||
name: Name,
|
||||
processor: (ConePropertySymbol) -> ProcessorAction
|
||||
): ProcessorAction = NEXT
|
||||
}
|
||||
|
||||
enum class FirPosition(val allowTypeParameters: Boolean = true) {
|
||||
SUPER_TYPE_OR_EXPANSION(allowTypeParameters = false),
|
||||
OTHER
|
||||
}
|
||||
|
||||
enum class ProcessorAction {
|
||||
STOP,
|
||||
NEXT;
|
||||
|
||||
operator fun not(): Boolean {
|
||||
return when (this) {
|
||||
STOP -> true
|
||||
NEXT -> false
|
||||
}
|
||||
}
|
||||
|
||||
fun next() = this == NEXT
|
||||
}
|
||||
+19
-10
@@ -7,9 +7,12 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirClassDeclaredMemberScope(
|
||||
@@ -19,17 +22,23 @@ class FirClassDeclaredMemberScope(
|
||||
) : FirAbstractProviderBasedScope(session, lookupInFir) {
|
||||
private val classId = klass.symbol.classId
|
||||
|
||||
override fun processClassifiersByName(
|
||||
name: Name,
|
||||
position: FirPosition,
|
||||
processor: (ConeSymbol) -> Boolean
|
||||
): Boolean {
|
||||
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||
val symbols = provider.getCallableSymbols(CallableId(classId.packageFqName, classId.relativeClassName, name))
|
||||
for (symbol in symbols) {
|
||||
if (!processor(symbol)) {
|
||||
return false
|
||||
if (symbol is ConeFunctionSymbol && !processor(symbol)) {
|
||||
return STOP
|
||||
}
|
||||
}
|
||||
return true
|
||||
return NEXT
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
|
||||
val symbols = provider.getCallableSymbols(CallableId(classId.packageFqName, classId.relativeClassName, name))
|
||||
for (symbol in symbols) {
|
||||
if (symbol is ConePropertySymbol && !processor(symbol)) {
|
||||
return STOP
|
||||
}
|
||||
}
|
||||
return NEXT
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMember
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedType
|
||||
import org.jetbrains.kotlin.fir.types.FirType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
class FirClassUseSiteScope(
|
||||
session: FirSession,
|
||||
private val superTypesScope: FirScope,
|
||||
private val declaredMemberScope: FirClassDeclaredMemberScope,
|
||||
lookupInFir: Boolean
|
||||
) : FirAbstractProviderBasedScope(session, lookupInFir) {
|
||||
//base symbol as key
|
||||
val overrides = mutableMapOf<ConeCallableSymbol, ConeCallableSymbol?>()
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun isSubtypeOf(subType: ConeKotlinType, superType: ConeKotlinType): Boolean {
|
||||
// TODO: introduce normal sub-typing
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isSubtypeOf(subType: FirType, superType: FirType) =
|
||||
isSubtypeOf(subType.cast<FirResolvedType>().type, superType.cast<FirResolvedType>().type)
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun isEqualTypes(a: ConeKotlinType, b: ConeKotlinType): Boolean {
|
||||
// TODO: introduce normal type comparison
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isEqualTypes(a: FirType, b: FirType) = isEqualTypes(a.cast<FirResolvedType>().type, b.cast<FirResolvedType>().type)
|
||||
|
||||
private fun isOverriddenFunCheck(member: FirNamedFunction, self: FirNamedFunction): Boolean {
|
||||
return member.valueParameters.size == self.valueParameters.size &&
|
||||
member.valueParameters.zip(self.valueParameters).all { (memberParam, selfParam) ->
|
||||
isEqualTypes(memberParam.returnType, selfParam.returnType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeCallableSymbol.isOverridden(seen: Set<ConeCallableSymbol>): ConeCallableSymbol? {
|
||||
if (overrides.containsKey(this)) return overrides[this]
|
||||
|
||||
fun sameReceivers(memberType: FirType?, selfType: FirType?): Boolean {
|
||||
return when {
|
||||
memberType != null && selfType != null -> isEqualTypes(memberType, selfType)
|
||||
else -> memberType == null && selfType == null
|
||||
}
|
||||
}
|
||||
|
||||
fun similarFunctionsOrBothProperties(member: FirCallableMember, self: FirCallableMember): Boolean {
|
||||
return when (member) {
|
||||
is FirNamedFunction -> self is FirNamedFunction && isOverriddenFunCheck(member, self)
|
||||
is FirConstructor -> false
|
||||
is FirProperty -> self is FirProperty
|
||||
else -> error("Unknown fir callable type: $member, $self")
|
||||
}
|
||||
}
|
||||
|
||||
val self = (this as AbstractFirBasedSymbol<*>).fir as FirCallableMember
|
||||
val overriding = seen.firstOrNull {
|
||||
val member = (it as AbstractFirBasedSymbol<*>).fir as FirCallableMember
|
||||
member.isOverride && self.modality != Modality.FINAL
|
||||
&& sameReceivers(member.receiverType, self.receiverType)
|
||||
&& isSubtypeOf(member.returnType, self.returnType)
|
||||
&& similarFunctionsOrBothProperties(member, self)
|
||||
} // TODO: two or more overrides for one fun?
|
||||
overrides[this] = overriding
|
||||
return overriding
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||
val seen = mutableSetOf<ConeCallableSymbol>()
|
||||
if (!declaredMemberScope.processFunctionsByName(name) {
|
||||
seen += it
|
||||
processor(it)
|
||||
}
|
||||
) return STOP
|
||||
|
||||
return superTypesScope.processFunctionsByName(name) {
|
||||
|
||||
val overriddenBy = it.isOverridden(seen)
|
||||
if (overriddenBy == null) {
|
||||
processor(it)
|
||||
} else {
|
||||
NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
|
||||
val seen = mutableSetOf<ConeCallableSymbol>()
|
||||
if (!declaredMemberScope.processPropertiesByName(name) {
|
||||
seen += it
|
||||
processor(it)
|
||||
}
|
||||
) return STOP
|
||||
|
||||
return superTypesScope.processPropertiesByName(name) {
|
||||
|
||||
val overriddenBy = it.isOverridden(seen)
|
||||
if (overriddenBy == null) {
|
||||
processor(it)
|
||||
} else {
|
||||
NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,11 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -29,4 +34,27 @@ class FirCompositeScope(
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private inline fun <T> processComposite(
|
||||
process: FirScope.(Name, (T) -> ProcessorAction) -> ProcessorAction,
|
||||
name: Name,
|
||||
noinline processor: (T) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
val scopes = if (reversedPriority) scopes.asReversed() else scopes
|
||||
for (scope in scopes) {
|
||||
if (!scope.process(name, processor)) {
|
||||
return STOP
|
||||
}
|
||||
}
|
||||
return NEXT
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||
return processComposite(FirScope::processFunctionsByName, name, processor)
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
|
||||
return processComposite(FirScope::processPropertiesByName, name, processor)
|
||||
}
|
||||
|
||||
}
|
||||
+19
-10
@@ -7,9 +7,12 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirTopLevelDeclaredMemberScope(
|
||||
@@ -19,17 +22,23 @@ class FirTopLevelDeclaredMemberScope(
|
||||
) : FirAbstractProviderBasedScope(session, lookupInFir) {
|
||||
private val packageFqName = file.packageFqName
|
||||
|
||||
override fun processClassifiersByName(
|
||||
name: Name,
|
||||
position: FirPosition,
|
||||
processor: (ConeSymbol) -> Boolean
|
||||
): Boolean {
|
||||
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||
val symbols = provider.getCallableSymbols(CallableId(packageFqName, name))
|
||||
for (symbol in symbols) {
|
||||
if (!processor(symbol)) {
|
||||
return false
|
||||
if (symbol is ConeFunctionSymbol && !processor(symbol)) {
|
||||
return STOP
|
||||
}
|
||||
}
|
||||
return true
|
||||
return NEXT
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
|
||||
val symbols = provider.getCallableSymbols(CallableId(packageFqName, name))
|
||||
for (symbol in symbols) {
|
||||
if (symbol is ConePropertySymbol && !processor(symbol)) {
|
||||
return STOP
|
||||
}
|
||||
}
|
||||
return NEXT
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
open class A {
|
||||
open fun foo(): A = this
|
||||
open fun bar(): A = this
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
override fun foo(): B = this
|
||||
fun bar(): B = this // Ambiguity, no override here
|
||||
|
||||
fun test() {
|
||||
foo()
|
||||
bar()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
FILE: simple.kt
|
||||
public open class A {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public open function foo(): R|A| {
|
||||
return@@@foo this#
|
||||
}
|
||||
|
||||
public open function bar(): R|A| {
|
||||
return@@@bar this#
|
||||
}
|
||||
|
||||
}
|
||||
public final class B : R|A| {
|
||||
public constructor(): super<R|A|>()
|
||||
|
||||
public final override function foo(): R|B| {
|
||||
return@@@foo this#
|
||||
}
|
||||
|
||||
public final function bar(): R|B| {
|
||||
return@@@bar this#
|
||||
}
|
||||
|
||||
public final function test(): R|kotlin/Unit| {
|
||||
R|/B.foo|()
|
||||
<Ambiguity: bar, [/B.bar, /A.bar]>#()
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -243,6 +243,24 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/overrides")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Overrides extends AbstractFirResolveTestCase {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInOverrides() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/overrides"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/overrides/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/references")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@ FILE: jvm.kt
|
||||
public constructor(): super<R|B|>()
|
||||
|
||||
public final function test(): R|kotlin/Unit| {
|
||||
R|/A.foo|()
|
||||
R|/A.bar|()
|
||||
<Ambiguity: foo, [/A.foo, /A.foo]>#()
|
||||
<Ambiguity: bar, [/A.bar, /A.bar]>#()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ FILE: jvm.kt
|
||||
public constructor(): super<R|B|>()
|
||||
|
||||
public final function test(): R|kotlin/Unit| {
|
||||
R|/A.foo|()
|
||||
<Ambiguity: foo, [/A.foo, /A.foo]>#()
|
||||
<Unresolved name: bar>#()
|
||||
<Unresolved name: baz>#()
|
||||
}
|
||||
@@ -33,8 +33,8 @@ FILE: jvm.kt
|
||||
|
||||
public final function test(): R|kotlin/Unit| {
|
||||
R|/A.foo|()
|
||||
R|/X.bar|()
|
||||
R|/Y.baz|()
|
||||
<Ambiguity: bar, [/X.bar, /X.bar]>#()
|
||||
<Ambiguity: baz, [/Y.baz, /Y.baz]>#()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user