Record Class LockIdentityValue

java.lang.Object
java.lang.Record
org.ek9lang.compiler.phase5.flow.LockIdentityValue
All Implemented Interfaces:
AbstractValue

public record LockIdentityValue(Set<Object> identityTokens) extends Record implements AbstractValue
Tracks which physical MutexLock object(s) a variable may currently refer to at a given program point.

The identityTokens set carries every identity the variable could have. In the common case the set is a singleton (one known lock); branch joins, polymorphic-getter resolution, and call-site argument bindings introduce multi-element sets. Phase C.3 iterates the cross-product of outer × inner identities when applying the deadlock verdict — if any pair forms a cycle (E08252) or a cross-thread same-lock pattern (E08253) the error fires.

Each element is one of two token shapes:

  • Allocation token — an opaque Object reference, freshly minted per MutexLock(...) constructor call site. Compared by Java ==. ISymbol references (for field-rooted and capture-rooted receivers) follow the same rule — A.4 freshness guarantees one symbol per allocation.
  • PlaceholderToken — symbolic identity for a parameter whose underlying object is unknown until resolved at a call site. Compared structurally on parameter FQN.

Why custom token equality and not the JDK Set contract: Symbol.equals(Object) is structural by name + category + genus + mutability. Two distinct fields both named lock on different classes would compare equal under that contract. If we relied on default HashSet/Set.copyOf semantics, those two physically-distinct locks would silently collapse to one element, missing a potential lock-order cycle. So this record stores its tokens in a deduplicated backing collection that enforces the per-token-type equality rules below (tokensEqual(Object, Object), tokenHash(Object)) and overrides equals/hashCode to use the same rules for set-level comparison. The public identityTokens() accessor returns an unmodifiable view; iterators preserve insertion order.

Why set-union lattice for deadlock detection: the usual constant-folding lattice widens to TOP when paths disagree because the downstream consumer only acts on certainty. Deadlock detection is the opposite — it acts on possibility. If any execution path could pair the outer hold with an inner enter that forms a cycle, we want to warn. So the join unions sets rather than widening; the verdict iterates all pairs; one bad pair is enough.

  • Constructor Details

    • LockIdentityValue

      public LockIdentityValue(Set<Object> identityTokens)
      Creates an instance of a LockIdentityValue record class.
      Parameters:
      identityTokens - the value for the identityTokens record component
  • Method Details

    • of

      public static LockIdentityValue of(Object identityToken)
      Singleton factory — wraps one identity token. Used for the common case where a variable has exactly one possible identity at this program point.
    • fromTokens

      public static LockIdentityValue fromTokens(Iterable<? extends Object> tokens)
      Build a value from a collection of tokens, applying token-rule dedup.
    • hasPlaceholder

      public boolean hasPlaceholder()
      Convenience accessor: true when at least one element of the set is a PlaceholderToken. A set may carry mixed token types (an allocation + a placeholder, post-substitution at a polymorphic call site).
    • join

      public AbstractValue join(AbstractValue other)
      Description copied from interface: AbstractValue
      Join this value with another at a branch convergence point. Returns the least upper bound of the two values.

      Key rules:

      • BOTTOM join X = X (unreachable path is ignored)
      • X join BOTTOM = X
      • TOP join X = TOP
      • Constant(a) join Constant(a) = Constant(a) (both agree)
      • Constant(a) join Constant(b) = TOP (disagreement)
      Specified by:
      join in interface AbstractValue
    • evaluateCondition

      public ConditionResult evaluateCondition(String operator, AbstractValue operand)
      Description copied from interface: AbstractValue
      Evaluate whether this abstract value satisfies a comparison condition.
      Specified by:
      evaluateCondition in interface AbstractValue
      Parameters:
      operator - the comparison operator (==, <>, <, >, etc.)
      operand - the right-hand side value to compare against
      Returns:
      TRUE if condition is always satisfied, FALSE if never satisfied, UNKNOWN if indeterminate
    • isKnown

      public boolean isKnown()
      Description copied from interface: AbstractValue
      Check if this value represents a known state (not TOP and not BOTTOM).
      Specified by:
      isKnown in interface AbstractValue
    • isBottom

      public boolean isBottom()
      Description copied from interface: AbstractValue
      Check if this value represents an unreachable program point.
      Specified by:
      isBottom in interface AbstractValue
    • equals

      public boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. All components in this record class are compared with Objects::equals(Object,Object).
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • hashCode

      public int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • toString

      public String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • tokensEqual

      static boolean tokensEqual(Object a, Object b)
      Token equality: structural for PlaceholderToken, identity (==) for everything else.
    • tokenHash

      static int tokenHash(Object t)
      Token hash consistent with tokensEqual(Object, Object): structural hash for PlaceholderToken, identity hash for everything else.
    • identityTokens

      public Set<Object> identityTokens()
      Returns the value of the identityTokens record component.
      Returns:
      the value of the identityTokens record component