Class: RubyLint::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-lint/runner.rb

Overview

Runner acts as an easy to use layer around the various parts of ruby-lint. Pass it some files and a Configuration object and it will take care of running code analysis, formatting it, etc.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Runner

Returns a new instance of Runner

Parameters:



16
17
18
# File 'lib/ruby-lint/runner.rb', line 16

def initialize(configuration)
  @configuration = configuration
end

Instance Attribute Details

#configurationRubyLint::Configuration (readonly)



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/ruby-lint/runner.rb', line 10

class Runner
  attr_reader :configuration

  ##
  # @param [RubyLint::Configuration] configuration
  #
  def initialize(configuration)
    @configuration = configuration
  end

  ##
  # Analyses the given files and returns the report results.
  #
  # @param [Array] files
  # @return [String]
  #
  def analyze(files)
    report    = Report.new(configuration.report_levels)
    presenter = configuration.presenter.new
    parser    = Parser.new

    parser.consumer = proc do |diag|
      report_diagnostic(diag, report)
    end

    files.each do |file|
      analyze_file(file, parser, report)
    end

    return presenter.present(report)
  end

  private

  ##
  # @param [String] file
  # @param [RubyLint::Parser] parser
  # @param [RubyLint::Report] report
  #
  def analyze_file(file, parser, report)
    ast, comments = parse_file(parser, file)

    extra_ast, extra_comments = process_external_files(ast)

    extra_ast.push(ast)

    comments.merge!(extra_comments)

    vm = run_vm(extra_ast, comments)

    run_analysis(ast, vm, report)
  end

  ##
  # Parses the given file and returns an Array containing all the associated
  # AST nodes and comments.
  #
  # @param [RubyLint::Parser] parser
  # @param [String] file
  # @return [Array]
  #
  def parse_file(parser, file)
    return parser.parse(File.read(file, :encoding => Encoding::UTF_8), file)
  end

  ##
  # Processes external Ruby files using {RubyLint::FileLoader}. The return
  # value is a collection of AST nodes and a Hash containing all the
  # associated comments.
  #
  # @param [RubyLint::AST::Node] root_ast
  # @return [Array]
  #
  def process_external_files(root_ast)
    loader = FileLoader.new(
      :directories  => configuration.directories,
      :ignore_paths => configuration.ignore_paths
    )

    nodes    = []
    comments = {}

    loader.iterate(root_ast)

    loader.nodes.each do |(ast, comment_associations)|
      nodes << ast

      comments.merge!(comment_associations)
    end

    return nodes, comments
  end

  ##
  # @param [Parser::Diagnostic] diagnostic
  # @param [RubyLint::Report] report
  #
  def report_diagnostic(diagnostic, report)
    report.add(
      :level   => diagnostic.level,
      :message => diagnostic.message,
      :line    => diagnostic.location.line,
      :column  => diagnostic.location.column + 1,
      :file    => diagnostic.location.source_buffer.name
    )
  end

  ##
  # @param [Array] nodes
  # @param [Hash] comments
  # @return [RubyLint::VirtualMachine]
  #
  def run_vm(nodes, comments)
    vm = RubyLint::VirtualMachine.new(:comments => comments)

    vm.run(nodes)

    return vm
  end

  ##
  # Runs all the registered analysis classes.
  #
  # @param [RubyLint::AST::Node] ast
  # @param [RubyLint::VirtualMachine] vm
  # @param [RubyLint::Report] report
  #
  def run_analysis(ast, vm, report)
    classes = configuration.analysis_classes.select do |const|
      const.analyze?(ast, vm)
    end

    classes.each do |const|
      instance = const.new(
        :vm     => vm,
        :report => report,
        :config => configuration
      )

      instance.iterate(ast)
    end
  end
end

Instance Method Details

#analyze(files) ⇒ String

Analyses the given files and returns the report results.

Parameters:

  • files (Array)

Returns:



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ruby-lint/runner.rb', line 26

def analyze(files)
  report    = Report.new(configuration.report_levels)
  presenter = configuration.presenter.new
  parser    = Parser.new

  parser.consumer = proc do |diag|
    report_diagnostic(diag, report)
  end

  files.each do |file|
    analyze_file(file, parser, report)
  end

  return presenter.present(report)
end

#analyze_file(file, parser, report) ⇒ Object (private)

Parameters:



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ruby-lint/runner.rb', line 49

def analyze_file(file, parser, report)
  ast, comments = parse_file(parser, file)

  extra_ast, extra_comments = process_external_files(ast)

  extra_ast.push(ast)

  comments.merge!(extra_comments)

  vm = run_vm(extra_ast, comments)

  run_analysis(ast, vm, report)
end

#parse_file(parser, file) ⇒ Array (private)

Parses the given file and returns an Array containing all the associated AST nodes and comments.

Parameters:

Returns:

  • (Array)


71
72
73
# File 'lib/ruby-lint/runner.rb', line 71

def parse_file(parser, file)
  return parser.parse(File.read(file, :encoding => Encoding::UTF_8), file)
end

#process_external_files(root_ast) ⇒ Array (private)

Processes external Ruby files using FileLoader. The return value is a collection of AST nodes and a Hash containing all the associated comments.

Parameters:

Returns:

  • (Array)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ruby-lint/runner.rb', line 83

def process_external_files(root_ast)
  loader = FileLoader.new(
    :directories  => configuration.directories,
    :ignore_paths => configuration.ignore_paths
  )

  nodes    = []
  comments = {}

  loader.iterate(root_ast)

  loader.nodes.each do |(ast, comment_associations)|
    nodes << ast

    comments.merge!(comment_associations)
  end

  return nodes, comments
end

#report_diagnostic(diagnostic, report) ⇒ Object (private)

Parameters:



107
108
109
110
111
112
113
114
115
# File 'lib/ruby-lint/runner.rb', line 107

def report_diagnostic(diagnostic, report)
  report.add(
    :level   => diagnostic.level,
    :message => diagnostic.message,
    :line    => diagnostic.location.line,
    :column  => diagnostic.location.column + 1,
    :file    => diagnostic.location.source_buffer.name
  )
end

#run_analysis(ast, vm, report) ⇒ Object (private)

Runs all the registered analysis classes.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/ruby-lint/runner.rb', line 137

def run_analysis(ast, vm, report)
  classes = configuration.analysis_classes.select do |const|
    const.analyze?(ast, vm)
  end

  classes.each do |const|
    instance = const.new(
      :vm     => vm,
      :report => report,
      :config => configuration
    )

    instance.iterate(ast)
  end
end

#run_vm(nodes, comments) ⇒ RubyLint::VirtualMachine (private)

Parameters:

  • nodes (Array)
  • comments (Hash)

Returns:



122
123
124
125
126
127
128
# File 'lib/ruby-lint/runner.rb', line 122

def run_vm(nodes, comments)
  vm = RubyLint::VirtualMachine.new(:comments => comments)

  vm.run(nodes)

  return vm
end