You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #2155 / #2366. With the receiver-aware weak-member guard, a Scala call recv.m(...) whose receiver is a value (values.get(k), xs.foreach(_.register()), underlying.close()) no longer binds an arbitrary project-wide m by short name. That is the right default, but it also drops the edges where the receiver's type is knowable from the caller's own source — a field, parameter or local with an explicit type annotation, or a constructor call in scope.
Measured on twitter/finagle (ca472de) in #2366: of the 9,149 CALLS edges the guard removes, 2,549 (28%) target a class whose name appears in the caller's file (import, type annotation, new). A sample of those is a mix of correct edges (Memcached.serve → Server.serve, CachingPool.checkout → Service.close, TypeTest.testRow → Row.intOrZero) and coincidences (PushStackServerTest → Stack.exists, RefCountedFactoryTest → FailureFlags.isFlagged). The other 72% target a class the caller file never mentions and are almost certainly noise.
Proposal
Receiver-type inference for Scala, applied before the registry resolves a member call:
Extraction records, per call, the receiver's root identifier (values in values.get(k), underlying in underlying.close()); today only is_method is set.
For the caller's file, build a name → declared type map from the shapes the grammar exposes directly: val x: T = …, var x: T, constructor/method parameters (x: T), val x = new T(...), val x = T(...) / T.apply(...) (companion factory).
When the root identifier has an entry T and T resolves to a class in the graph (through the import map or the same file), resolve m as T.m / T$.m — a new strategy such as receiver_type sitting above suffix_match in confidence. When it does not, the call keeps the current suppressed outcome (no weak short-name fallback).
Out of scope for a first cut: inherited members (T.m declared on a parent), generics (Seq[T]), inferred val x = someCall() types, implicit conversions.
Expected effect
Recovers a subset of the 2,549 "owner mentioned" edges — the ones where the type is written down — without reintroducing the 6,600 where it is not. A before/after on finagle with the same edge-identity comparison as #2366 would show recall regained per strategy and the residual.
Summary
Follow-up to #2155 / #2366. With the receiver-aware weak-member guard, a Scala call
recv.m(...)whose receiver is a value (values.get(k),xs.foreach(_.register()),underlying.close()) no longer binds an arbitrary project-widemby short name. That is the right default, but it also drops the edges where the receiver's type is knowable from the caller's own source — a field, parameter or local with an explicit type annotation, or a constructor call in scope.Measured on
twitter/finagle(ca472de) in #2366: of the 9,149 CALLS edges the guard removes, 2,549 (28%) target a class whose name appears in the caller's file (import, type annotation,new). A sample of those is a mix of correct edges (Memcached.serve → Server.serve,CachingPool.checkout → Service.close,TypeTest.testRow → Row.intOrZero) and coincidences (PushStackServerTest → Stack.exists,RefCountedFactoryTest → FailureFlags.isFlagged). The other 72% target a class the caller file never mentions and are almost certainly noise.Proposal
Receiver-type inference for Scala, applied before the registry resolves a member call:
valuesinvalues.get(k),underlyinginunderlying.close()); today onlyis_methodis set.name → declared typemap from the shapes the grammar exposes directly:val x: T = …,var x: T, constructor/method parameters(x: T),val x = new T(...),val x = T(...)/T.apply(...)(companion factory).TandTresolves to a class in the graph (through the import map or the same file), resolvemasT.m/T$.m— a new strategy such asreceiver_typesitting abovesuffix_matchin confidence. When it does not, the call keeps the current suppressed outcome (no weak short-name fallback).Out of scope for a first cut: inherited members (
T.mdeclared on a parent), generics (Seq[T]), inferredval x = someCall()types, implicit conversions.Expected effect
Recovers a subset of the 2,549 "owner mentioned" edges — the ones where the type is written down — without reintroducing the 6,600 where it is not. A before/after on finagle with the same edge-identity comparison as #2366 would show recall regained per strategy and the residual.
Related
T$.mfor object members)Tfrom the caller's imports)