Ragex.Editor.Refactor (Ragex v0.10.1)

View Source

Semantic refactoring operations that leverage the knowledge graph.

Provides AST-aware refactoring operations like rename_function and rename_module that automatically update all affected files using the graph to find call sites and dependencies.

Summary

Functions

Changes a function signature by adding, removing, reordering, or renaming parameters.

Converts function visibility between public (def) and private (defp).

Extracts multiple functions from a module into a new module.

Inlines a function by replacing all its calls with the function body.

Adds, removes, or updates module attributes.

Renames a function across the entire codebase.

Renames a module across the entire codebase.

Renames a function parameter and all its references within the function body.

Types

refactor_result()

@type refactor_result() :: %{
  status: :success | :failure,
  files_modified: non_neg_integer(),
  transaction_result: Ragex.Editor.Transaction.transaction_result()
}

Functions

change_signature(module_name, function_name, old_arity, signature_changes, opts \\ [])

@spec change_signature(
  atom() | String.t(),
  atom() | String.t(),
  non_neg_integer(),
  map(),
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Changes a function signature by adding, removing, reordering, or renaming parameters.

Parameters

  • module_name: Module containing the function
  • function_name: Function to modify
  • old_arity: Current function arity
  • signature_changes: Map describing the changes (see details below)
  • opts: Options
    • :scope - :module (same file only) or :project (all files, default: :project)
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Signature Changes Format

The signature_changes map can contain:

  • :add_params - List of params to add with defaults
  • :remove_params - List of param positions to remove (0-indexed)
  • :reorder_params - New param order
  • :rename_params - List of renames

Returns

  • {:ok, result} on success
  • {:error, reason} on failure (with rollback)

Examples

# Add an optional parameter
changes = %{add_params: [%{name: :opts, position: 2, default: []}]}
Refactor.change_signature(:MyModule, :process, 2, changes)

# Remove second parameter and rename first
changes = %{
  remove_params: [1],
  rename_params: [{:old_name, :new_name}]
}
Refactor.change_signature(:MyModule, :transform, 3, changes)

convert_visibility(module_name, function_name, arity, visibility, opts \\ [])

@spec convert_visibility(
  atom() | String.t(),
  atom() | String.t(),
  non_neg_integer(),
  :public | :private,
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Converts function visibility between public (def) and private (defp).

Parameters

  • module_name: Module containing the function
  • function_name: Function to modify
  • arity: Function arity
  • visibility: :public or :private
  • opts: Options
    • :add_doc - Add documentation when making public (default: false)
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure

Examples

# Make private function public
Refactor.convert_visibility(:MyModule, :helper, 1, :public)

# Make public function private
Refactor.convert_visibility(:MyModule, :exposed, 2, :private)

extract_function(module_name, source_function, source_arity, new_function_name, line_range, opts \\ [])

@spec extract_function(
  atom() | String.t(),
  atom() | String.t(),
  non_neg_integer(),
  atom() | String.t(),
  {pos_integer(), pos_integer()},
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Extracts a range of lines from a function into a new function.

Parameters

  • module_name: Module containing the function
  • source_function: Function to extract from
  • source_arity: Arity of source function
  • new_function_name: Name for the extracted function
  • line_range: {start_line, end_line} tuple (1-indexed)
  • opts: Options
    • :placement - :after_source | :before_source | :end_of_module (default: :after_source)

    • :visibility - :public | :private (default: :private)

    • :add_doc - boolean (default: false)
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure (with rollback)

Examples

# Extract lines 10-15 from MyModule.process/2 into helper/0
Refactor.extract_function(:MyModule, :process, 2, :helper, {10, 15})

# Extract as public function at end of module
Refactor.extract_function(
  :MyModule, :process, 2, :extracted_logic, {10, 15},
  visibility: :public, placement: :end_of_module
)

extract_module(source_module, new_module, functions, opts \\ [])

@spec extract_module(
  atom() | String.t(),
  atom() | String.t(),
  [{atom(), non_neg_integer()}],
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Extracts multiple functions from a module into a new module.

Parameters

  • source_module: Source module name
  • new_module: New module name
  • functions: List of {function_name, arity} tuples
  • opts: Options
    • :file_path - Explicit path for new module (optional)
    • :add_moduledoc - boolean (default: true)
    • :update_aliases - boolean (default: true)
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure (with rollback)

Examples

# Extract helpers into new module
functions = [{:helper1, 1}, {:helper2, 2}]
Refactor.extract_module(:MyModule, :MyModule.Helpers, functions)

inline_function(module_name, function_name, arity, opts \\ [])

@spec inline_function(
  atom() | String.t(),
  atom() | String.t(),
  non_neg_integer(),
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Inlines a function by replacing all its calls with the function body.

Parameters

  • module_name: Module containing the function
  • function_name: Function to inline
  • arity: Function arity
  • opts: Options
    • :scope - :module (same file only) or :project (all files, default: :project)
    • :remove_definition - Remove function definition after inlining (default: true)
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure (with rollback)

Examples

# Inline MyModule.helper/1 across entire project
Refactor.inline_function(:MyModule, :helper, 1)

# Inline only within the same module, keep definition
Refactor.inline_function(
  :MyModule, :helper, 1,
  scope: :module, remove_definition: false
)

modify_attributes(module_name, changes, opts \\ [])

@spec modify_attributes(atom() | String.t(), map(), keyword()) ::
  {:ok, refactor_result()} | {:error, term()}

Adds, removes, or updates module attributes.

Parameters

  • module_name: Module to modify
  • changes: Map with :add, :remove, and/or :update keys
  • opts: Options
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure

Examples

# Add and update attributes
changes = %{
  add: [{:vsn, "1.0.0"}],
  remove: [:deprecated],
  update: [{:moduledoc, "Updated docs"}]
}
Refactor.modify_attributes(:MyModule, changes)

move_function(source_module, target_module, function_name, arity, opts \\ [])

@spec move_function(
  atom() | String.t(),
  atom() | String.t(),
  atom() | String.t(),
  non_neg_integer(),
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Moves a function from one module to another.

Parameters

  • source_module: Source module name
  • target_module: Target module name
  • function_name: Function to move
  • arity: Function arity
  • opts: Options
    • :placement - :start | :end (default: :end)

    • :update_references - boolean (default: true)
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure (with rollback)

Examples

# Move function to existing module
Refactor.move_function(:MyModule, :MyModule.Utils, :helper, 1)

rename_function(module_name, old_name, new_name, arity, opts \\ [])

@spec rename_function(
  atom() | String.t(),
  atom() | String.t(),
  atom() | String.t(),
  non_neg_integer(),
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Renames a function across the entire codebase.

Uses the knowledge graph to find all call sites and updates them atomically.

Parameters

  • module_name: Module containing the function (atom or string)
  • old_name: Current function name (atom or string)
  • new_name: New function name (atom or string)
  • arity: Function arity
  • opts: Options
    • :validate - Validate before/after (default: true)
    • :format - Format files after editing (default: true)
    • :scope - :module (same module only) or :project (all files, default)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure (with rollback)

Examples

# Rename MyModule.old_func/2 to MyModule.new_func/2 across project
Refactor.rename_function(:MyModule, :old_func, :new_func, 2)

# Rename only within the same module
Refactor.rename_function(:MyModule, :old_func, :new_func, 2, scope: :module)

rename_module(old_name, new_name, opts \\ [])

@spec rename_module(atom() | String.t(), atom() | String.t(), keyword()) ::
  {:ok, refactor_result()} | {:error, term()}

Renames a module across the entire codebase.

Updates the module definition and all references (imports, aliases, calls).

Parameters

  • old_name: Current module name (atom or string)
  • new_name: New module name (atom or string)
  • opts: Options (same as rename_function)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure (with rollback)

Examples

Refactor.rename_module(:OldModule, :NewModule)

rename_parameter(module_name, function_name, arity, old_param_name, new_param_name, opts \\ [])

@spec rename_parameter(
  atom() | String.t(),
  atom() | String.t(),
  non_neg_integer(),
  atom() | String.t(),
  atom() | String.t(),
  keyword()
) :: {:ok, refactor_result()} | {:error, term()}

Renames a function parameter and all its references within the function body.

Parameters

  • module_name: Module containing the function
  • function_name: Function to modify
  • arity: Function arity
  • old_param_name: Current parameter name
  • new_param_name: New parameter name
  • opts: Options
    • :validate - boolean (default: true)
    • :format - boolean (default: true)

Returns

  • {:ok, result} on success
  • {:error, reason} on failure

Examples

# Rename parameter x to input
Refactor.rename_parameter(:MyModule, :process, 1, :x, :input)