Class: Synvert::Core::Rewriter

Inherits:
Object
  • Object
show all
Defined in:
lib/synvert/core/rewriter.rb

Overview

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

Defined Under Namespace

Modules: Helper Classes: Action, AppendAction, Condition, DeleteAction, GemSpec, GotoScope, IfExistCondition, IfOnlyExistCondition, InsertAction, InsertAfterAction, Instance, RemoveAction, ReplaceAction, ReplaceErbStmtWithExprAction, ReplaceWithAction, RubyVersion, Scope, UnlessExistCondition, Warning, WithinScope

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group, name, &block) ⇒ Synvert::Core::Rewriter

Initialize a rewriter. When a rewriter is initialized, it is also registered.

Parameters:

  • group (String)

    group of the rewriter.

  • name (String)

    name of the rewriter.

  • block (Block)

    a block defines the behaviors of the rewriter, block code won’t be called when initialization.



165
166
167
168
169
170
171
172
173
174
# File 'lib/synvert/core/rewriter.rb', line 165

def initialize(group, name, &block)
  @group = group
  @name = name
  @block = block
  @helpers = []
  @sub_snippets = []
  @warnings = []
  @affected_files = Set.new
  self.class.register(@group, @name, self)
end

Instance Attribute Details

#affected_filesSet (readonly)

Returns affected fileds.

Returns:

  • (Set)

    affected fileds



156
# File 'lib/synvert/core/rewriter.rb', line 156

attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec

#gem_specObject (readonly)

Returns the value of attribute gem_spec.



156
# File 'lib/synvert/core/rewriter.rb', line 156

attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec

#groupString (readonly)

Returns the group of rewriter.

Returns:

  • (String)

    the group of rewriter



156
157
158
# File 'lib/synvert/core/rewriter.rb', line 156

def group
  @group
end

#helperArray (readonly)

Returns helper methods.

Returns:

  • (Array)

    helper methods.



156
# File 'lib/synvert/core/rewriter.rb', line 156

attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec

#helpersObject (readonly)

Returns the value of attribute helpers.



156
157
158
# File 'lib/synvert/core/rewriter.rb', line 156

def helpers
  @helpers
end

#nameString (readonly)

Returns the unique name of rewriter.

Returns:

  • (String)

    the unique name of rewriter



156
# File 'lib/synvert/core/rewriter.rb', line 156

attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec

#ruby_versionRewriter::RubyVersion (readonly)

Returns the ruby version.

Returns:



156
# File 'lib/synvert/core/rewriter.rb', line 156

attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec

#sub_snippetsArray<Synvert::Core::Rewriter> (readonly)

Returns all rewriters this rewiter calls.

Returns:



156
# File 'lib/synvert/core/rewriter.rb', line 156

attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec

#warningsArray<Synvert::Core::Rewriter::Warning> (readonly)

Returns warning messages.

Returns:



156
# File 'lib/synvert/core/rewriter.rb', line 156

attr_reader :group, :name, :sub_snippets, :helpers, :warnings, :affected_files, :ruby_version, :gem_spec

Class Method Details

.availablesHash<String, Hash<String, Rewriter>>

Get all available rewriters

Returns:

  • (Hash<String, Hash<String, Rewriter>>)


124
125
126
# File 'lib/synvert/core/rewriter.rb', line 124

def availables
  rewriters
end

.call(group, name, sandbox = false) ⇒ Synvert::Core::Rewriter

Get a registered rewriter by group and name, then process that rewriter.

Parameters:

  • group (String)

    the rewriter group.

  • name (String)

    the rewriter name.

  • sandbox (Boolean) (defaults to: false)

    if run in sandbox mode, default is false.

Returns:

Raises:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/synvert/core/rewriter.rb', line 90

def call(group, name, sandbox = false)
  group = group.to_s
  name = name.to_s
  if exist? group, name
    rewriter = rewriters[group][name]
    if sandbox
      rewriter.process_with_sandbox
    else
      rewriter.process
    end
    rewriter
  else
    raise RewriterNotFound, "Rewriter #{group}/#{name} not found"
  end
end

.clearObject

Clear all registered rewriters.



129
130
131
# File 'lib/synvert/core/rewriter.rb', line 129

def clear
  rewriters.clear
end

.execute(&block) ⇒ Object

Execute the temporary rewriter without group and name.

Parameters:

  • block (Block)

    a block defines the behaviors of the rewriter.



51
52
53
# File 'lib/synvert/core/rewriter.rb', line 51

def execute(&block)
  Rewriter.new('', '', &block).process
end

.exist?(group, name) ⇒ Boolean

Check if one rewriter exist.

Parameters:

  • group (String)

    the rewriter group.

  • name (String)

    the rewriter name.

Returns:

  • (Boolean)

    true if the rewriter exist.



111
112
113
114
115
116
117
118
119
# File 'lib/synvert/core/rewriter.rb', line 111

def exist?(group, name)
  group = group.to_s
  name = name.to_s
  if rewriters[group] && rewriters[group][name]
    true
  else
    false
  end
end

.fetch(group, name) ⇒ Synvert::Core::Rewriter

Fetch a rewriter by group and name.

Parameters:

  • group (String)

    rewrtier group.

  • name (String)

    rewrtier name.

Returns:

Raises:



73
74
75
76
77
78
79
80
81
# File 'lib/synvert/core/rewriter.rb', line 73

