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

affected_files[R]

@!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
gem_spec[R]

@!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
group[R]

@!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
helpers[R]

@!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
name[R]

@!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
ruby_version[R]

@!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
sub_snippets[R]

@!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
warnings[R]

@!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

availables() click to toggle source

Get all available rewriters

@return [Hash<String, Hash<String, Rewriter>>]

# File lib/synvert/core/rewriter.rb, line 111
def availables
  rewriters
end
call(group, name, sandbox = false) click to toggle source

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() click to toggle source

Clear all registered rewriters.

# File lib/synvert/core/rewriter.rb, line 116
def clear
  rewriters.clear
end
execute(&block) click to toggle source

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(group, name) click to toggle source

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
new(group, name, &block) click to toggle source

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(group, name, rewriter) click to toggle source

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

rewriters() click to toggle source
# File lib/synvert/core/rewriter.rb, line 122
def rewriters
  @rewriters ||= {}
end

Public Instance Methods

add_affected_file(file_path) click to toggle source

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
add_file(filename, content) click to toggle source

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
add_snippet(group, name) click to toggle source

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_warning(warning) click to toggle source

Add a warning.

@param warning [Synvert::Core::Rewriter::Warning]

# File lib/synvert/core/rewriter.rb, line 188
def add_warning(warning)
  @warnings << warning
end
description(description = nil) click to toggle source

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
helper_method(name, &block) click to toggle source

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
if_gem(name, version) click to toggle source

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
if_ruby(version) click to toggle source

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() click to toggle source

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_with_sandbox() click to toggle source

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
redo_until_no_change() click to toggle source

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
remove_file(filename) click to toggle source

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
todo(todo = nil) click to toggle source

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
within_file(file_pattern, &block)

Parse within_file dsl, it finds a specifiled file.

Alias for: within_files
within_files(file_pattern, &block) click to toggle source

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
Also aliased as: within_file