Skip to content

Commit 39ea9f9

Browse files
patrick-dedicationautonomousapps
authored andcommitted
feat: record lambda in binaryClassAccesses
1 parent 682540d commit 39ea9f9

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

src/main/kotlin/com/autonomousapps/internal/asm.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,24 @@ private class MethodAnalyzer(
460460
) {
461461
log { "- MethodAnalyzer#visitInvokeDynamicInsn: $name $descriptor" }
462462
addClass(descriptor, ClassRef.Kind.NOT_ANNOTATION)
463+
464+
// Bootstrap arguments may contain Handle instances pointing to the actual implementation
465+
// method (e.g. a static method reference compiled to INVOKEDYNAMIC). Record each such Handle
466+
// as a MemberAccess so callers appear in binaryClassAccesses.
467+
for (arg in bootstrapMethodArguments) {
468+
if (arg is Handle) {
469+
log { " - MethodAnalyzer#visitInvokeDynamicInsn bootstrap Handle: ${arg.owner}.${arg.name} ${arg.desc}" }
470+
addClass(if (arg.owner.startsWith("[")) arg.owner else "L${arg.owner};", ClassRef.Kind.NOT_ANNOTATION)
471+
val method = MemberAccess.Method(
472+
owner = arg.owner,
473+
name = arg.name,
474+
descriptor = arg.desc,
475+
)
476+
binaryClasses.merge(arg.owner, sortedSetOf(method)) { acc, inc ->
477+
acc.apply { addAll(inc) }
478+
}
479+
}
480+
}
463481
}
464482

465483
override fun visitLocalVariable(
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) 2025. Tony Robalik.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package com.autonomousapps.internal.fixtures;
4+
5+
public class ClassUsedInLambda {
6+
7+
public void someMethod() {
8+
}
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2025. Tony Robalik.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package com.autonomousapps.internal.fixtures;
4+
5+
public class LambdaUsage {
6+
7+
public void run() {
8+
var classUsedInLambda = new ClassUsedInLambda();
9+
Runnable r = classUsedInLambda::someMethod;
10+
r.run();
11+
}
12+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2025. Tony Robalik.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package com.autonomousapps.internal
4+
5+
import com.autonomousapps.internal.asm.ClassReader
6+
import com.autonomousapps.internal.fixtures.LambdaUsage
7+
import com.autonomousapps.model.internal.intermediates.consumer.MemberAccess
8+
import com.google.common.truth.Truth.assertThat
9+
import org.gradle.api.logging.Logging
10+
import org.junit.jupiter.api.Test
11+
12+
class ClassAnalyzerTest {
13+
14+
private val logger = Logging.getLogger(ClassAnalyzerTest::class.java)
15+
16+
@Test fun `records lambda usage in binaryClassAccesses`() {
17+
val classAnalyzer = ClassAnalyzer(logger).also { analyzer ->
18+
ClassReader(LambdaUsage::class.java.name).accept(analyzer, 0)
19+
}
20+
21+
val binaryClassAccesses: Map<String, Set<MemberAccess>> = classAnalyzer.getBinaryClasses()
22+
23+
val methodOwner = "com/autonomousapps/internal/fixtures/ClassUsedInLambda"
24+
assertThat(binaryClassAccesses).containsKey(methodOwner)
25+
assertThat(binaryClassAccesses[methodOwner]).containsExactly(
26+
MemberAccess.Method(
27+
owner = methodOwner,
28+
name = "<init>",
29+
descriptor = "()V",
30+
),
31+
MemberAccess.Method(
32+
owner = methodOwner,
33+
name = "someMethod",
34+
descriptor = "()V",
35+
)
36+
)
37+
}
38+
}

0 commit comments

Comments
 (0)