[FIR] Support several super-related diagnostics

This commit is contained in:
Nick
2020-03-27 03:18:03 +03:00
committed by Mikhail Glukhikh
parent 5570a5fe74
commit b38d30bab0
23 changed files with 456 additions and 27 deletions
@@ -0,0 +1,10 @@
class A {
fun f() {}
}
class B : A {
fun g() {
<!NOT_A_SUPERTYPE!>super<String><!>.<!UNRESOLVED_REFERENCE!>f<!>()
super<A>.f()
}
}
@@ -0,0 +1,21 @@
FILE: notASupertype.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun f(): R|kotlin/Unit| {
}
}
public final class B : R|A| {
public constructor(): R|B| {
super<R|kotlin/Any|>()
}
public final fun g(): R|kotlin/Unit| {
super<R|kotlin/String|>.<Unresolved name: f>#()
super<R|A|>.R|/A.f|()
}
}
@@ -0,0 +1,20 @@
fun String.f() {
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super@f<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
}
fun foo() {
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!SUPER_NOT_AVAILABLE!>super<Nothing><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
class A {
fun act() {
<!UNRESOLVED_REFERENCE!>println<!>("Test")
}
fun String.fact() {
<!UNRESOLVED_REFERENCE!>println<!>("Fest")
}
}
@@ -0,0 +1,24 @@
FILE: superNotAvailable.kt
public final fun R|kotlin/String|.f(): R|kotlin/Unit| {
super<<ERROR TYPE REF: No super type>>.<Unresolved name: compareTo>#(String())
super<<ERROR TYPE REF: No super type>>.<Unresolved name: compareTo>#(String())
}
public final fun foo(): R|kotlin/Unit| {
super<<ERROR TYPE REF: No super type>>
super<<ERROR TYPE REF: No super type>>.<Unresolved name: foo>#()
super<R|kotlin/Nothing|>.<Unresolved name: foo>#()
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun act(): R|kotlin/Unit| {
<Unresolved name: println>#(String(Test))
}
public final fun R|kotlin/String|.fact(): R|kotlin/Unit| {
<Unresolved name: println>#(String(Fest))
}
}
@@ -0,0 +1,9 @@
open class A {
open fun foo() {}
}
interface ATrait : A {
override fun foo() {
<!SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE!>super<A><!>.foo()
}
}
@@ -0,0 +1,16 @@
FILE: superclassNotAccessibleFromInterface.kt
public open class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public open fun foo(): R|kotlin/Unit| {
}
}
public abstract interface ATrait : R|A| {
public open override fun foo(): R|kotlin/Unit| {
super<R|A|>.R|/A.foo|()
}
}
@@ -750,6 +750,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/infixFunctions.kt");
}
@TestMetadata("notASupertype.kt")
public void testNotASupertype() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
}
@TestMetadata("redundantModifier.kt")
public void testRedundantModifier() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/redundantModifier.kt");
@@ -764,6 +769,16 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
public void testSuperIsNotAnExpression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superIsNotAnExpression.kt");
}
@TestMetadata("superNotAvailable.kt")
public void testSuperNotAvailable() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superNotAvailable.kt");
}
@TestMetadata("superclassNotAccessibleFromInterface.kt")
public void testSuperclassNotAccessibleFromInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superclassNotAccessibleFromInterface.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/expresssions")
@@ -750,6 +750,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/infixFunctions.kt");
}
@TestMetadata("notASupertype.kt")
public void testNotASupertype() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
}
@TestMetadata("redundantModifier.kt")
public void testRedundantModifier() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/redundantModifier.kt");
@@ -764,6 +769,16 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
public void testSuperIsNotAnExpression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superIsNotAnExpression.kt");
}
@TestMetadata("superNotAvailable.kt")
public void testSuperNotAvailable() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superNotAvailable.kt");
}
@TestMetadata("superclassNotAccessibleFromInterface.kt")
public void testSuperclassNotAccessibleFromInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superclassNotAccessibleFromInterface.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/expresssions")
@@ -0,0 +1,108 @@
/*
* 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
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
/**
* Returns true if this is a superclass of other.
*/
fun FirClass<*>.isSuperclassOf(other: FirClass<*>): Boolean {
/**
* Hides additional parameters.
*/
fun FirClass<*>.isSuperclassOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
for (it in other.superTypeRefs) {
val that = it.firClassLike(session) as? FirClass<*>
?: continue
if (that in exclude) {
continue
}
if (that.classKind == ClassKind.CLASS) {
if (that == this) {
return true
}
exclude.add(that)
return this.isSuperclassOf(that, exclude)
}
}
return false
}
return isSuperclassOf(other, mutableSetOf())
}
/**
* Returns true if this is a superclass of other.
*/
fun FirClass<*>.isSupertypeOf(other: FirClass<*>): Boolean {
/**
* Hides additional parameters.
*/
fun FirClass<*>.isSupertypeOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
for (it in other.superTypeRefs) {
val that = it.firClassLike(session) as? FirClass<*>
?: continue
if (that in exclude) {
continue
}
exclude.add(that)
if (that == this) {
return true
}
if (this.isSupertypeOf(that, exclude)) {
return true
}
}
return false
}
return isSupertypeOf(other, mutableSetOf())
}
/**
* Returns the FirRegularClass associated with this
* or null of something goes wrong.
*/
fun ConeClassLikeType.toRegularClass(session: FirSession): FirRegularClass? {
return lookupTag.toSymbol(session).safeAs<FirRegularClassSymbol>()?.fir
}
/**
* Returns the FirRegularClass associated with this
* or null of something goes wrong.
*/
fun ConeKotlinType.toRegularClass(session: FirSession): FirRegularClass? {
return safeAs<ConeClassLikeType>()?.toRegularClass(session)
}
/**
* Returns the FirRegularClass associated with this
* or null of something goes wrong.
*/
fun FirTypeRef.toRegularClass(session: FirSession): FirRegularClass? {
return safeAs<FirResolvedTypeRef>()?.type?.toRegularClass(session)
}
@@ -9,6 +9,14 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
object CallCheckers {
val EXPRESSIONS: List<FirExpressionChecker<FirExpression>> = listOf()
val QUALIFIED_ACCESS: List<FirQualifiedAccessChecker> = listOf<FirQualifiedAccessChecker>() + EXPRESSIONS
val FUNCTION_CALLS: List<FirFunctionCallChecker> = listOf<FirFunctionCallChecker>() + QUALIFIED_ACCESS
val QUALIFIED_ACCESS: List<FirQualifiedAccessChecker> = listOf(
FirSuperNotAvailableChecker,
FirNotASupertypeChecker,
FirSuperclassNotAccessibleFromInterfaceChecker
) + EXPRESSIONS
val FUNCTION_CALLS: List<FirFunctionCallChecker> = listOf<FirFunctionCallChecker>(
) + QUALIFIED_ACCESS
}
@@ -0,0 +1,58 @@
/*
* 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.isSupertypeOf
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirNotASupertypeChecker : FirQualifiedAccessChecker() {
override fun check(functionCall: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val surrounding = context.findClosestClass() ?: return
val targetClass = functionCall.calleeReference.safeAs<FirSuperReference>()
?.superTypeRef
?.toRegularClass(context.session)
?: return
if (!targetClass.isSupertypeOf(surrounding)) {
reporter.report(functionCall.source)
}
}
/**
* Returns the closest to the end of context.containingDeclarations
* item like FirRegularClass or FirAnonymousObject
* or null if no such item could be found.
*/
private fun CheckerContext.findClosestClass(): FirClass<*>? {
for (it in containingDeclarations.reversed()) {
if (
it is FirRegularClass ||
it is FirAnonymousObject
) {
return it as FirClass<*>
}
}
return null
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let {
report(FirErrors.NOT_A_SUPERTYPE.on(it))
}
}
}
@@ -0,0 +1,33 @@
/*
* 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.KtNodeTypes.*
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
object FirSuperNotAvailableChecker : FirQualifiedAccessChecker() {
override fun check(functionCall: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
if (functionCall.source?.elementType == SUPER_EXPRESSION) {
val isInsideClass = context.containingDeclarations.any {
it.source?.elementType == CLASS || it.source?.elementType == OBJECT_LITERAL
}
if (!isInsideClass) {
reporter.report(functionCall.source)
}
}
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let {
report(FirErrors.SUPER_NOT_AVAILABLE.on(it))
}
}
}
@@ -0,0 +1,62 @@
/*
* 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.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isSuperclassOf
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
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.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessChecker() {
override fun check(functionCall: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val closestClass = context.findClosest<FirRegularClass>() ?: return
if (closestClass.classKind == ClassKind.INTERFACE) {
val origin = getClassLikeDeclaration(functionCall, context)
?.symbol.safeAs<FirRegularClassSymbol>()
?.fir
?: return
if (origin.source != null && origin.isSuperclassOf(closestClass)) {
reporter.report(functionCall.explicitReceiver?.source)
}
}
}
/**
* Returns the ClassLikeDeclaration where the function has been defined
* or null if no proper declaration has been found.
*/
private fun getClassLikeDeclaration(functionCall: FirQualifiedAccessExpression, context: CheckerContext): FirClassLikeDeclaration<*>? {
val classId = functionCall.calleeReference.safeAs<FirResolvedNamedReference>()
?.resolvedSymbol.safeAs<FirNamedFunctionSymbol>()
?.callableId
?.classId
?: return null
if (!classId.isLocal) {
return context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.fir
}
return null
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let {
report(FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE.on(it))
}
}
}
@@ -7,36 +7,58 @@ package org.jetbrains.kotlin.fir.analysis.checkers.context
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
import org.jetbrains.kotlin.name.Name
abstract class CheckerContext {
abstract val implicitReceiverStack: ImplicitReceiverStack
abstract val containingDeclarations: List<FirDeclaration>
abstract val sessionHolder: SessionHolder
val session: FirSession
get() = sessionHolder.session
/**
* Returns the closest to the end of context.containingDeclarations
* T instance or null if no such item could be found.
*/
inline fun <reified T : FirDeclaration> findClosest(): T? {
for (it in containingDeclarations.reversed()) {
return it as? T ?: continue
}
return null
}
}
class PersistentCheckerContext(
override val implicitReceiverStack: PersistentImplicitReceiverStack,
override val containingDeclarations: PersistentList<FirDeclaration>
override val implicitReceiverStack: PersistentImplicitReceiverStack = PersistentImplicitReceiverStack(),
override val containingDeclarations: PersistentList<FirDeclaration> = persistentListOf(),
override val sessionHolder: SessionHolder
) : CheckerContext() {
constructor() : this(
constructor(sessionHolder: SessionHolder) : this(
PersistentImplicitReceiverStack(),
persistentListOf()
persistentListOf(),
sessionHolder
)
fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): PersistentCheckerContext {
return PersistentCheckerContext(
implicitReceiverStack.add(name, value),
containingDeclarations
containingDeclarations,
sessionHolder
)
}
fun addDeclaration(declaration: FirDeclaration): PersistentCheckerContext {
return PersistentCheckerContext(
implicitReceiverStack,
containingDeclarations.add(declaration)
containingDeclarations.add(declaration),
sessionHolder
)
}
}
@@ -48,7 +48,8 @@ abstract class AbstractDiagnosticCollector(
private var componentsInitialized = false
private val visitor = Visitor()
private var context = PersistentCheckerContext()
@Suppress("LeakingThis")
private var context = PersistentCheckerContext(this)
fun initializeComponents(vararg components: AbstractDiagnosticCollectorComponent) {
if (componentsInitialized) {
@@ -57,6 +57,10 @@ class DeclarationCheckersDiagnosticComponent(collector: AbstractDiagnosticCollec
runCheck { DeclarationCheckers.DECLARATIONS.check(enumEntry, data, it) }
}
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: CheckerContext) {
runCheck { DeclarationCheckers.DECLARATIONS.check(anonymousObject, data, it) }
}
private fun <D : FirDeclaration> List<FirDeclarationChecker<D>>.check(
declaration: D,
context: CheckerContext,
@@ -37,6 +37,9 @@ object FirErrors {
val VARIABLE_EXPECTED by error0<FirSourceElement, PsiElement>()
val RETURN_NOT_ALLOWED by error0<FirSourceElement, PsiElement>()
val SUPER_IS_NOT_AN_EXPRESSION by error0<FirSourceElement, PsiElement>()
val SUPER_NOT_AVAILABLE by error0<FirSourceElement, PsiElement>()
val NOT_A_SUPERTYPE by error0<FirSourceElement, PsiElement>()
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0<FirSourceElement, PsiElement>()
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)
@@ -19,10 +19,10 @@ class A<E>() : C(), T {
super<C>@A.bar()
super<E>.<!UNRESOLVED_REFERENCE!>bar<!>()
super<E>@A.<!UNRESOLVED_REFERENCE!>bar<!>()
super<Int>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NOT_A_SUPERTYPE!>super<Int><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<<!SYNTAX!><!>>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<() -> Unit>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<Unit>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NOT_A_SUPERTYPE!>super<() -> Unit><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NOT_A_SUPERTYPE!>super<Unit><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<T>@B.foo()
super<C>@B.bar()
}
@@ -30,11 +30,11 @@ class A<E>() : C(), T {
inner class B : T {
fun test() {
super<T>.foo();
super<C>.bar()
super<C>@A.bar()
<!NOT_A_SUPERTYPE!>super<C><!>.bar()
<!NOT_A_SUPERTYPE!>super<C>@A<!>.bar()
super<T>@A.foo()
super<T>@B.foo()
super<C>@B.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NOT_A_SUPERTYPE!>super<C>@B<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
super.foo()
super
super<T>
@@ -5,6 +5,6 @@ open class A {
interface ATrait : A {
override fun foo() {
super<A>.foo()
<!SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE!>super<A><!>.foo()
}
}
@@ -1,4 +1,4 @@
fun String.f() {
<!NO_SUPERTYPE, NO_SUPERTYPE!>super@f<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!NO_SUPERTYPE, NO_SUPERTYPE!>super<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super@f<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
}
@@ -1,5 +1,5 @@
fun foo() {
<!NO_SUPERTYPE, NO_SUPERTYPE!>super<!>
<!NO_SUPERTYPE, NO_SUPERTYPE!>super<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<Nothing>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!SUPER_NOT_AVAILABLE!>super<Nothing><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
@@ -1,11 +1,11 @@
fun any(a : Any) {}
fun notAnExpression() {
any(<!NO_SUPERTYPE, NO_SUPERTYPE!>super<!>) // not an expression
if (<!NO_SUPERTYPE, NO_SUPERTYPE!>super<!>) {} else {} // not an expression
val x = <!NO_SUPERTYPE, NO_SUPERTYPE, NO_SUPERTYPE!>super<!> // not an expression
any(<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>) // not an expression
if (<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!>) {} else {} // not an expression
val x = <!NO_SUPERTYPE, NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!> // not an expression
when (1) {
<!NO_SUPERTYPE, NO_SUPERTYPE!>super<!> -> 1 // not an expression
<!NO_SUPERTYPE, NO_SUPERTYPE, SUPER_NOT_AVAILABLE!>super<!> -> 1 // not an expression
else -> {}
}
@@ -20,7 +20,7 @@ class TestSuperForBase : B() {
typealias MyBase = B
override fun foo() {
super<Base>.foo()
<!NOT_A_SUPERTYPE!>super<Base><!>.foo()
super<B>.foo()
super<MyBase>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<U>.foo()
@@ -32,7 +32,7 @@ class TestSuperForGenericBase<T> : GB<T>() {
typealias MyBaseInt = GB<Int>
override fun foo() {
super<GenericBase>.foo()
<!NOT_A_SUPERTYPE!>super<GenericBase><!>.foo()
super<GB>.foo()
super<MyBase>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<MyBaseInt>.<!UNRESOLVED_REFERENCE!>foo<!>() // Type arguments don't matter here