Skip to main content

LanguageFixProvider

Trait LanguageFixProvider 

Source
pub trait LanguageFixProvider: Send + Sync {
    // Required methods
    fn should_skip_path(&self, path: &Path) -> bool;
    fn post_process_lines(&self, lines: &mut [String]);
    fn plan_remove_attribute(
        &self,
        rule_id: &str,
        incident: &Incident,
        file_path: &Path,
    ) -> Option<PlannedFix>;
    fn plan_ensure_dependency(
        &self,
        rule_id: &str,
        incident: &Incident,
        package: &str,
        new_version: &str,
        file_path: &Path,
    ) -> Vec<PlannedFix>;
    fn get_matched_text(&self, incident: &Incident) -> String;
    fn get_matched_text_for_rename(
        &self,
        incident: &Incident,
        mappings: &[RenameMapping],
    ) -> String;
    fn is_whole_file_rename(&self, incident: &Incident) -> bool;

    // Provided methods
    fn pre_apply(&self, _project_root: &Path) -> Option<Box<dyn Any>> { ... }
    fn post_apply(
        &self,
        _project_root: &Path,
        _modified_files: &[PathBuf],
        _pre_state: Option<Box<dyn Any>>,
    ) -> Result<()> { ... }
}
Expand description

Trait that language-specific crates implement to provide syntax-aware fix operations for the fix engine.

Implementations are passed to plan_fixes, apply_fixes, and preview_fixes at runtime.

Required Methods§

Source

fn should_skip_path(&self, path: &Path) -> bool

Should this file path be skipped during fix planning?

For example, a JS/TS provider skips node_modules/ since those dependencies are updated via package manager, not source patches.

Source

fn post_process_lines(&self, lines: &mut [String])

Post-process lines after edits have been applied.

Called once per file after all text edits are applied. Implementations can use this to clean up language-specific artifacts (e.g., deduplicating import specifiers after renames produce duplicates).

Source

fn plan_remove_attribute( &self, rule_id: &str, incident: &Incident, file_path: &Path, ) -> Option<PlannedFix>

Plan an attribute/prop removal fix.

Given an incident flagging an attribute for removal, produce a PlannedFix with the text edits needed to remove it. Returns None if the incident cannot be processed.

Source

fn plan_ensure_dependency( &self, rule_id: &str, incident: &Incident, package: &str, new_version: &str, file_path: &Path, ) -> Vec<PlannedFix>

Plan dependency version fix(es).

Given an incident requiring a dependency to be at a specific version, produce PlannedFix entries with the text edits needed to update or add the dependency in the appropriate manifest file (e.g., package.json for Node.js, Cargo.toml for Rust, go.mod for Go).

Returns a Vec because a single incident (e.g., a transitive lockfile dep) may require updating multiple parent packages. Returns an empty Vec if the language provider does not support dependency management or if the incident cannot be processed.

Source

fn get_matched_text(&self, incident: &Incident) -> String

Extract the matched text from incident variables.

Incidents carry language-specific variable names (e.g., propName, className, variableName). This method extracts the primary matched text from whichever variable is present.

Source

fn get_matched_text_for_rename( &self, incident: &Incident, mappings: &[RenameMapping], ) -> String

Get the matched text for rename operations.

Rename mappings may target either the attribute name or its value. This method inspects incident variables to find which mapping entry matches, considering both names and values.

Source

fn is_whole_file_rename(&self, incident: &Incident) -> bool

Whether a rename incident requires whole-file scanning.

Some renames (e.g., component/import renames in JSX) affect many lines beyond the incident line – opening tags, closing tags, type references. When this returns true, the engine scans the entire file for all occurrences of the rename mappings.

Provided Methods§

Source

fn pre_apply(&self, _project_root: &Path) -> Option<Box<dyn Any>>

Capture baseline state before edits are written to disk.

Called once before any files are modified. Implementations can capture pre-existing state needed for diffing in post_apply — e.g., the set of unmet peer dependencies before package version updates, so that post_apply only installs newly introduced peers rather than pre-existing intentionally-unmet ones (like host-provided shared modules).

Returns opaque state that will be forwarded to post_apply.

Default: no-op, returns None.

Source

fn post_apply( &self, _project_root: &Path, _modified_files: &[PathBuf], _pre_state: Option<Box<dyn Any>>, ) -> Result<()>

Post-process after all fixes in a plan have been applied to disk.

Called once after all files are written. Implementations can trigger ecosystem-specific steps like npm install after package.json modifications to keep the lockfile and node_modules in sync.

project_root is the top-level project directory. modified_files lists paths of files that were actually changed. pre_state is the opaque state returned by pre_apply, if any.

Default: no-op.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§