Class CoverageDisplayName
Three cases are handled:
- Synthetic methods (
_main,_call,i_init,c_init, etc.) — show the enclosing scope name. This makes a program's_mainrender as the program name, a dynamic function's_callrender as the dynamic function's name, and so on. - Regular methods/operators on an aggregate (class, trait,
component, record, service) — prefix the method name with the aggregate
name. Renders as
Newt.move,ASimpleClass.aCheck,Walker.?. This distinguishes methods from module-level free functions in coverage report listings. - Module-level free functions — show the bare function name with no prefix.
Used by every IR generator that registers function entries with
CoverageProbePlacer: OperationDfnGenerator,
AggregateDfnGenerator, ServiceDfnGenerator,
TextDfnGenerator.
-
Method Summary
Modifier and TypeMethodDescriptionstatic StringResolve the display name for a function/method symbol.static StringidentityForSymbol(ISymbol operationSymbol) THE join key for a construct — the display name minus its one cosmetic exception.static StringsourceQualifiedName(ISymbol operationSymbol) THE fully-qualified name to use as a coverage/profiling IDENTITY for a callable — stable across every parameterisation of a generic.
-
Method Details
-
forSymbol
-
identityForSymbol
THE join key for a construct — the display name minus its one cosmetic exception.Use this whenever a construct must be MATCHED against data gathered elsewhere (input variety, complexity, any per-construct report); use
forSymbol(ISymbol)only to show a human a name. They differ for exactly one shape: a constructor renders bare asCounterfor readability, but every other producer names itCounter.Counter, so joining on the display form made every constructor silently miss its row.Deliberately NOT
ISymbol.getFullyQualifiedName(), which is a different thing again: for a method it yieldsmodule::classify, dropping the enclosing type, and for a free function it yields the syntheticmodule::_call. Neither can be joined on.- Parameters:
operationSymbol- the symbol whose identity is needed; must not be null- Returns:
Aggregate.memberfor aggregate members (constructors included), else the bare name
-
sourceQualifiedName
THE fully-qualified name to use as a coverage/profiling IDENTITY for a callable — stable across every parameterisation of a generic.Why this exists (defect D11). EK9 monomorphises, so
Holder of StringandHolder of Integerare separate aggregates with mangled names. A METHOD'sgetFullyQualifiedName()does not carry its owning type, so two parameterisations already agree — but a CONSTRUCTOR's name IS its type's name, which is the mangled one, so the two disagree and one source constructor acquires an identity per parameterisation. Probe and function ids hash this name, so the effect is a denominator counting the same source constructor N times.Coverage is deliberately TYPE-BLIND: it answers "did this source line ever execute", and EK9 has no
instanceofor casts, so a generic body cannot branch on its type argument. Type breadth is the separate input-variety axis's job. Hence the generic's own name, NOTgetFriendlyName(), which would append the type arguments and split the identity again.🔑 Resolved from the SYMBOL (
PossibleGenericSymbol.getGenericType()), never by un-mangling the string.FriendlyInternalNameis the display-only transform and says so: it reduces every dynamic class and function tocls/fn, which would make two dynamic constructs in one module collide as one identity.- Parameters:
operationSymbol- the symbol whose identity is needed; must not be null- Returns:
- the fully-qualified name, with a parameterised type's constructor named for its generic
-