lib/reek/source/source_code.rb in reek-2.2.1 vs lib/reek/source/source_code.rb in reek-3.0.0
- old
+ new
@@ -1,26 +1,28 @@
require_relative '../cli/silencer'
Reek::CLI::Silencer.silently do
- require 'parser/current'
+ require 'parser/ruby22'
end
-require_relative '../core/tree_dresser'
-require_relative '../core/ast_node'
+require_relative '../tree_dresser'
+require_relative '../ast/node'
module Reek
+ # @api private
module Source
#
# A +Source+ object represents a chunk of Ruby source code.
#
+ # @api private
class SourceCode
attr_reader :description
# 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
- def initialize(code, description, parser = Parser::Ruby21)
+ def initialize(code, description, parser = Parser::Ruby22)
@source = code
@description = description
@parser = parser
end
@@ -28,34 +30,63 @@
# 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`
#
- # source - One of File|IO|String
+ # @param source [File|IO|String] - the given source
#
- # Returns an instance of SourceCode
+ # @return an instance of SourceCode
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
- # Parses the given source into an AST.
+ # 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
#
- # @return [Reek::Core::ASTNode] the AST presentation of the given source
+ # 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
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
- Core::TreeDresser.new.dress(ast, comment_map)
+ TreeDresser.new.dress(ast, comment_map)
end
end
end
end
end