Class: Reek::Source::SourceCode Private

Inherits:
Object
  • Object
show all
Defined in:
lib/reek/source/source_code.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

A Source object represents a chunk of Ruby source code.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(code, description, parser = Parser::Ruby22) ⇒ SourceCode

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializer.

code - ruby code as String description - in case of STDIN this is “STDIN” otherwise it’s a filepath as String parser - the parser to use for generating AST’s out of the given source



23
24
25
26
27
# File 'lib/reek/source/source_code.rb', line 23

def initialize(code, description, parser = Parser::Ruby22)
  @source      = code
  @description = description
  @parser      = parser
end

Instance Attribute Details

#descriptionObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



16
17
18
# File 'lib/reek/source/source_code.rb', line 16

def description
  @description
end

Class Method Details

.from(source) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes an instance of SourceCode given a source. This source can come via 3 different ways:

  • from files a la ‘reek lib/reek/`

  • from IO (STDIN) a la ‘echo “class Foo; end” | reek`

  • from String via our rspec matchers a la ‘expect(“class Foo; end”).to reek`

Parameters:

  • source (File|IO|String)
    • the given source

Returns:

  • an instance of SourceCode



38
39
40
41
42
43
44
# File 'lib/reek/source/source_code.rb', line 38

def self.from(source)
  case source
  when File   then new(source.read, source.path)
  when IO     then new(source.readlines.join, 'STDIN')
  when String then new(source, 'string')
  end
end

Instance Method Details

#syntax_treeObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parses the given source into an AST and associates the source code comments with it. This AST is then traversed by a TreeDresser which adorns the nodes in the AST with our SexpExtensions. Finally this AST is returned where each node is an anonymous subclass of Reek::AST::Node

Important to note is that reek will not fail on unparseable files but rather print out a warning and then just continue.

Given this @source:

# comment about C
class C
  def m
    puts 'nada'
  end
end

this method would return something that looks like

(class
  (const nil :C) nil
  (def :m
    (args)
    (send nil :puts
      (str "nada"))))

where each node is possibly adorned with our SexpExtensions (see ast/ast_node_class_map and ast/sexp_extensions for details).

@return [Anonymous subclass of Reek::AST::Node] the AST presentation
        for the given source


77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/reek/source/source_code.rb', line 77

def syntax_tree
  @syntax_tree ||=
    begin
      begin
        ast, comments = @parser.parse_with_comments(@source, @description)
      rescue Racc::ParseError, Parser::SyntaxError => error
        $stderr.puts "#{description}: #{error.class.name}: #{error}"
      end

      # See https://whitequark.github.io/parser/Parser/Source/Comment/Associator.html
      comment_map = Parser::Source::Comment.associate(ast, comments) if ast
      TreeDresser.new.dress(ast, comment_map)
    end
end