Skip to content

Commit 98ef223

Browse files
authored
Merge pull request github#9213 from smowton/smowton/fix/inherited-single-abstract-method
Kotlin: fix implementation of SAM classes that inherit their abstract method
2 parents 2e1db7d + edb678f commit 98ef223

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -653,9 +653,13 @@ open class KotlinFileExtractor(
653653
}
654654
}
655655

656-
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>? = null, locOverride: Label<DbLocation>? = null): Label<out DbCallable>? {
657-
if (isFake(f)) return null
656+
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>? = null, locOverride: Label<DbLocation>? = null) =
657+
if (isFake(f))
658+
null
659+
else
660+
forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, idOverride, locOverride)
658661

662+
fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>? = null, locOverride: Label<DbLocation>? = null): Label<out DbCallable> {
659663
with("function", f) {
660664
DeclarationStackAdjuster(f).use {
661665

@@ -4034,7 +4038,15 @@ open class KotlinFileExtractor(
40344038

40354039
fun trySub(t: IrType, context: TypeContext) = if (typeSub == null) t else typeSub(t, context, pluginContext)
40364040

4037-
extractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, idOverride = ids.function, locOverride = tw.getLocation(e))
4041+
// Force extraction of this function even if this is a fake override --
4042+
// This happens in the case where a functional interface inherits its only abstract member,
4043+
// which usually we wouldn't extract, but in this case we're effectively using it as a template
4044+
// for the real function we're extracting that will implement this interface, and it serves fine
4045+
// for that purpose. By contrast if we looked through the fake to the underlying abstract method
4046+
// we would need to compose generic type substitutions -- for example, if we're implementing
4047+
// T UnaryOperator<T>.apply(T t) here, we would need to compose substitutions so we can implement
4048+
// the real underlying R Function<T, R>.apply(T t).
4049+
forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, idOverride = ids.function, locOverride = tw.getLocation(e))
40384050

40394051
//body
40404052
val blockId = tw.getFreshIdLabel<DbBlock>()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.kt:0:0:0:0 | TestKt | test.kt:3:1:3:35 | f |
2+
| test.kt:0:0:0:0 | TestKt | test.kt:5:1:9:1 | test |
3+
| test.kt:7:5:7:12 | new Function1<String,String>(...) { ... } | test.kt:7:5:7:12 | invoke |
4+
| test.kt:7:5:7:12 | new UnaryOperator<String>(...) { ... } | test.kt:7:5:7:12 | apply |
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import java.util.function.UnaryOperator
2+
3+
fun f(x: UnaryOperator<String>) { }
4+
5+
fun test() {
6+
7+
f({x -> x})
8+
9+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import java
2+
3+
from ClassOrInterface ci
4+
where ci.fromSource()
5+
select ci, ci.getAMethod()

0 commit comments

Comments
 (0)