Class: Parser::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/parser/runner.rb

Direct Known Subclasses

RubyParse, RubyRewrite

Defined Under Namespace

Classes: RubyParse, RubyRewrite

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRunner

Returns a new instance of Runner.



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/parser/runner.rb', line 15

def initialize
  @slop         = Slop.new(:strict => true)
  @parser_class = nil
  @parser       = nil
  @files        = []
  @fragments    = []

  @source_count = 0
  @source_size  = 0

  setup_option_parsing
end

Class Method Details

.go(options) ⇒ Object



11
12
13
# File 'lib/parser/runner.rb', line 11

def self.go(options)
  new.execute(options)
end

Instance Method Details

#execute(options) ⇒ Object



28
29
30
31
32
33
# File 'lib/parser/runner.rb', line 28

def execute(options)
  parse_options(options)
  prepare_parser

  process_all_input
end

#input_sizeObject (private)



126
127
128
# File 'lib/parser/runner.rb', line 126

def input_size
  @files.size + @fragments.size
end

#parse_options(options) ⇒ Object (private)



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/parser/runner.rb', line 90

def parse_options(options)
  @slop.parse!(options)

  # Slop has just removed recognized options from `options`.
  options.each do |file_or_dir|
    if File.directory?(file_or_dir)
      Find.find(file_or_dir) do |path|
        @files << path if path.end_with? '.rb'
      end
    else
      @files << file_or_dir
    end
  end

  if @files.empty? && @fragments.empty?
    $stderr.puts "Need something to parse!"
    exit 1
  end

  if @parser_class.nil?
    require 'parser/current'
    @parser_class = Parser::CurrentRuby
  end
end

#prepare_parserObject (private)



115
116
117
118
119
120
121
122
123
124
# File 'lib/parser/runner.rb', line 115

def prepare_parser
  @parser = @parser_class.new

  @parser.diagnostics.all_errors_are_fatal = true
  @parser.diagnostics.ignore_warnings      = !@slop.warnings?

  @parser.diagnostics.consumer = lambda do |diagnostic|
    puts(diagnostic.render)
  end
end

#process(buffer) ⇒ Object (private)

Raises:

  • (NotImplementedError)


176
177
178
# File 'lib/parser/runner.rb', line 176

def process(buffer)
  raise NotImplementedError, "implement #{self.class}##{__callee__}"
end

#process_all_inputObject (private)



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/parser/runner.rb', line 130

def process_all_input
  parsing_time =
    Benchmark.measure do
      process_fragments
      process_files
    end

  if @slop.benchmark?
    report_with_time(parsing_time)
  end
end

#process_buffer(buffer) ⇒ Object (private)



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/parser/runner.rb', line 160

def process_buffer(buffer)
  @parser.reset

  process(buffer)

  @source_count += 1
  @source_size  += buffer.source.size

rescue Parser::SyntaxError
  # skip

rescue StandardError
  $stderr.puts("Failed on: #{buffer.name}")
  raise
end

#process_filesObject (private)



151
152
153
154
155
156
157
158
# File 'lib/parser/runner.rb', line 151

def process_files
  @files.each do |filename|
    buffer = Parser::Source::Buffer.new(filename)
    buffer.read

    process_buffer(buffer)
  end
end

#process_fragmentsObject (private)



142
143
144
145
146
147
148
149
# File 'lib/parser/runner.rb', line 142

def process_fragments
  @fragments.each_with_index do |fragment, index|
    buffer = Source::Buffer.new("(fragment:#{index})")
    buffer.source = fragment

    process_buffer(buffer)
  end
end

#report_with_time(parsing_time) ⇒ Object (private)



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/parser/runner.rb', line 180

def report_with_time(parsing_time)
  cpu_time = parsing_time.utime

  speed = '%.3f' % (@source_size / cpu_time / 1000)
  puts "Parsed #{@source_count} files (#{@source_size} characters)" \
       " in #{'%.2f' % cpu_time} seconds (#{speed} kchars/s)."

  if defined?(RUBY_ENGINE)
    engine = RUBY_ENGINE
  else
    engine = 'ruby'
  end

  puts "Running on #{engine} #{RUBY_VERSION}."
end

#runner_nameObject (private)

Raises:

  • (NotImplementedError)


37
38
39
# File 'lib/parser/runner.rb', line 37

def runner_name
  raise NotImplementedError, "implement #{self.class}##{__callee__}"
end

#setup_option_parsingObject (private)



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/parser/runner.rb', line 41

def setup_option_parsing
  @slop.banner "Usage: #{runner_name} [options] FILE|DIRECTORY..."

  @slop.on 'h', 'help', 'Display this help message and exit', :tail => true do
    puts @slop.help
    puts <<-HELP

  If you specify a DIRECTORY, then all *.rb files are fetched
  from it recursively and appended to the file list.

  The default parsing mode is for current Ruby (#{RUBY_VERSION}).
    HELP
    exit
  end

  @slop.on 'V', 'version', 'Output version information and exit', :tail => true do
    puts "#{runner_name} based on parser version #{Parser::VERSION}"
    exit
  end

  @slop.on '18', 'Parse as Ruby 1.8.7 would' do
    require 'parser/ruby18'
    @parser_class = Parser::Ruby18
  end

  @slop.on '19', 'Parse as Ruby 1.9.3 would' do
    require 'parser/ruby19'
    @parser_class = Parser::Ruby19
  end

  @slop.on '20', 'Parse as Ruby 2.0.0 would' do
    require 'parser/ruby20'
    @parser_class = Parser::Ruby20
  end

  @slop.on '21', 'Parse as Ruby trunk would (use with caution)' do
    require 'parser/ruby21'
    @parser_class = Parser::Ruby21
  end

  @slop.on 'w',  'warnings',  'Enable warnings'

  @slop.on 'B',  'benchmark', 'Benchmark the processor'

  @slop.on 'e=', 'Process a fragment of Ruby code' do |fragment|
    @fragments << fragment
  end
end