Skip to content

feat(dynamic-calls): add reflection to FLAG_ONLY_KINDS when target cannot be resolved #1652

@carlos-alm

Description

@carlos-alm

Problem

Currently, FLAG_ONLY_KINDS only covers eval, computed-key, and unresolved-dynamic. reflection is NOT included, which means:

  • Reflect.apply(fn, ctx, args) where fn isn't defined in the codebase → silently dropped (no sink edge, no edge at all)
  • clazz.getMethod("name") where name can't be resolved → silently dropped
  • ::greet where greet doesn't exist in the codebase → silently dropped

This is the same silent-drop problem Phase 0 solved for eval/computed-key.

Proposed fix

Option A: Add reflection to FLAG_ONLY_KINDS — but this would create sink edges for ALL reflection patterns that fail to resolve, including normal .call/.apply on well-typed objects. This might be too broad.

Option B: Add a sub-kind for reflection patterns that ALWAYS need a sink edge (forced-reflection) vs those that should only emit one if they fail to resolve.

Option C: Only add reflection to FLAG_ONLY_KINDS when it comes from explicit API patterns (Reflect.*, getMethod, ::ref) that are always dynamic, not from .call/.apply/.bind which often resolves statically.

Impact

Currently affects: JVM getMethod unresolved cases, Reflect.* patterns where target fn not found.
Severity: Medium — the call is detected but invisible when unresolved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions