Synvert core provides a set of DSLs to rewrite (find and replace) ruby code. e.g.
Synvert::Rewriter.new 'ruby', 'map_and_flatten_to_flat_map' do configure(parser: Synvert::PARSER_PARSER) description <<~EOS It converts `map` and `flatten` to `flat_map` ```ruby enum.map do # do something end.flatten ``` => ```ruby enum.flat_map do # do something end ``` EOS within_files Synvert::ALL_RUBY_FILES + Synvert::ALL_RAKE_FILES do find_node '.send [receiver=.block [caller=.send[message=map]]] [message=flatten] [arguments.size=0]' do group do delete :message, :dot replace 'receiver.caller.message', with: 'flat_map' end end end end
It also supports to add callbacks to visit ast nodes.
Synvert::Helper.new 'ruby/parse' do |options| configure(parser: Synvert::PRISM_PARSER) with_configurations(number_of_workers: 1) do class_names = [] within_file Synvert::ALL_RUBY_FILES do add_callback :class_node, at: 'start' do |node| class_names << node.name.to_source end end # class_names is an array of class names end end
Want to see more examples, check out synvert-snippets-ruby.
Want to use the CLI, check out synvert-ruby.
DSLs are as follows
- configure - configure the rewriter
- description - describe what the rewriter does
- if_ruby - check if ruby version is greater than or equal to the specified ruby version
- if_gem - compare version of specified gem
- within_files - find specified files
- within_file - alias to within_files
- add_file - add a new file
- remove_file - remove a file
- helper_method - define a helper method
- add_snippet - call another rewriter
- call_helper - call a shared rewriter
- with_configurations - execute a block of code with temporary configurations
Scopes:
- within_node - recursively find matching ast nodes
- with_node - alias to within_node
- find_node - alias to within_node
- goto_node - go to a child node
Conditions:
- if_exist_node - check if matching node exist in the child nodes
- unless_exist_node - check if matching node doesn't exist in the child nodes
Actions:
- append - append the code to the bottom of current node body
- prepend - prepend the code to the bottom of current node body
- insert - insert code
- insert_after - insert the code next to the current node
- insert_before - insert the code previous to the current node
- replace - replace the code of specified child nodes
- delete - delete the code in specified child nodes
- remove - remove the whole code of current node
- wrap - wrap the current node with prefix and suffix code
- replace_with - replace the whole code of current node
- warn - warn message
- replace_erb_stmt_with_expr - replace erb stmt code to expr code
- noop - no operation
- group - group actions
- add_action - add custom action
Callbacks:
- add_callback - add callback when visiting ast nodes
Others:
- wrap_with_quotes - wrap string code with single or double quotes
- add_leading_spaces - add leading spaces before the string code
Attributes:
- file_path - current file path
- node - current ast node
- mutation_adapter - mutation adapter to get some helper methods