Class LockIdentityInference
Object tokens for MutexLock allocation sites, returns the
ISymbol reference as token for field/parameter/capture-rooted
identities, and produces stable string IDs for cross-record / wire-format use.
Used by the LockAnalysisListener (Phase B.1) to assign and propagate
LockIdentityValue entries through the ValueTrackingAnalyzer
state during the AST walk.
Identity discipline: tokens are compared by Java == reference
equality. Two distinct calls to mintAllocationToken(IToken) for different
source locations always produce different tokens, even if the resulting
LockIdentityValues look superficially similar. The
tokenForSymbol(ISymbol) path returns the symbol itself as the token, so all
call sites resolving to the same ISymbol share one conceptual identity.
Caching: mintAllocationToken(IToken) caches per source location, so
revisiting the same MutexLock(...) constructor expression returns the
same Object reference and thus the same conceptual identity. The
cache is per-LockIdentityInference instance, which lives per
function/source pass (or longer if reused across passes).
Stable IDs: stableIdFor(Object, IdentityOrigin) encodes the token into a deterministic
string suitable for foreign-key references in the
LockAnalysis schema and for
JSON output to MCP consumers. The encoding is canonical for a given
token+origin pair within a compilation; it is not stable across compiles or
across workspaces (intentional — the analysis is transient).
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionlockIdentityValueFor(Object token) Wrap a token in aLockIdentityValuefor assignment to the analyzer state viaValueTrackingAnalyzer.recordAssignment.mintAllocationToken(IToken siteLocation) Mint (or return cached) opaque identity token for aMutexLock(...)constructor call at the given source location.resolveParamSymbol(String paramFqn) Resolve the original parameterISymbolfor a placeholder FQN, if one has been registered viatokenForSymbol(ISymbol).stableIdFor(Object token, IdentityOrigin origin) Produce a deterministic string identifier for the given token, suitable for foreign-key references in theLockAnalysisschema and for JSON output to MCP consumers.tokenForSymbol(ISymbol symbol) Return an identity token for a field, parameter, or capture receiver.unwrapCapture(ISymbol symbol, IScopedSymbol enclosingFunction) LiketokenForSymbol(ISymbol)but unwraps one level of dynamic-function capture: if the symbol is one ofenclosingFunction's captured variables, resolve the same-named variable in theCaptureScope's enclosing scope and use that outer symbol's identity instead.
-
Constructor Details
-
LockIdentityInference
public LockIdentityInference()
-
-
Method Details
-
mintAllocationToken
Mint (or return cached) opaque identity token for aMutexLock(...)constructor call at the given source location.Subsequent calls with the same location key return the same Object reference, so multiple analyses of the same call site agree on identity.
- Parameters:
siteLocation- source token of the constructor call expression. Must be non-null.- Returns:
- opaque identity token (always non-null).
-
tokenForSymbol
Return an identity token for a field, parameter, or capture receiver.Parameters mint a
PlaceholderTokenkeyed by the parameter's fully-qualified name. The placeholder is resolved at each call site during inter-procedural propagation (Phase C.2) — the static analogue of "fill the slot when you push the next stack frame." Two placeholders for the same parameter FQN compare equal (structural equality onPlaceholderToken.paramFqn), so propagation and fixpoint iteration see consistent identities across passes.Fields and captures return the
ISymbolreference itself. Per EK9's A.4 freshness constraint a field's symbol is 1:1 with the allocation that initialised it, so the symbol's identity (==) is a safe stand-in for the underlying object identity. Captures similarly preserve the outer symbol's identity (callers should unwrap viaunwrapCapture(ISymbol, IScopedSymbol)before requesting a token).- Parameters:
symbol- the field / parameter / capture symbol. Must be non-null.- Returns:
- a
PlaceholderTokenfor incoming parameters, or the symbol itself for fields and captures.
-
resolveParamSymbol
Resolve the original parameterISymbolfor a placeholder FQN, if one has been registered viatokenForSymbol(ISymbol).Used by consumers that need the parameter's declaration site (name + source token) rather than the alias variable that happened to be in scope when an identity was first resolved at an enter call site.
- Parameters:
paramFqn- fully-qualified parameter name as carried on thePlaceholderToken.- Returns:
- the original parameter symbol, or
nullif no token has been minted for this FQN through this inference instance.
-
unwrapCapture
LiketokenForSymbol(ISymbol)but unwraps one level of dynamic-function capture: if the symbol is one ofenclosingFunction's captured variables, resolve the same-named variable in theCaptureScope's enclosing scope and use that outer symbol's identity instead.Why: EK9's
DynamicCaptureOrErrorcreates a freshVariableSymbolin theCaptureScopewhen a variable is captured into a lambda. That fresh symbol has a differentISymbolidentity than the outer variable being captured, so naivetokenForSymbolwould treat the same conceptual lock as two distinct identities. The C.3 verdict would then over-flag legitimate reentrant patterns (positive case) and fail to recognise same-lock-cross-thread patterns (E08253 case).Scope: first-cut handles one level of capture. Deep-nested lambdas (lambda-in-lambda-in-method) where the outer is itself a capture would need iterative unwrapping; tracked as a known limitation.
- Parameters:
symbol- the receiver symbol resolved inside the lambda body.enclosingFunction- the immediate enclosing function/method whensymbolwas resolved (i.e. the dynamic function containing the receiver reference).- Returns:
- the outer
ISymbolif the receiver is a single-level capture;symbolitself otherwise.
-
lockIdentityValueFor
Wrap a token in aLockIdentityValuefor assignment to the analyzer state viaValueTrackingAnalyzer.recordAssignment.- Parameters:
token- the opaque identity token (typically obtained viamintAllocationToken(IToken)ortokenForSymbol(ISymbol)).- Returns:
- a new
LockIdentityValuecarrying the token.
-
stableIdFor
Produce a deterministic string identifier for the given token, suitable for foreign-key references in theLockAnalysisschema and for JSON output to MCP consumers.Encoding by origin:
IdentityOrigin.ALLOCATION—"alloc:<file>:<line>:<col>"— token must have been minted viamintAllocationToken(IToken); lookup reverses the cache to recover the source location.IdentityOrigin.FIELD_ROOTED—"field:<FQN>"from the symbol's fully-qualified name.IdentityOrigin.PARAMETER—"param:<FQN>".IdentityOrigin.CAPTURE—"capture:<FQN>".
- Parameters:
token- the opaque identity token.origin- how the token was sourced; controls the encoding prefix.- Returns:
- stable string identifier; never null.
-