Split out of #1595 (report 5 of 9) — filed by @rrodriguesNutrium, credit to them.
KOTLIN_QUERIES["calls"] (kotlin.py:24-30) captures (constructor_invocation). In the tree-sitter Kotlin grammar an annotation with arguments is annotation -> @ + constructor_invocation, so every such annotation is collected as a call from the annotated function:
@Preview(showBackground = true)
@Deprecated("old")
fun Foo() { realCall() }
function_calls for Foo yields Preview (line 3), Deprecated (line 4) and realCall (line 6).
Argument-less annotations (@Composable, @Test) are unaffected — no arguments means no constructor_invocation.
Consequences:
- Phantom
CALLS edges from any function carrying an annotation with arguments. On Android that is a large share of functions: @Preview(...), @Query(...), @Insert(...), @InstallIn(...), @SerialName(...).
- A function whose name matches an annotation's simple name gains spurious inbound callers, which also makes it look alive to
find_dead_code.
analyze call-chain / analyze callers traverse these edges, so the noise is user-visible.
Fix direction (untested, from the reporter): a constructor_invocation whose parent chain includes annotation/modifiers is an annotation, not a call — skipping those should filter them.
Split out of #1595 (report 5 of 9) — filed by @rrodriguesNutrium, credit to them.
KOTLIN_QUERIES["calls"](kotlin.py:24-30) captures(constructor_invocation). In the tree-sitter Kotlin grammar an annotation with arguments isannotation -> @ + constructor_invocation, so every such annotation is collected as a call from the annotated function:function_callsforFooyieldsPreview(line 3),Deprecated(line 4) andrealCall(line 6).Argument-less annotations (
@Composable,@Test) are unaffected — no arguments means noconstructor_invocation.Consequences:
CALLSedges from any function carrying an annotation with arguments. On Android that is a large share of functions:@Preview(...),@Query(...),@Insert(...),@InstallIn(...),@SerialName(...).find_dead_code.analyze call-chain/analyze callerstraverse these edges, so the noise is user-visible.Fix direction (untested, from the reporter): a
constructor_invocationwhose parent chain includesannotation/modifiersis an annotation, not a call — skipping those should filter them.