Skip to content

Commit e80254b

Browse files
committed
Fix generated implementation of an inherited single abstract method
For example, UnaryOperator<T> extends Function<T, T> without overriding / defining its own `apply` method.
1 parent f918b2e commit e80254b

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
@@ -654,9 +654,13 @@ open class KotlinFileExtractor(
654654
}
655655
}
656656

657-
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>? {
658-
if (isFake(f)) return null
657+
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) =
658+
if (isFake(f))
659+
null
660+
else
661+
extractNonFakeFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, idOverride, locOverride)
659662

663+
fun extractNonFakeFunction(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> {
660664
with("function", f) {
661665
DeclarationStackAdjuster(f).use {
662666

@@ -3997,7 +4001,15 @@ open class KotlinFileExtractor(
39974001

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

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

40024014
//body
40034015
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)