def fetch(group, name)
  group = group.to_s
  name = name.to_s
  if exist? group, name
    rewriters[group][name]
  else
    raise RewriterNotFound, "Rewriter #{group} #{name} not found"
  end
end

.register(group, name, rewriter) ⇒ Object

Register a rewriter with its group and name.

Parameters:

  • group (String)

    the rewriter group.

  • name (String)

    the unique rewriter name.

  • rewriter (Synvert::Core::Rewriter)

    the rewriter to register.



60
61
62
63
64
65
# File 'lib/synvert/core/rewriter.rb', line 60

def register(group, name, rewriter)
  group = group.to_s
  name = name.to_s
  rewriters[group] ||= {}
  rewriters[group][name] = rewriter
end

Instance Method Details

#add_affected_file(file_path) ⇒ Object

Add an affected file.

Parameters:

  • file_path (String)


203
204
205
# File 'lib/synvert/core/rewriter.rb', line 203

def add_affected_file(file_path)
  @affected_files.add(file_path)
end

#add_file(filename, content) ⇒ Object

Parses add_file dsl, it adds a new file.

Parameters:

  • filename (String)

    file name of newly created file.

  • content (String)

    file body of newly created file.



260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/synvert/core/rewriter.rb', line 260

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) ⇒ Object

Parse add_snippet dsl, it calls anther rewriter.

Parameters:

  • group (String)

    group of another rewriter.

  • name (String)

    name of another rewriter.



289
290
291
# File 'lib/synvert/core/rewriter.rb', line 289

def add_snippet(group, name)
  @sub_snippets << self.class.call(group.to_s, name.to_s, @sandbox)
end

#add_warning(warning) ⇒ Object

Add a warning.

Parameters:



196
197
198
# File 'lib/synvert/core/rewriter.rb', line 196

def add_warning(warning)
  @warnings << warning
end

#description(description = nil) ⇒ Object

Parse description dsl, it sets description of the rewrite. Or get description.

Parameters:

  • description (String) (defaults to: nil)

    rewriter description.

Returns:

  • rewriter description.



216
217
218
219
220
221
222
# File 'lib/synvert/core/rewriter.rb', line 216

def description(description = nil)
  if description
    @description = description
  else
    @description
  end
end

#helper_method(name, &block) ⇒ Object

Parse helper_method dsl, it defines helper method for [Synvert::Core::Rewriter::Instance].

Parameters:

  • name (String)

    helper method name.

  • block (Block)

    helper method block.



297
298
299
# File 'lib/synvert/core/rewriter.rb', line 297

def helper_method(name, &block)
  @helpers << { name: name, block: block }
end

#if_gem(name, version) ⇒ Object

Parse if_gem dsl, it compares version of the specified gem.

Parameters:

  • name (String)

    gem name.

  • version (String)

    equal, less than or greater than specified version, e.g. ‘>= 2.0.0’,



235
236
237
# File 'lib/synvert/core/rewriter.rb', line 235

def if_gem(name, version)
  @gem_spec = Rewriter::GemSpec.new(name, version)
end

#if_ruby(version) ⇒ Object

Parse if_ruby dal, it checks if ruby version if greater than or equal to the specified ruby version.

Parameters:

  • version, (String)

    specified ruby version.



227
228
229
# File 'lib/synvert/core/rewriter.rb', line 227

def if_ruby(version)
  @ruby_version = Rewriter::RubyVersion.new(version)
end

#processObject

Process the rewriter. It will call the block.



178
179
180
# File 'lib/synvert/core/rewriter.rb', line 178

def process
  instance_eval(&@block)
end

#process_with_sandboxObject

Process rewriter with sandbox mode. It will call the block but doesn’t change any file.



184
185
186
187
188
189
190
191
# File 'lib/synvert/core/rewriter.rb', line 184

def process_with_sandbox
  @sandbox = true
  begin
    process
  ensure
    @sandbox = false
  end
end

#remove_file(filename) ⇒ Object

Parses remove_file dsl, it removes a file.

Parameters:

  • filename (String)

    file name.



278
279
280
281
282
283
# File 'lib/synvert/core/rewriter.rb', line 278

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) ⇒ String

Parse todo dsl, it sets todo of the rewriter. Or get todo.

Parameters:

  • todo_list (String)

    rewriter todo.

Returns:

  • (String)

    rewriter todo.



306
307
308
309
310
311
312
# File 'lib/synvert/core/rewriter.rb', line 306

def todo(todo = nil)
  if todo
    @todo = todo
  else
    @todo
  end
end

#within_files(file_pattern, options = {}, &block) ⇒ Object Also known as: within_file

Parse within_files dsl, it finds specified files. It creates a [Synvert::Core::Rewriter::Instance] to rewrite code.

Parameters:

  • file_pattern (String)

    pattern to find files, e.g. spec/*/_spec.rb

  • options (Hash) (defaults to: {})

    instance options.

  • block (Block)

    the block to rewrite code in the matching files.



245
246
247
248
249
250
251
# File 'lib/synvert/core/rewriter.rb', line 245

def within_files(file_pattern, options = {}, &block)
  return if @sandbox

  if (!@ruby_version || @ruby_version.match?) && (!@gem_spec || @gem_spec.match?)
    Rewriter::Instance.new(self, file_pattern, options, &block).process
  end
end