Module: RuboCop::Cop::ReparsedEquivalence

Overview

Verifies that a candidate correction of the inspected source is a syntactic no-op: the corrected source must parse successfully and produce the same AST as the original.

This turns "is this piece of syntax redundant?" questions into a parser-backed check instead of a hand-maintained enumeration of grammar rules: instead of modeling which constructs make (for example) a line continuation or a pair of parentheses significant, a cop can apply the correction and let the parser answer.

Cops implement #apply_reparse_correction(corrector, item) and call verified_by_reparse(items), which returns the items whose corrections are verified. Items sharing a reparse scope (the innermost method definition or class/module body, which parse standalone and cannot capture outer local variables) are verified together with a single reparse, falling back to per-item verification when the batch does not hold. Scope groups are keyed by node identity, since structurally identical definitions in different places must not share a group.

Two hooks customize the comparison:

  • normalize_reparsed_ast(node) - loosen strict tree equality where a cop's correction is equivalence-preserving beyond parse identity (such laws must be justified per cop; the default compares trees as-is).
  • preprocess_reparsed_source(source) - rewrite both sides before parsing (e.g. to neutralize __LINE__ when a correction legitimately shifts line numbers).

__FILE__ is handled by parsing with the original path, and fragments containing __LINE__ are verified by reparsing both sides so that fragment line offsets cancel out.

Note that comments are invisible to the AST, so corrections that may touch comment text must be guarded separately by the caller.

Constant Summary collapse

MAX_VERIFICATION_FRAGMENT_SIZE =

Above this size, verification does not reparse. What happens to such items depends on oversized; in practice only machine-generated files come near the limit.

64 * 1024