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§
Sourcefn should_skip_path(&self, path: &Path) -> bool
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.
Sourcefn post_process_lines(&self, lines: &mut [String])
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).
Sourcefn plan_remove_attribute(
&self,
rule_id: &str,
incident: &Incident,
file_path: &Path,
) -> Option<PlannedFix>
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.
Sourcefn plan_ensure_dependency(
&self,
rule_id: &str,
incident: &Incident,
package: &str,
new_version: &str,
file_path: &Path,
) -> Vec<PlannedFix>
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.
Sourcefn get_matched_text(&self, incident: &Incident) -> String
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.
Sourcefn get_matched_text_for_rename(
&self,
incident: &Incident,
mappings: &[RenameMapping],
) -> String
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.
Sourcefn is_whole_file_rename(&self, incident: &Incident) -> bool
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§
Sourcefn pre_apply(&self, _project_root: &Path) -> Option<Box<dyn Any>>
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.
Sourcefn post_apply(
&self,
_project_root: &Path,
_modified_files: &[PathBuf],
_pre_state: Option<Box<dyn Any>>,
) -> Result<()>
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".