Expand description
Position-independent fingerprints of AST nodes.
structural_fingerprint hashes a node’s full structure — kinds, names,
literals, operators, doc comments — while ignoring every Span. Two
nodes that differ only in where they sit in the file (an edit above a
function shifts every offset inside it) get the same fingerprint.
This is meant for incremental tools such as salsa-based analyzers: store the fingerprint next to a declaration’s subtree and compare fingerprints instead of nodes, so a declaration whose code did not change compares equal after unrelated edits and its downstream results can be reused. Results derived from such a node must not carry its absolute positions; keep them relative to the declaration and add its current start when reporting.
It works on anything that implements serde::Serialize, so both the
arena and the owned AST are supported.
use php_ast::fingerprint::structural_fingerprint;
use php_ast::owned::{Expr, ExprKind};
use php_ast::Span;
let var = |name: &str, start: u32| Expr {
kind: ExprKind::Variable(name.into()),
span: Span::new(start, start + 1 + name.len() as u32),
};
// Same variable at two positions: equal fingerprints.
assert_eq!(structural_fingerprint(&var("x", 10)), structural_fingerprint(&var("x", 90)));
// A different variable: different fingerprints.
assert_ne!(structural_fingerprint(&var("x", 10)), structural_fingerprint(&var("y", 10)));Functions§
- structural_
fingerprint - A 64-bit hash of
node’s structure that ignores everySpan.