The last two deferred callback-registration shapes from #756, each scoped
to positions where the reference is trustworthy:
PHP — a string is a callable ONLY in a known callable position:
- string args of core HOFs (usort, array_map, array_filter,
call_user_func*, preg_replace_callback, spl_autoload_register,
set_error_handler, … — PHP_CALLABLE_HOFS): ungated (PHP globals are
referenced cross-file without imports) + resolution unique-or-drop,
function-kind only ('Cls::m' strings resolve qualified)
- array callables anywhere in call args: [$this, 'method'] routes through
the class-scoped this. resolver (parents included); [Foo::class,
'method'] resolves qualified
- strings to arbitrary functions: deliberately nothing
Ruby — hook-DSL symbols name a method of the enclosing class:
(skip_)?(before|after|around)_* / validate / set_callback /
helper_method / rescue_from(with:) symbols → class-scoped this.<sym>,
riding the supertype pass so `before_action :authenticate` in a
controller resolves to ApplicationController's method. `validates`
(plural) excluded — its symbols name ATTRIBUTES. Class-body-level hooks
attribute to the CLASS node (the scoped resolvers now accept class-like
from-nodes).
Also hardened while validating: the this.X supertype pass is now
NODE-anchored — file-anchored class node → implements/extends edge targets
→ contains-anchored member lookup — replacing the name-keyed
getSupertypes walk, which unioned every same-named class's parents (rails
has a dozen `Engine`s) and produced a cross-class wrong edge.
A/B vs main: WordPress +556 (14/14 sampled genuine — [$this,'m'] wiring,
array_map('absint',…), sodium polyfill call_user_func_array dispatch);
rails/rails +385 after the node-anchored fix (16/16 sampled genuine, incl.
inherited hooks across real extends edges); controls byte-stable
(excalidraw 0-delta, redis identical, typeorm keeps its +4 inherited
getters). The only calls-edge deltas anywhere are pre-existing
minified-bundle resolution jitter (wp-tinymce.js single-letter symbols).
Full suite 1391 passed. EXTRACTION_VERSION 21 → 22 (re-index to benefit).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>