Skip to main content

FunctionIdentity

Struct FunctionIdentity 

Source
pub struct FunctionIdentity {
    pub file: String,
    pub name: String,
    pub start_line: u32,
    pub start_column: Option<u32>,
    pub end_line: Option<u32>,
    pub end_column: Option<u32>,
    pub source_hash: Option<String>,
    pub resolution: IdentityResolution,
    pub stable_id: String,
}
Expand description

Canonical, versioned identity for a function.

Becomes the cross-surface join key between the OSS CLI’s static function inventory, V8 / Istanbul runtime coverage, test coverage from oxc-coverage-instrument, source-map remapped findings, and fallow-cloud aggregation when present.

§Name aliasing

The name field carries the same value as StaticFunction::name and Finding::function. The three spellings exist for backwards compatibility with 0.5-and-earlier envelopes: Finding::function and the legacy file / line fields are preserved verbatim so display surfaces (CLI human output, SARIF, GitHub annotations) keep working unchanged. New code should read FunctionIdentity::name when the field is present.

§Column semantics (load-bearing)

FunctionIdentity::start_column and FunctionIdentity::end_column are 1-indexed UTF-16 column offsets, anchored at the function-body start (matching Istanbul fnMap[i].loc.start, NOT fnMap[i].decl.start). Producers MUST normalize their native semantics to this anchor:

  • Istanbul producers read fnMap[i].loc.start.column (already UTF-16, 0-indexed) and add 1.
  • V8 producers (fallow-v8-coverage, oxc_coverage_v8) map the function’s startOffset byte offset to a UTF-16 column via the script text, then add 1.
  • AST-based producers (oxc spans) convert the Span::start byte offset to UTF-16 column, then add 1.

Pick one anchor and stick to it: producers picking different anchors for the same function would silently produce different (start_line, start_column) pairs for display, but they MUST still produce the same FunctionIdentity::stable_id because columns are intentionally NOT hashed (see below).

§Hash exclusion of columns

function_identity_id hashes only the NUL-delimited file, name, and start_line (see its rustdoc for the exact 0.8.0 recipe). Columns, end positions, and source_hash are descriptive metadata for display and same-line disambiguation, but are NOT part of the hash. Rationale: V8 runtime dumps frequently lack column info, while Istanbul fnMap and oxc spans always have it. If columns were hashed, the same function observed by two producers with different fidelity would produce two different stable_id values and the cross-surface join would silently break.

Same-line functions remain distinguishable via the column metadata on the struct itself, just not via the stable_id. Cloud aggregation that needs to disambiguate same-line functions during display can use (start_line, start_column) as a secondary key once the stable join has happened.

§Resolution confidence

FunctionIdentity::resolution is required (not Option) so cloud aggregation can record how each identity was produced. See IdentityResolution for the variants.

Added in protocol 0.6.0.

Fields§

§file: String

Path to the source file, relative to Request::project_root. Matches the legacy file field on Finding, HotPath, BlastRadiusEntry, and ImportanceEntry.

§name: String

Function name as reported by the producing pipeline. Matches StaticFunction::name and Finding::function.

§start_line: u32

1-indexed line where the function body starts. Matches StaticFunction::start_line and the legacy line field on findings / hot paths / blast-radius / importance entries.

§start_column: Option<u32>

1-indexed UTF-16 column of the first character of the function body (inclusive). Anchored at the function-body opening (Istanbul loc.start, V8 mapped from byte offset via script text, oxc Span::start mapped to UTF-16). Istanbul’s loc.start.column is 0-indexed inclusive, so producers MUST add 1 when reading from Istanbul fnMap. V8 producers whose Coverage.takePreciseCoverage() offsets originated from a disk-loaded script source MUST decode the script through UTF-8 before counting UTF-16 code units; offsets from inline-string scripts already speak UTF-16. Optional: older V8 dumps and Istanbul artifacts without column data omit this field. Descriptive metadata only; NOT part of FunctionIdentity::stable_id.

§end_line: Option<u32>

1-indexed line where the function body ends (inclusive). Optional. Mirrors StaticFunction::end_line.

§end_column: Option<u32>

1-indexed UTF-16 column of the last character of the function body (inclusive). Same indexing and anchor conventions as FunctionIdentity::start_column. Note: Istanbul’s loc.end.column is 0-indexed AND exclusive (the column AFTER the last character), so the mapping from Istanbul to this field is identity (protocol_end_column = istanbul_end_column): the off-by-one between “0-indexed exclusive” and “1-indexed inclusive” cancels. V8 and oxc producers MUST convert their byte-offset / span-end to the same 1-indexed-inclusive convention. Optional. Descriptive metadata only; NOT part of FunctionIdentity::stable_id.

§source_hash: Option<String>

Optional cross-producer tiebreaker for moved or renamed functions whose positions changed but whose source body is byte-identical.

Format (pinned in protocol 0.7.0, MUST hold across producers): the first 8 bytes of SHA-256(<canonical body bytes>) rendered as 16 lowercase hex characters. Compute via source_hash_for so every producer agrees on the value.

Canonical body bytes (also pinned): the bytes the producing compiler or parser sees for the function, including the signature line and the closing brace, with NO whitespace normalization. Two producers observing the same function in the same file MUST hand the same byte slice to source_hash_for.

Producers that cannot compute this format MUST omit the field rather than emit a divergent string. Consumers MAY use a present value as a cross-producer comparability signal; an absent value carries no information.

NOT part of FunctionIdentity::stable_id.

§resolution: IdentityResolution

How this identity was produced. See IdentityResolution. Required: a missing field would silently default to one of the variants and hide the resolution-confidence signal cloud aggregation needs.

§stable_id: String

Deterministic cross-surface join key of shape fallow:fn:<16 hex>. Producers MUST compute this via function_identity_id so the CLI, sidecar, and cloud agree on the value for the same function. See the struct-level docs for the hash-input rationale.

Implementations§

Source§

impl FunctionIdentity

Source

pub fn stable_id_computed(&self) -> String

Recompute the canonical FunctionIdentity::stable_id from file, name, and start_line. Diagnostic helper only: useful for logging or test assertions that a producer-supplied stable_id was computed via the canonical helper, and for debug_assert!(self.stable_id == self.stable_id_computed()) in producer test suites.

NOT a validation gate. Consumers MUST NOT reject payloads whose stable_id differs from the value returned here. A future protocol major that evolves the hash inputs would otherwise turn every such consumer into a hard-fail on upgrade, defeating the cross-surface join the value exists to provide.

Trait Implementations§

Source§

impl Clone for FunctionIdentity

Source§

fn clone(&self) -> FunctionIdentity

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for FunctionIdentity

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for FunctionIdentity

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for FunctionIdentity

Source§

fn eq(&self, other: &FunctionIdentity) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for FunctionIdentity

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for FunctionIdentity

Source§

impl StructuralPartialEq for FunctionIdentity

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,