[FIR] Support diagnostic QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
|||||||
|
interface IBase<T> {
|
||||||
|
fun foo() {}
|
||||||
|
fun bar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias AliasedIBase1 = IBase<String>
|
||||||
|
typealias AliasedIBase = AliasedIBase1
|
||||||
|
|
||||||
|
interface IDerived<T> : IBase<T> {
|
||||||
|
override fun foo() {}
|
||||||
|
fun qux() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test : IDerived<String>, IBase<String> {
|
||||||
|
fun test() {
|
||||||
|
super<<!QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE!>IBase<!>>.foo()
|
||||||
|
super<<!QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE!>IBase<!>>.bar()
|
||||||
|
super<IDerived>.foo()
|
||||||
|
super<IDerived>.bar()
|
||||||
|
super<IDerived>.qux()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test2 : IDerived<String>, AliasedIBase {
|
||||||
|
fun test() {
|
||||||
|
super<<!QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE!>IBase<!>>.foo()
|
||||||
|
super<<!QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE!>IBase<!>>.bar()
|
||||||
|
super<<!QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE!>AliasedIBase<!>>.foo()
|
||||||
|
super<<!QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE!>AliasedIBase<!>>.bar()
|
||||||
|
super<IDerived>.foo()
|
||||||
|
super<IDerived>.bar()
|
||||||
|
super<IDerived>.qux()
|
||||||
|
}
|
||||||
|
}
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
FILE: qualifiedSupertypeExtendedByOtherSupertype.kt
|
||||||
|
public abstract interface IBase<T> : R|kotlin/Any| {
|
||||||
|
public open fun foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public open fun bar(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final typealias AliasedIBase1 = R|IBase<kotlin/String>|
|
||||||
|
public final typealias AliasedIBase = R|AliasedIBase1|
|
||||||
|
public abstract interface IDerived<T> : R|IBase<T>| {
|
||||||
|
public open override fun foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public open fun qux(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Test : R|IDerived<kotlin/String>|, R|IBase<kotlin/String>| {
|
||||||
|
public constructor(): R|Test| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
super<R|IBase|>.R|/IBase.foo|()
|
||||||
|
super<R|IBase|>.R|/IBase.bar|()
|
||||||
|
super<R|IDerived|>.R|/IDerived.foo|()
|
||||||
|
super<R|IDerived|>.R|/IBase.bar|()
|
||||||
|
super<R|IDerived|>.R|/IDerived.qux|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Test2 : R|IDerived<kotlin/String>|, R|AliasedIBase| {
|
||||||
|
public constructor(): R|Test2| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
super<R|IBase|>.R|/IBase.foo|()
|
||||||
|
super<R|IBase|>.R|/IBase.bar|()
|
||||||
|
super<R|AliasedIBase|>.R|/IBase.foo|()
|
||||||
|
super<R|AliasedIBase|>.R|/IBase.bar|()
|
||||||
|
super<R|IDerived|>.R|/IDerived.foo|()
|
||||||
|
super<R|IDerived|>.R|/IBase.bar|()
|
||||||
|
super<R|IDerived|>.R|/IDerived.qux|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Generated
+5
@@ -826,6 +826,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifiedSupertypeExtendedByOtherSupertype.kt")
|
||||||
|
public void testQualifiedSupertypeExtendedByOtherSupertype() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("redundantModifier.kt")
|
@TestMetadata("redundantModifier.kt")
|
||||||
public void testRedundantModifier() throws Exception {
|
public void testRedundantModifier() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/redundantModifier.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/redundantModifier.kt");
|
||||||
|
|||||||
+5
@@ -826,6 +826,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("qualifiedSupertypeExtendedByOtherSupertype.kt")
|
||||||
|
public void testQualifiedSupertypeExtendedByOtherSupertype() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("redundantModifier.kt")
|
@TestMetadata("redundantModifier.kt")
|
||||||
public void testRedundantModifier() throws Exception {
|
public void testRedundantModifier() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/redundantModifier.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/redundantModifier.kt");
|
||||||
|
|||||||
+56
-10
@@ -9,9 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
@@ -34,7 +32,9 @@ fun FirClass<*>.isSuperclassOf(other: FirClass<*>): Boolean {
|
|||||||
*/
|
*/
|
||||||
fun FirClass<*>.isSuperclassOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
|
fun FirClass<*>.isSuperclassOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
|
||||||
for (it in other.superTypeRefs) {
|
for (it in other.superTypeRefs) {
|
||||||
val that = it.firClassLike(session) as? FirClass<*>
|
val that = it.firClassLike(session)
|
||||||
|
?.followAllAlias(session)
|
||||||
|
?.safeAs<FirClass<*>>()
|
||||||
?: continue
|
?: continue
|
||||||
|
|
||||||
if (that in exclude) {
|
if (that in exclude) {
|
||||||
@@ -58,7 +58,7 @@ fun FirClass<*>.isSuperclassOf(other: FirClass<*>): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this is a superclass of other.
|
* Returns true if this is a supertype of other.
|
||||||
*/
|
*/
|
||||||
fun FirClass<*>.isSupertypeOf(other: FirClass<*>): Boolean {
|
fun FirClass<*>.isSupertypeOf(other: FirClass<*>): Boolean {
|
||||||
/**
|
/**
|
||||||
@@ -66,20 +66,22 @@ fun FirClass<*>.isSupertypeOf(other: FirClass<*>): Boolean {
|
|||||||
*/
|
*/
|
||||||
fun FirClass<*>.isSupertypeOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
|
fun FirClass<*>.isSupertypeOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
|
||||||
for (it in other.superTypeRefs) {
|
for (it in other.superTypeRefs) {
|
||||||
val that = it.firClassLike(session) as? FirClass<*>
|
val candidate = it.firClassLike(session)
|
||||||
|
?.followAllAlias(session)
|
||||||
|
?.safeAs<FirClass<*>>()
|
||||||
?: continue
|
?: continue
|
||||||
|
|
||||||
if (that in exclude) {
|
if (candidate in exclude) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
exclude.add(that)
|
exclude.add(candidate)
|
||||||
|
|
||||||
if (that == this) {
|
if (candidate == this) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isSupertypeOf(that, exclude)) {
|
if (this.isSupertypeOf(candidate, exclude)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,3 +141,47 @@ fun FirSymbolOwner<*>.getContainingClass(context: CheckerContext): FirClassLikeD
|
|||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the FirClassLikeDeclaration the type alias is pointing
|
||||||
|
* to provided `this` is a FirTypeAlias. Returns this otherwise.
|
||||||
|
*/
|
||||||
|
fun FirClassLikeDeclaration<*>.followAlias(session: FirSession): FirClassLikeDeclaration<*>? {
|
||||||
|
return this.safeAs<FirTypeAlias>()
|
||||||
|
?.expandedTypeRef
|
||||||
|
?.firClassLike(session)
|
||||||
|
?: return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the FirClassLikeDeclaration that the
|
||||||
|
* sequence of FirTypeAlias'es points to starting
|
||||||
|
* with `this`. Or null if something goes wrong.
|
||||||
|
*/
|
||||||
|
fun FirClassLikeDeclaration<*>.followAllAlias(session: FirSession): FirClassLikeDeclaration<*>? {
|
||||||
|
var it: FirClassLikeDeclaration<*>? = this
|
||||||
|
|
||||||
|
while (it is FirTypeAlias) {
|
||||||
|
it = it.expandedTypeRef.firClassLike(session)
|
||||||
|
}
|
||||||
|
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the closest to the end of context.containingDeclarations
|
||||||
|
* item like FirRegularClass or FirAnonymousObject
|
||||||
|
* or null if no such item could be found.
|
||||||
|
*/
|
||||||
|
fun CheckerContext.findClosestClassOrObject(): FirClass<*>? {
|
||||||
|
for (it in containingDeclarations.reversed()) {
|
||||||
|
if (
|
||||||
|
it is FirRegularClass ||
|
||||||
|
it is FirAnonymousObject
|
||||||
|
) {
|
||||||
|
return it as FirClass<*>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -14,7 +14,8 @@ object CallCheckers {
|
|||||||
FirSuperNotAvailableChecker,
|
FirSuperNotAvailableChecker,
|
||||||
FirNotASupertypeChecker,
|
FirNotASupertypeChecker,
|
||||||
FirSuperclassNotAccessibleFromInterfaceChecker,
|
FirSuperclassNotAccessibleFromInterfaceChecker,
|
||||||
FirAbstractSuperCallChecker
|
FirAbstractSuperCallChecker,
|
||||||
|
FirQualifiedSupertypeExtendedByOtherSupertypeChecker,
|
||||||
) + EXPRESSIONS
|
) + EXPRESSIONS
|
||||||
|
|
||||||
val FUNCTION_CALLS: List<FirFunctionCallChecker> = listOf<FirFunctionCallChecker>(
|
val FUNCTION_CALLS: List<FirFunctionCallChecker> = listOf<FirFunctionCallChecker>(
|
||||||
|
|||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.analysis.checkers.call
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.followAllAlias
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccessChecker() {
|
||||||
|
override fun check(functionCall: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
// require to be called over a super reference
|
||||||
|
val superReference = functionCall.calleeReference.safeAs<FirSuperReference>()
|
||||||
|
?: return
|
||||||
|
|
||||||
|
val explicitType = superReference.superTypeRef.safeAs<FirResolvedTypeRef>()
|
||||||
|
?.firClassLike(context.session)
|
||||||
|
?.followAllAlias(context.session).safeAs<FirClass<*>>()
|
||||||
|
?: return
|
||||||
|
|
||||||
|
val surroundingType = context.findClosestClassOrObject()
|
||||||
|
?: return
|
||||||
|
|
||||||
|
// how many supertypes of `surroundingType`
|
||||||
|
// have `explicitType` as their supertype or
|
||||||
|
// equal to it
|
||||||
|
var count = 0
|
||||||
|
|
||||||
|
for (it in surroundingType.superTypeRefs) {
|
||||||
|
val that = it.firClassLike(context.session)
|
||||||
|
?.followAllAlias(context.session).safeAs<FirClass<*>>()
|
||||||
|
?: continue
|
||||||
|
|
||||||
|
if (explicitType == that || explicitType.isSupertypeOf(that)) {
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
if (count >= 2) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count >= 2) {
|
||||||
|
reporter.report(superReference.superTypeRef.source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DiagnosticReporter.report(source: FirSourceElement?) {
|
||||||
|
source?.let {
|
||||||
|
report(FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE.on(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@ object FirErrors {
|
|||||||
val NOT_A_SUPERTYPE by error0<FirSourceElement, PsiElement>()
|
val NOT_A_SUPERTYPE by error0<FirSourceElement, PsiElement>()
|
||||||
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0<FirSourceElement, PsiElement>()
|
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0<FirSourceElement, PsiElement>()
|
||||||
val ABSTRACT_SUPER_CALL by error0<FirSourceElement, PsiElement>()
|
val ABSTRACT_SUPER_CALL by error0<FirSourceElement, PsiElement>()
|
||||||
|
val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error0<FirSourceElement, PsiElement>()
|
||||||
|
|
||||||
val INAPPLICABLE_INFIX_MODIFIER by existing<FirSourceElement, PsiElement, String>(Errors.INAPPLICABLE_INFIX_MODIFIER)
|
val INAPPLICABLE_INFIX_MODIFIER by existing<FirSourceElement, PsiElement, String>(Errors.INAPPLICABLE_INFIX_MODIFIER)
|
||||||
val CONSTRUCTOR_IN_OBJECT by existing<FirSourceElement, KtDeclaration>(Errors.CONSTRUCTOR_IN_OBJECT)
|
val CONSTRUCTOR_IN_OBJECT by existing<FirSourceElement, KtDeclaration>(Errors.CONSTRUCTOR_IN_OBJECT)
|
||||||
|
|||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
interface IBase<T> {
|
|
||||||
fun foo() {}
|
|
||||||
fun bar() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IDerived<T> : IBase<T> {
|
|
||||||
override fun foo() {}
|
|
||||||
fun qux() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Test : IDerived<String>, IBase<String> {
|
|
||||||
fun test() {
|
|
||||||
super<IBase>.foo()
|
|
||||||
super<IBase>.bar()
|
|
||||||
super<IDerived>.foo()
|
|
||||||
super<IDerived>.bar()
|
|
||||||
super<IDerived>.qux()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface IBase<T> {
|
interface IBase<T> {
|
||||||
fun foo() {}
|
fun foo() {}
|
||||||
fun bar() {}
|
fun bar() {}
|
||||||
|
|||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
interface IBase {
|
|
||||||
fun foo() {}
|
|
||||||
fun bar() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IDerived1 : IBase {
|
|
||||||
override fun foo() {}
|
|
||||||
fun qux() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IDerived2 : IBase {
|
|
||||||
override fun foo() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Test : IDerived1, IBase, IDerived2 {
|
|
||||||
override fun foo() {}
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
super<IBase>.foo()
|
|
||||||
super<IBase>.bar()
|
|
||||||
|
|
||||||
super<IDerived1>.foo()
|
|
||||||
super<IDerived1>.bar()
|
|
||||||
super<IDerived1>.qux()
|
|
||||||
|
|
||||||
super<IDerived2>.foo()
|
|
||||||
super<IDerived2>.bar()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface IBase {
|
interface IBase {
|
||||||
fun foo() {}
|
fun foo() {}
|
||||||
fun bar() {}
|
fun bar() {}
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,7 @@ class TestSuperForBase : B() {
|
|||||||
typealias MyBase = B
|
typealias MyBase = B
|
||||||
|
|
||||||
override fun foo() {
|
override fun foo() {
|
||||||
<!NOT_A_SUPERTYPE!>super<Base><!>.foo()
|
super<Base>.foo()
|
||||||
super<B>.foo()
|
super<B>.foo()
|
||||||
super<MyBase>.<!UNRESOLVED_REFERENCE!>foo<!>()
|
super<MyBase>.<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
super<U>.foo()
|
super<U>.foo()
|
||||||
@@ -32,7 +32,7 @@ class TestSuperForGenericBase<T> : GB<T>() {
|
|||||||
typealias MyBaseInt = GB<Int>
|
typealias MyBaseInt = GB<Int>
|
||||||
|
|
||||||
override fun foo() {
|
override fun foo() {
|
||||||
<!NOT_A_SUPERTYPE!>super<GenericBase><!>.foo()
|
super<GenericBase>.foo()
|
||||||
super<GB>.foo()
|
super<GB>.foo()
|
||||||
super<MyBase>.<!UNRESOLVED_REFERENCE!>foo<!>()
|
super<MyBase>.<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
super<MyBaseInt>.<!UNRESOLVED_REFERENCE!>foo<!>() // Type arguments don't matter here
|
super<MyBaseInt>.<!UNRESOLVED_REFERENCE!>foo<!>() // Type arguments don't matter here
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ open class Bar2 : Bar() {
|
|||||||
class ManySupers: Foo2(), B {
|
class ManySupers: Foo2(), B {
|
||||||
fun foo() {
|
fun foo() {
|
||||||
super<Foo2>.test()
|
super<Foo2>.test()
|
||||||
super<B>.test()
|
super<<!QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE!>B<!>>.test()
|
||||||
super.test()
|
super.test()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user