[FIR] Introduce containsMultipleNonSubsumed to intersection overrides
After this change the IO created for `SimpleColoredComponent::setToolTipText` will be `containsMultipleNonSubsumed == true` while IOs created for classes in `intersectionOverridesIntersection.kt` will have this property set to `false`. ^KT-65972 Fixed
This commit is contained in:
committed by
Space Team
parent
ee20d979cb
commit
341a23d05c
+4
-1
@@ -334,7 +334,10 @@ class FirSignatureEnhancement(
|
|||||||
this.name = name!!
|
this.name = name!!
|
||||||
status = firMethod.status
|
status = firMethod.status
|
||||||
symbol = if (isIntersectionOverride) {
|
symbol = if (isIntersectionOverride) {
|
||||||
FirIntersectionOverrideFunctionSymbol(methodId, overriddenMembers.map { it.symbol })
|
FirIntersectionOverrideFunctionSymbol(
|
||||||
|
methodId, overriddenMembers.map { it.symbol },
|
||||||
|
containsMultipleNonSubsumed = (firMethod.symbol as? FirIntersectionCallableSymbol)?.containsMultipleNonSubsumed == true,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
FirNamedFunctionSymbol(methodId)
|
FirNamedFunctionSymbol(methodId)
|
||||||
}.also { functionSymbol = it }
|
}.also { functionSymbol = it }
|
||||||
|
|||||||
@@ -375,7 +375,11 @@ class JavaOverrideChecker internal constructor(
|
|||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility {
|
): Visibility {
|
||||||
val overridesWithoutIntersections = extractedOverrides.flatMap { it.flattenIntersectionsRecursively() }
|
// It's crucial that we only unwrap phantom intersection overrides.
|
||||||
|
// See comments in the following tests for explanation:
|
||||||
|
// - intersectionWithMultipleDefaultsInJavaOverriddenByIntersectionInKotlin.kt
|
||||||
|
// - intersectionOverridesIntersection.kt
|
||||||
|
val overridesWithoutIntersections = extractedOverrides.flatMap { it.flattenPhantomIntersectionsRecursively() }
|
||||||
val nonSubsumed = overridesWithoutIntersections.nonSubsumed().filterOutDuplicates()
|
val nonSubsumed = overridesWithoutIntersections.nonSubsumed().filterOutDuplicates()
|
||||||
|
|
||||||
// In Java it's OK to inherit multiple implementations of the same function
|
// In Java it's OK to inherit multiple implementations of the same function
|
||||||
|
|||||||
@@ -176,6 +176,16 @@ fun MemberWithBaseScope<FirCallableSymbol<*>>.flattenIntersectionsRecursively():
|
|||||||
return baseScope.getDirectOverriddenMembersWithBaseScope(member).flatMap { it.flattenIntersectionsRecursively() }
|
return baseScope.getDirectOverriddenMembersWithBaseScope(member).flatMap { it.flattenIntersectionsRecursively() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MemberWithBaseScope<FirCallableSymbol<*>>.flattenPhantomIntersectionsRecursively(): List<MemberWithBaseScope<FirCallableSymbol<*>>> {
|
||||||
|
val symbol = member.unwrapSubstitutionOverrides<FirCallableSymbol<*>>()
|
||||||
|
|
||||||
|
if (symbol !is FirIntersectionCallableSymbol || symbol.containsMultipleNonSubsumed) {
|
||||||
|
return listOf(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseScope.getDirectOverriddenMembersWithBaseScope(member).flatMap { it.flattenPhantomIntersectionsRecursively() }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callable declaration D [subsumes](https://kotlinlang.org/spec/inheritance.html#matching-and-subsumption-of-declarations)
|
* A callable declaration D [subsumes](https://kotlinlang.org/spec/inheritance.html#matching-and-subsumption-of-declarations)
|
||||||
* a callable declaration B if D overrides B.
|
* a callable declaration B if D overrides B.
|
||||||
|
|||||||
+5
-1
@@ -166,7 +166,11 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
|
|||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility {
|
): Visibility {
|
||||||
val overridesWithoutIntersections = extractedOverrides.flatMap { it.flattenIntersectionsRecursively() }
|
// It's crucial that we only unwrap phantom intersection overrides.
|
||||||
|
// See comments in the following tests for explanation:
|
||||||
|
// - intersectionWithMultipleDefaultsInJavaOverriddenByIntersectionInKotlin.kt
|
||||||
|
// - intersectionOverridesIntersection.kt
|
||||||
|
val overridesWithoutIntersections = extractedOverrides.flatMap { it.flattenPhantomIntersectionsRecursively() }
|
||||||
val nonSubsumed = overridesWithoutIntersections.nonSubsumed().filterOutDuplicates()
|
val nonSubsumed = overridesWithoutIntersections.nonSubsumed().filterOutDuplicates()
|
||||||
return chooseIntersectionVisibilityOrNull(nonSubsumed) ?: Visibilities.Unknown
|
return chooseIntersectionVisibilityOrNull(nonSubsumed) ?: Visibilities.Unknown
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-9
@@ -64,7 +64,8 @@ class FirTypeIntersectionScopeContext(
|
|||||||
val context: FirTypeIntersectionScopeContext,
|
val context: FirTypeIntersectionScopeContext,
|
||||||
val mostSpecific: List<MemberWithBaseScope<D>>,
|
val mostSpecific: List<MemberWithBaseScope<D>>,
|
||||||
overriddenMembers: List<MemberWithBaseScope<D>>,
|
overriddenMembers: List<MemberWithBaseScope<D>>,
|
||||||
containingScope: FirTypeScope?
|
containingScope: FirTypeScope?,
|
||||||
|
val containsMultipleNonSubsumed: Boolean,
|
||||||
) : ResultOfIntersection<D>(overriddenMembers, containingScope) {
|
) : ResultOfIntersection<D>(overriddenMembers, containingScope) {
|
||||||
override val chosenSymbol: D by lazy {
|
override val chosenSymbol: D by lazy {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -174,7 +175,15 @@ class FirTypeIntersectionScopeContext(
|
|||||||
}
|
}
|
||||||
if (nonTrivial) {
|
if (nonTrivial) {
|
||||||
// Only add non-subsumed members to list of overridden in intersection override.
|
// Only add non-subsumed members to list of overridden in intersection override.
|
||||||
result += ResultOfIntersection.NonTrivial(this, mostSpecific, overriddenMembers = group, containingScope = null)
|
result += ResultOfIntersection.NonTrivial(
|
||||||
|
this, mostSpecific,
|
||||||
|
overriddenMembers = group,
|
||||||
|
containingScope = null,
|
||||||
|
containsMultipleNonSubsumed = when {
|
||||||
|
forClassUseSiteScope -> group.flatMap { it.flattenPhantomIntersectionsRecursively() }.nonSubsumed().size > 1
|
||||||
|
else -> mostSpecific.flatMap { it.flattenPhantomIntersectionsRecursively() }.nonSubsumed().size > 1
|
||||||
|
},
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
val (member, containingScope) = mostSpecific.first()
|
val (member, containingScope) = mostSpecific.first()
|
||||||
result += ResultOfIntersection.SingleMember(member, group, containingScope)
|
result += ResultOfIntersection.SingleMember(member, group, containingScope)
|
||||||
@@ -203,6 +212,7 @@ class FirTypeIntersectionScopeContext(
|
|||||||
fun <D : FirCallableSymbol<*>> createIntersectionOverride(
|
fun <D : FirCallableSymbol<*>> createIntersectionOverride(
|
||||||
mostSpecific: List<MemberWithBaseScope<D>>,
|
mostSpecific: List<MemberWithBaseScope<D>>,
|
||||||
extractedOverrides: List<MemberWithBaseScope<D>>,
|
extractedOverrides: List<MemberWithBaseScope<D>>,
|
||||||
|
containsMultipleNonSubsumed: Boolean,
|
||||||
): MemberWithBaseScope<FirCallableSymbol<*>> {
|
): MemberWithBaseScope<FirCallableSymbol<*>> {
|
||||||
val newModality = chooseIntersectionOverrideModality(extractedOverrides.flatMap { it.flattenIntersectionsRecursively() }.nonSubsumed())
|
val newModality = chooseIntersectionOverrideModality(extractedOverrides.flatMap { it.flattenIntersectionsRecursively() }.nonSubsumed())
|
||||||
val newVisibility = overrideChecker.chooseIntersectionVisibility(extractedOverrides, dispatchClassSymbol)
|
val newVisibility = overrideChecker.chooseIntersectionVisibility(extractedOverrides, dispatchClassSymbol)
|
||||||
@@ -211,14 +221,20 @@ class FirTypeIntersectionScopeContext(
|
|||||||
val key = mostSpecific.first()
|
val key = mostSpecific.first()
|
||||||
return when (key.member) {
|
return when (key.member) {
|
||||||
is FirNamedFunctionSymbol ->
|
is FirNamedFunctionSymbol ->
|
||||||
createIntersectionOverrideFunction(mostSpecificSymbols, extractedOverridesSymbols, newModality, newVisibility)
|
createIntersectionOverrideFunction(
|
||||||
|
mostSpecificSymbols, extractedOverridesSymbols, newModality, newVisibility, containsMultipleNonSubsumed
|
||||||
|
)
|
||||||
|
|
||||||
is FirPropertySymbol ->
|
is FirPropertySymbol ->
|
||||||
createIntersectionOverrideProperty(mostSpecificSymbols, extractedOverridesSymbols, newModality, newVisibility)
|
createIntersectionOverrideProperty(
|
||||||
|
mostSpecificSymbols, extractedOverridesSymbols, newModality, newVisibility, containsMultipleNonSubsumed
|
||||||
|
)
|
||||||
|
|
||||||
is FirFieldSymbol -> {
|
is FirFieldSymbol -> {
|
||||||
if (forClassUseSiteScope) error("Can not create intersection override in class scope for field ${key.member}")
|
if (forClassUseSiteScope) error("Can not create intersection override in class scope for field ${key.member}")
|
||||||
createIntersectionOverrideField(mostSpecificSymbols, extractedOverridesSymbols, newModality, newVisibility)
|
createIntersectionOverrideField(
|
||||||
|
mostSpecificSymbols, extractedOverridesSymbols, newModality, newVisibility, containsMultipleNonSubsumed
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> error("Unsupported symbol type for creating intersection overrides: ${key.member}")
|
else -> error("Unsupported symbol type for creating intersection overrides: ${key.member}")
|
||||||
@@ -323,6 +339,7 @@ class FirTypeIntersectionScopeContext(
|
|||||||
overrides: Collection<FirCallableSymbol<*>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
newModality: Modality?,
|
newModality: Modality?,
|
||||||
newVisibility: Visibility,
|
newVisibility: Visibility,
|
||||||
|
containsMultipleNonSubsumed: Boolean,
|
||||||
): FirNamedFunctionSymbol {
|
): FirNamedFunctionSymbol {
|
||||||
val key = mostSpecific.first() as FirNamedFunctionSymbol
|
val key = mostSpecific.first() as FirNamedFunctionSymbol
|
||||||
val keyFir = key.fir
|
val keyFir = key.fir
|
||||||
@@ -330,7 +347,7 @@ class FirTypeIntersectionScopeContext(
|
|||||||
dispatchReceiverType.classId ?: keyFir.dispatchReceiverClassLookupTagOrNull()?.classId!!,
|
dispatchReceiverType.classId ?: keyFir.dispatchReceiverClassLookupTagOrNull()?.classId!!,
|
||||||
keyFir.name
|
keyFir.name
|
||||||
)
|
)
|
||||||
val newSymbol = FirIntersectionOverrideFunctionSymbol(callableId, overrides)
|
val newSymbol = FirIntersectionOverrideFunctionSymbol(callableId, overrides, containsMultipleNonSubsumed)
|
||||||
val deferredReturnTypeCalculation = deferredReturnTypeCalculationOrNull(mostSpecific)
|
val deferredReturnTypeCalculation = deferredReturnTypeCalculationOrNull(mostSpecific)
|
||||||
FirFakeOverrideGenerator.createCopyForFirFunction(
|
FirFakeOverrideGenerator.createCopyForFirFunction(
|
||||||
newSymbol, keyFir, derivedClassLookupTag = null, session,
|
newSymbol, keyFir, derivedClassLookupTag = null, session,
|
||||||
@@ -353,10 +370,12 @@ class FirTypeIntersectionScopeContext(
|
|||||||
overrides: Collection<FirCallableSymbol<*>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
newModality: Modality?,
|
newModality: Modality?,
|
||||||
newVisibility: Visibility,
|
newVisibility: Visibility,
|
||||||
|
containsMultipleNonSubsumed: Boolean,
|
||||||
): FirPropertySymbol {
|
): FirPropertySymbol {
|
||||||
return createIntersectionOverrideVariable<FirPropertySymbol, _>(
|
return createIntersectionOverrideVariable<FirPropertySymbol, _>(
|
||||||
mostSpecific,
|
mostSpecific,
|
||||||
overrides,
|
overrides,
|
||||||
|
containsMultipleNonSubsumed,
|
||||||
::FirIntersectionOverridePropertySymbol,
|
::FirIntersectionOverridePropertySymbol,
|
||||||
) { symbol, fir, deferredReturnTypeCalculation, returnType ->
|
) { symbol, fir, deferredReturnTypeCalculation, returnType ->
|
||||||
FirFakeOverrideGenerator.createCopyForFirProperty(
|
FirFakeOverrideGenerator.createCopyForFirProperty(
|
||||||
@@ -380,10 +399,12 @@ class FirTypeIntersectionScopeContext(
|
|||||||
overrides: Collection<FirCallableSymbol<*>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
newModality: Modality?,
|
newModality: Modality?,
|
||||||
newVisibility: Visibility,
|
newVisibility: Visibility,
|
||||||
|
containsMultipleNonSubsumed: Boolean,
|
||||||
): FirFieldSymbol {
|
): FirFieldSymbol {
|
||||||
return createIntersectionOverrideVariable<FirFieldSymbol, _>(
|
return createIntersectionOverrideVariable<FirFieldSymbol, _>(
|
||||||
mostSpecific,
|
mostSpecific,
|
||||||
overrides,
|
overrides,
|
||||||
|
containsMultipleNonSubsumed,
|
||||||
::FirIntersectionOverrideFieldSymbol
|
::FirIntersectionOverrideFieldSymbol
|
||||||
) { symbol, fir, deferredReturnTypeCalculation, returnType ->
|
) { symbol, fir, deferredReturnTypeCalculation, returnType ->
|
||||||
FirFakeOverrideGenerator.createCopyForFirField(
|
FirFakeOverrideGenerator.createCopyForFirField(
|
||||||
@@ -404,13 +425,14 @@ class FirTypeIntersectionScopeContext(
|
|||||||
private inline fun <reified S : FirVariableSymbol<F>, F : FirVariable> createIntersectionOverrideVariable(
|
private inline fun <reified S : FirVariableSymbol<F>, F : FirVariable> createIntersectionOverrideVariable(
|
||||||
mostSpecific: Collection<FirCallableSymbol<*>>,
|
mostSpecific: Collection<FirCallableSymbol<*>>,
|
||||||
overrides: Collection<FirCallableSymbol<*>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
createIntersectionOverrideSymbol: (CallableId, Collection<FirCallableSymbol<*>>) -> S,
|
containsMultipleNonSubsumed: Boolean,
|
||||||
|
createIntersectionOverrideSymbol: (CallableId, Collection<FirCallableSymbol<*>>, Boolean) -> S,
|
||||||
createCopy: (S, F, deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation?, returnType: ConeKotlinType?) -> F
|
createCopy: (S, F, deferredReturnTypeCalculation: CallableCopyDeferredReturnTypeCalculation?, returnType: ConeKotlinType?) -> F
|
||||||
): S {
|
): S {
|
||||||
val key = mostSpecific.first() as S
|
val key = mostSpecific.first() as S
|
||||||
val keyFir = key.fir
|
val keyFir = key.fir
|
||||||
val callableId = CallableId(dispatchReceiverType.classId ?: keyFir.dispatchReceiverClassLookupTagOrNull()?.classId!!, keyFir.name)
|
val callableId = CallableId(dispatchReceiverType.classId ?: keyFir.dispatchReceiverClassLookupTagOrNull()?.classId!!, keyFir.name)
|
||||||
val newSymbol = createIntersectionOverrideSymbol(callableId, overrides)
|
val newSymbol = createIntersectionOverrideSymbol(callableId, overrides, containsMultipleNonSubsumed)
|
||||||
val deferredReturnTypeCalculation = deferredReturnTypeCalculationOrNull(mostSpecific)
|
val deferredReturnTypeCalculation = deferredReturnTypeCalculationOrNull(mostSpecific)
|
||||||
val newReturnType =
|
val newReturnType =
|
||||||
runIf(!forClassUseSiteScope && mostSpecific.none { (it as FirVariableSymbol<*>).fir.isVar } && deferredReturnTypeCalculation == null) {
|
runIf(!forClassUseSiteScope && mostSpecific.none { (it as FirVariableSymbol<*>).fir.isVar } && deferredReturnTypeCalculation == null) {
|
||||||
@@ -459,7 +481,7 @@ class FirIntersectionOverrideStorage(val session: FirSession) : FirSessionCompon
|
|||||||
val cacheByScope: FirCache<ConeKotlinType, FirIntersectionOverrideCache, Nothing?> =
|
val cacheByScope: FirCache<ConeKotlinType, FirIntersectionOverrideCache, Nothing?> =
|
||||||
cachesFactory.createCache { _ ->
|
cachesFactory.createCache { _ ->
|
||||||
cachesFactory.createCache { _, result ->
|
cachesFactory.createCache { _, result ->
|
||||||
result.context.createIntersectionOverride(result.mostSpecific, result.overriddenMembers)
|
result.context.createIntersectionOverride(result.mostSpecific, result.overriddenMembers, result.containsMultipleNonSubsumed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,11 +47,19 @@ open class FirNamedFunctionSymbol(callableId: CallableId) : FirFunctionSymbol<Fi
|
|||||||
|
|
||||||
interface FirIntersectionCallableSymbol {
|
interface FirIntersectionCallableSymbol {
|
||||||
val intersections: Collection<FirCallableSymbol<*>>
|
val intersections: Collection<FirCallableSymbol<*>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `true` iff a call to `nonSubsumed()` for `intersections` would result into a list with more than one symbol.
|
||||||
|
* Intuitively, `false` means this intersection is, strictly speaking, redundant, but we still created it
|
||||||
|
* as an implementation detail.
|
||||||
|
*/
|
||||||
|
val containsMultipleNonSubsumed: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class FirIntersectionOverrideFunctionSymbol(
|
class FirIntersectionOverrideFunctionSymbol(
|
||||||
callableId: CallableId,
|
callableId: CallableId,
|
||||||
override val intersections: Collection<FirCallableSymbol<*>>,
|
override val intersections: Collection<FirCallableSymbol<*>>,
|
||||||
|
override val containsMultipleNonSubsumed: Boolean,
|
||||||
) : FirNamedFunctionSymbol(callableId), FirIntersectionCallableSymbol
|
) : FirNamedFunctionSymbol(callableId), FirIntersectionCallableSymbol
|
||||||
|
|
||||||
class FirConstructorSymbol(callableId: CallableId) : FirFunctionSymbol<FirConstructor>(callableId), ConstructorSymbolMarker {
|
class FirConstructorSymbol(callableId: CallableId) : FirFunctionSymbol<FirConstructor>(callableId), ConstructorSymbolMarker {
|
||||||
|
|||||||
@@ -72,12 +72,14 @@ open class FirPropertySymbol(callableId: CallableId, ) : FirVariableSymbol<FirPr
|
|||||||
|
|
||||||
class FirIntersectionOverridePropertySymbol(
|
class FirIntersectionOverridePropertySymbol(
|
||||||
callableId: CallableId,
|
callableId: CallableId,
|
||||||
override val intersections: Collection<FirCallableSymbol<*>>
|
override val intersections: Collection<FirCallableSymbol<*>>,
|
||||||
|
override val containsMultipleNonSubsumed: Boolean,
|
||||||
) : FirPropertySymbol(callableId), FirIntersectionCallableSymbol
|
) : FirPropertySymbol(callableId), FirIntersectionCallableSymbol
|
||||||
|
|
||||||
class FirIntersectionOverrideFieldSymbol(
|
class FirIntersectionOverrideFieldSymbol(
|
||||||
callableId: CallableId,
|
callableId: CallableId,
|
||||||
override val intersections: Collection<FirCallableSymbol<*>>
|
override val intersections: Collection<FirCallableSymbol<*>>,
|
||||||
|
override val containsMultipleNonSubsumed: Boolean,
|
||||||
) : FirFieldSymbol(callableId), FirIntersectionCallableSymbol
|
) : FirFieldSymbol(callableId), FirIntersectionCallableSymbol
|
||||||
|
|
||||||
class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol<FirBackingField>(callableId) {
|
class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol<FirBackingField>(callableId) {
|
||||||
|
|||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
// FILE: ColoredTextContainer.java
|
|
||||||
public interface ColoredTextContainer {
|
|
||||||
default void setToolTipText(String text) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: JComponent.java
|
|
||||||
public abstract class JComponent {
|
|
||||||
public void setToolTipText(String text) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: SimpleColoredComponent.java
|
|
||||||
// IDEALLY:
|
|
||||||
// Provides `IO SimpleColoredComponent::setToolTipText`, because inherits
|
|
||||||
// `JComponent::setToolTipText` and `ColoredTextContainer::setToolTipText`,
|
|
||||||
// which don't sumbsume one another, but Java allows picking the class-based one in this case.
|
|
||||||
// REALITY:
|
|
||||||
// Contains an IO for the above. We check if this is green Java via a
|
|
||||||
// modified check that accounts for this case.
|
|
||||||
public class SimpleColoredComponent extends JComponent implements ColoredTextContainer {}
|
|
||||||
|
|
||||||
// FILE: Main.kt
|
|
||||||
|
|
||||||
// Not important, left for the record
|
|
||||||
interface TextFragment : ColoredTextContainer
|
|
||||||
|
|
||||||
// IDEALLY:
|
|
||||||
// Provides `JComponent::setToolTipText`, because inherits
|
|
||||||
// `ColoredTextContainer::setToolTipText` and `IO SimpleColoredComponent::setToolTipText`,
|
|
||||||
// and the latter subsumes the former.
|
|
||||||
// REALITY:
|
|
||||||
// Contains IO between `ColoredTextContainer::setToolTipText` and `IO SimpleColoredComponent::setToolTipText`.
|
|
||||||
// In this case `IO SimpleColoredComponent::setToolTipText` should not be unwrapped, otherwise
|
|
||||||
// we miss `nonSubsumed()` check and since this is a Kotlin class we are not allowed to implicitly choose
|
|
||||||
// between `JComponent::setToolTipText` and `ColoredTextContainer::setToolTipText`.
|
|
||||||
private <!CANNOT_INFER_VISIBILITY!>class TextFragmentImpl<!> : TextFragment, SimpleColoredComponent()
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// FILE: ColoredTextContainer.java
|
// FILE: ColoredTextContainer.java
|
||||||
public interface ColoredTextContainer {
|
public interface ColoredTextContainer {
|
||||||
default void setToolTipText(String text) {}
|
default void setToolTipText(String text) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user