KT-12156: for the purposes of inline-related diagnostics

treat function declaration as final if it is a member of a final class
This commit is contained in:
Dmitry Petrov
2016-05-19 14:53:56 +03:00
parent 7332032bb6
commit a25ba5baf1
3 changed files with 57 additions and 4 deletions
@@ -98,7 +98,7 @@ object InlineAnalyzerExtension : FunctionAnalyzerExtension.AnalyzerExtension {
}
}
if (functionDescriptor.modality == Modality.FINAL) {
if (functionDescriptor.isEffectivelyFinal()) {
if (overridesAnything) {
trace.report(Errors.OVERRIDE_BY_INLINE.on(function))
}
@@ -108,6 +108,11 @@ object InlineAnalyzerExtension : FunctionAnalyzerExtension.AnalyzerExtension {
trace.report(Errors.DECLARATION_CANT_BE_INLINED.on(function))
}
private fun FunctionDescriptor.isEffectivelyFinal(): Boolean =
modality == Modality.FINAL ||
containingDeclaration.let { containingDeclaration ->
containingDeclaration is ClassDescriptor && containingDeclaration.modality == Modality.FINAL
}
private fun checkHasInlinableAndNullability(
functionDescriptor: FunctionDescriptor,
@@ -8,10 +8,36 @@ interface IBase {
class CDerived : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
class CNested : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!OVERRIDE_BY_INLINE!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
}
val anObject = object : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!OVERRIDE_BY_INLINE!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
}
fun aMethod() {
class CLocal : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!OVERRIDE_BY_INLINE!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
}
}
}
open class COpen : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
open class COpenNested : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
@@ -19,12 +45,12 @@ class CDerived : IBase {
val anObject = object : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
}
fun aMethod() {
class CLocal : IBase {
open class COpenLocal : IBase {
<!OVERRIDE_BY_INLINE!>override inline final fun foo()<!> {}
<!DECLARATION_CANT_BE_INLINED!>override inline fun bar()<!> {}
<!OVERRIDE_BY_INLINE!>override inline final fun <<!REIFIED_TYPE_PARAMETER_IN_OVERRIDE!>reified<!> T> qux(x: T)<!> {}
@@ -22,6 +22,28 @@ public final class CDerived : IBase {
}
}
public open class COpen : IBase {
public constructor COpen()
public final val anObject: IBase
public final fun aMethod(): kotlin.Unit
public open inline override /*1*/ fun bar(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final inline override /*1*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline override /*1*/ fun </*0*/ reified T> qux(/*0*/ x: T): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open class COpenNested : IBase {
public constructor COpenNested()
public open inline override /*1*/ fun bar(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final inline override /*1*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline override /*1*/ fun </*0*/ reified T> qux(/*0*/ x: T): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public interface IBase {
public abstract fun bar(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean