class Synvert::Core::Rewriter
Rewriter
is the top level namespace in a snippet.
One Rewriter
can contain one or many [Synvert::Core::Rewriter::Instance], which define the behavior what files and what codes to detect and rewrite to what code.
Synvert::Rewriter.new 'factory_girl_short_syntax', 'use FactoryGirl short syntax' do if_gem 'factory_girl', '>= 2.0.0' within_files 'spec/**/*.rb' do with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do replace_with "create({{arguments}})" end end end
Attributes
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
@!attribute [r] group
@return [String] the group of rewriter
@!attribute [r] name
@return [String] the unique name of rewriter
@!attribute [r] sub_snippets
@return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
@!attribute [r] helper
@return [Array] helper methods.
@!attribute [r] warnings
@return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
@!attribute [r] affected_files
@return [Set] affected fileds
@!attribute [r] ruby_version
@return [Rewriter::RubyVersion] the ruby version
@!attribute [r] gem_spec
@return [Rewriter::GemSpec] the gem spec
Public Class Methods
Get all available rewriters
@return [Hash<String, Hash<String, Rewriter>>]
# File lib/synvert/core/rewriter.rb, line 111 def availables rewriters end
Get a registered rewriter by group and name, then process that rewriter.
@param group [String] the rewriter group. @param name [String] the rewriter name. @param sandbox [Boolean] if run in sandbox mode, default is false. @return [Synvert::Core::Rewriter] the registered rewriter. @raise [Synvert::Core::RewriterNotFound] if the registered rewriter is not found.
# File lib/synvert/core/rewriter.rb, line 98 def call(group, name, sandbox = false) rewriter = fetch(group, name) if sandbox rewriter.process_with_sandbox else rewriter.process end rewriter end
Clear all registered rewriters.
# File lib/synvert/core/rewriter.rb, line 116 def clear rewriters.clear end
Execute the temporary rewriter without group and name.
@param block [Block] a block defines the behaviors of the rewriter.
# File lib/synvert/core/rewriter.rb, line 57 def execute(&block) rewriter = Rewriter.new('', '', &block) rewriter.process rewriter end
Fetch a rewriter by group and name.
@param group [String] rewrtier group. @param name [String] rewrtier name. @return [Synvert::Core::Rewriter] the matching rewriter. @raise [Synvert::Core::RewriterNotFound] if the registered rewriter is not found.
# File lib/synvert/core/rewriter.rb, line 81 def fetch(group, name) group = group.to_s name = name.to_s if rewriters[group] && rewriters[group][name] rewriters[group][name] else raise RewriterNotFound, "Rewriter #{group} #{name} not found" end end
Initialize a rewriter. When a rewriter is initialized, it is also registered.
@param group [String] group of the rewriter. @param name [String] name of the rewriter. @param block [Block] a block defines the behaviors of the rewriter, block code won't be called when initialization. @return [Synvert::Core::Rewriter]
# File lib/synvert/core/rewriter.rb, line 152 def initialize(group, name, &block) @group = group @name = name @block = block @helpers = [] @sub_snippets = [] @warnings = [] @affected_files = Set.new @redo_until_no_change = false self.class.register(@group, @name, self) end
Register a rewriter with its group and name.
@param group [String] the rewriter group. @param name [String] the unique rewriter name. @param rewriter [Synvert::Core::Rewriter] the rewriter to register.
# File lib/synvert/core/rewriter.rb, line 68 def register(group, name, rewriter) group = group.to_s name = name.to_s rewriters[group] ||= {} rewriters[group][name] = rewriter end
Private Class Methods
# File lib/synvert/core/rewriter.rb, line 122 def rewriters @rewriters ||= {} end
Public Instance Methods
Add an affected file.
@param file_path [String]
# File lib/synvert/core/rewriter.rb, line 195 def add_affected_file(file_path) @affected_files.add(file_path) end
Parses add_file
dsl, it adds a new file.
@param filename [String] file name of newly created file. @param content [String] file body of newly created file.
# File lib/synvert/core/rewriter.rb, line 251 def add_file(filename, content) return if @sandbox filepath = File.join(Configuration.path, filename) if File.exist?(filepath) puts "File #{filepath} already exists." return end FileUtils.mkdir_p File.dirname(filepath) File.open filepath, 'w' do |file| file.write content end end
Parse add_snippet
dsl, it calls anther rewriter.
@param group [String] group of another rewriter. @param name [String] name of another rewriter.
# File lib/synvert/core/rewriter.rb, line 280 def add_snippet(group, name) @sub_snippets << self.class.call(group.to_s, name.to_s, @sandbox) end
Add a warning.
@param warning [Synvert::Core::Rewriter::Warning]
# File lib/synvert/core/rewriter.rb, line 188 def add_warning(warning) @warnings << warning end
Parse description dsl, it sets description of the rewrite. Or get description.
@param description [String] rewriter description. @return rewriter description.
# File lib/synvert/core/rewriter.rb, line 208 def description(description = nil) if description @description = description else @description end end
Parse helper_method
dsl, it defines helper method for [Synvert::Core::Rewriter::Instance].
@param name [String] helper method name. @param block [Block] helper method block.
# File lib/synvert/core/rewriter.rb, line 288 def helper_method(name, &block) @helpers << { name: name, block: block } end
Parse if_gem
dsl, it compares version of the specified gem.
@param name [String] gem name. @param version [String] equal, less than or greater than specified version, e.g. '>= 2.0.0',
# File lib/synvert/core/rewriter.rb, line 227 def if_gem(name, version) @gem_spec = Rewriter::GemSpec.new(name, version) end
Parse if_ruby
dal, it checks if ruby version if greater than or equal to the specified ruby version.
@param version, [String] specified ruby version.
# File lib/synvert/core/rewriter.rb, line 219 def if_ruby(version) @ruby_version = Rewriter::RubyVersion.new(version) end
Process the rewriter. It will call the block.
# File lib/synvert/core/rewriter.rb, line 166 def process @affected_files = Set.new instance_eval(&@block) if !@affected_files.empty? && @redo_until_no_change process end end
Process rewriter with sandbox mode. It will call the block but doesn't change any file.
# File lib/synvert/core/rewriter.rb, line 176 def process_with_sandbox @sandbox = true begin process ensure @sandbox = false end end
Rerun the snippet until no change.
# File lib/synvert/core/rewriter.rb, line 306 def redo_until_no_change @redo_until_no_change = true end
Parses remove_file
dsl, it removes a file.
@param filename [String] file name.
# File lib/synvert/core/rewriter.rb, line 269 def remove_file(filename) return if @sandbox file_path = File.join(Configuration.path, filename) File.delete(file_path) if File.exist?(file_path) end
Parse todo dsl, it sets todo of the rewriter. Or get todo.
@param todo_list [String] rewriter todo. @return [String] rewriter todo.
# File lib/synvert/core/rewriter.rb, line 297 def todo(todo = nil) if todo @todo = todo else @todo end end
Parse within_file
dsl, it finds a specifiled file.
Parse within_files
dsl, it finds specified files. It creates a [Synvert::Core::Rewriter::Instance] to rewrite code.
@param file_pattern [String] pattern to find files, e.g. spec/*/_spec.rb @param block [Block] the block to rewrite code in the matching files.
# File lib/synvert/core/rewriter.rb, line 236 def within_files(file_pattern, &block) return if @sandbox if (!@ruby_version || @ruby_version.match?) && (!@gem_spec || @gem_spec.match?) Rewriter::Instance.new(self, file_pattern, &block).process end end