fasterer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.fasterer.yml +17 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +93 -0
- data/Rakefile +7 -0
- data/bin/fasterer +5 -0
- data/fasterer.gemspec +28 -0
- data/lib/fasterer.rb +7 -0
- data/lib/fasterer/analyzer.rb +99 -0
- data/lib/fasterer/binary_call.rb +4 -0
- data/lib/fasterer/cli.rb +10 -0
- data/lib/fasterer/file_traverser.rb +81 -0
- data/lib/fasterer/method_call.rb +138 -0
- data/lib/fasterer/method_definition.rb +51 -0
- data/lib/fasterer/offense.rb +69 -0
- data/lib/fasterer/offense_collector.rb +17 -0
- data/lib/fasterer/parse_error.rb +10 -0
- data/lib/fasterer/parser.rb +11 -0
- data/lib/fasterer/rescue_call.rb +36 -0
- data/lib/fasterer/scanners/method_call_scanner.rb +134 -0
- data/lib/fasterer/scanners/method_definition_scanner.rb +52 -0
- data/lib/fasterer/scanners/offensive.rb +25 -0
- data/lib/fasterer/scanners/rescue_call_scanner.rb +28 -0
- data/lib/fasterer/token.rb +27 -0
- data/lib/fasterer/version.rb +3 -0
- data/spec/lib/fasterer/analyzer/01_parallel_assignment_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/02_rescue_vs_respond_to_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/03_module_eval_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/04_find_vs_bsearch_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/06_shuffle_first_vs_sample_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/08_for_loop_vs_each_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/09_each_with_index_vs_while_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/10_map_flatten_vs_flat_map_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/11_reverse_each_vs_reverse_each_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/12_select_first_vs_detect_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/13_sort_vs_sort_by_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/14_fetch_with_argument_vs_block_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/15_keys_each_vs_each_key_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/16_hash_merge_bang_vs_hash_brackets_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/18_block_vs_symbol_to_proc_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/19_proc_call_vs_yield_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/24_gsub_vs_tr_spec.rb +12 -0
- data/spec/lib/fasterer/analyzer/98_misc_spec.rb +11 -0
- data/spec/lib/fasterer/analyzer/99_exceptional_files_spec.rb +11 -0
- data/spec/lib/fasterer/method_call_spec.rb +483 -0
- data/spec/lib/fasterer/method_definition_spec.rb +93 -0
- data/spec/lib/fasterer/rescue_call_spec.rb +76 -0
- data/spec/spec_helper.rb +99 -0
- data/spec/support/analyzer/01_parallel_assignment.rb +10 -0
- data/spec/support/analyzer/02_rescue_vs_respond_to.rb +36 -0
- data/spec/support/analyzer/03_module_eval.rb +11 -0
- data/spec/support/analyzer/04_find_vs_bsearch.rb +5 -0
- data/spec/support/analyzer/06_shuffle_first_vs_sample.rb +5 -0
- data/spec/support/analyzer/08_for_loop_vs_each.rb +8 -0
- data/spec/support/analyzer/09_each_with_index_vs_while.rb +3 -0
- data/spec/support/analyzer/10_map_flatten_vs_flat_map.rb +15 -0
- data/spec/support/analyzer/11_reverse_each_vs_reverse_each.rb +9 -0
- data/spec/support/analyzer/12_select_first_vs_detect.rb +7 -0
- data/spec/support/analyzer/13_sort_vs_sort_by.rb +9 -0
- data/spec/support/analyzer/14_fetch_with_argument_vs_block.rb +11 -0
- data/spec/support/analyzer/15_keys_each_vs_each_key.rb +15 -0
- data/spec/support/analyzer/16_hash_merge_bang_vs_hash_brackets.rb +21 -0
- data/spec/support/analyzer/18_block_vs_symbol_to_proc.rb +30 -0
- data/spec/support/analyzer/19_proc_call_vs_yield.rb +24 -0
- data/spec/support/analyzer/24_gsub_vs_tr.rb +14 -0
- data/spec/support/analyzer/98_misc.rb +15 -0
- data/spec/support/analyzer/99_exceptional_files.rb +7 -0
- data/spec/support/binary_call/simple_comparison.rb +0 -0
- data/spec/support/method_call/method_call_on_constant.rb +1 -0
- data/spec/support/method_call/method_call_on_integer.rb +1 -0
- data/spec/support/method_call/method_call_on_method_call.rb +1 -0
- data/spec/support/method_call/method_call_on_string.rb +1 -0
- data/spec/support/method_call/method_call_on_variable.rb +2 -0
- data/spec/support/method_call/method_call_with_a_block.rb +5 -0
- data/spec/support/method_call/method_call_with_a_integer_argument.rb +1 -0
- data/spec/support/method_call/method_call_with_a_regex_argument.rb +1 -0
- data/spec/support/method_call/method_call_with_an_argument_and_a_block.rb +2 -0
- data/spec/support/method_call/method_call_with_an_implicit_receiver.rb +1 -0
- data/spec/support/method_call/method_call_with_an_implicit_receiver_and_no_brackets.rb +1 -0
- data/spec/support/method_call/method_call_with_an_implicit_receiver_and_no_brackets_and_do_end.rb +3 -0
- data/spec/support/method_call/method_call_with_equals.rb +1 -0
- data/spec/support/method_call/method_call_with_one_argument.rb +1 -0
- data/spec/support/method_call/method_call_with_two_arguments.rb +2 -0
- data/spec/support/method_call/method_call_without_brackets.rb +1 -0
- data/spec/support/method_definition/method_with_argument_and_block.rb +3 -0
- data/spec/support/method_definition/method_with_block.rb +3 -0
- data/spec/support/method_definition/method_with_default_argument.rb +3 -0
- data/spec/support/method_definition/method_with_splat_and_block.rb +3 -0
- data/spec/support/method_definition/simple_method.rb +2 -0
- data/spec/support/method_definition/simple_method_omitted_parenthesis.rb +2 -0
- data/spec/support/method_definition/simple_method_with_argument.rb +3 -0
- data/spec/support/rescue_call/plain_rescue.rb +7 -0
- data/spec/support/rescue_call/rescue_with_class.rb +5 -0
- data/spec/support/rescue_call/rescue_with_class_and_variable.rb +5 -0
- data/spec/support/rescue_call/rescue_with_multiple_classes.rb +4 -0
- data/spec/support/rescue_call/rescue_with_multiple_classes_and_variable.rb +5 -0
- data/spec/support/rescue_call/rescue_with_variable.rb +6 -0
- metadata +303 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 700f1de5e4957667423d3e045970c1046e86579f
|
4
|
+
data.tar.gz: 7c60c88efa59abe5857436f1a229a96b54f77e6d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 70b4baaf83af7c16e926245b5685b9a2b52568f4f81c279da6d0f70a68cd1af49b82dda342c43d0a4f5c4e6bb65ab027cb9fee19afdd0601be6815db660d2865
|
7
|
+
data.tar.gz: 26543c720eefaf8f678e4353d4a5837d336912def1359d300a3d3f45903ca1bf4e2185446e916ef9fdf4b74c4548e829989f1d2f9131f1438cd6180141435565
|
data/.fasterer.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
speedups:
|
2
|
+
parallel_assignment: false
|
3
|
+
rescue_vs_respond_to: true
|
4
|
+
module_eval: true
|
5
|
+
shuffle_first_vs_sample: true
|
6
|
+
for_loop_vs_each: true
|
7
|
+
each_with_index_vs_while: false
|
8
|
+
map_flatten_vs_flat_map: true
|
9
|
+
reverse_each_vs_reverse_each: true
|
10
|
+
select_first_vs_detect: true
|
11
|
+
sort_vs_sort_by: true
|
12
|
+
fetch_with_argument_vs_block: true
|
13
|
+
keys_each_vs_each_key: true
|
14
|
+
hash_merge_bang_vs_hash_brackets: true
|
15
|
+
block_vs_symbol_to_proc: true
|
16
|
+
proc_call_vs_yield: true
|
17
|
+
gsub_vs_tr: true
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Damir Svrtan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/DamirSvrtan/fasterer.svg?branch=master)](https://travis-ci.org/DamirSvrtan/fasterer)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/DamirSvrtan/fasterer/badges/gpa.svg)](https://codeclimate.com/github/DamirSvrtan/fasterer)
|
3
|
+
# Fasterer
|
4
|
+
|
5
|
+
Make your Rubies go faster with this command line tool highly inspired by [fast-ruby](https://github.com/JuanitoFatas/fast-ruby) and [Sferik's talk at Baruco Conf](https://speakerdeck.com/sferik/writing-fast-ruby).
|
6
|
+
|
7
|
+
Fasterer will suggest some speed improvements which you can check in detail at the [fast-ruby repo](https://github.com/JuanitoFatas/fast-ruby).
|
8
|
+
|
9
|
+
**Please note** that you shouldn't follow the suggestions blindly. Using a while loop instead of a each_with_index probably shouldn't be considered if you're doing a regular Rails project, but maybe if you're doing something very speed dependent such as Rack or if you're building your own framework, you might consider this speed increase.
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
```shell
|
16
|
+
gem install fasterer
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Run it from the root of your project:
|
22
|
+
|
23
|
+
```shell
|
24
|
+
fasterer
|
25
|
+
```
|
26
|
+
|
27
|
+
## Example output
|
28
|
+
|
29
|
+
```shell
|
30
|
+
|
31
|
+
app/models/post.rb
|
32
|
+
Array#select.first is slower than Array#detect. Occured at lines: 57, 61.
|
33
|
+
|
34
|
+
db/seeds/cities.rb
|
35
|
+
Hash#keys.each is slower than Hash#each_key. Occured at lines: 15, 33.
|
36
|
+
|
37
|
+
test/options_test.rb
|
38
|
+
Hash#merge! with one argument is slower than Hash#[]. Occured at lines: 84.
|
39
|
+
|
40
|
+
test/module_test.rb
|
41
|
+
Don't rescue NoMethodError, rather check with respond_to?. Occured at lines: 272.
|
42
|
+
|
43
|
+
spec/cache/mem_cache_store_spec.rb
|
44
|
+
Use tr instead of gsub when grepping plain strings. Occured at lines: 161.
|
45
|
+
```
|
46
|
+
## Configuration
|
47
|
+
|
48
|
+
You can turn of speed suggestions with a simple yaml file called **.fasterer.yml** in the root of your project. Example:
|
49
|
+
|
50
|
+
|
51
|
+
```yaml
|
52
|
+
speedups:
|
53
|
+
parallel_assignment: false
|
54
|
+
rescue_vs_respond_to: true
|
55
|
+
module_eval: true
|
56
|
+
shuffle_first_vs_sample: true
|
57
|
+
for_loop_vs_each: true
|
58
|
+
each_with_index_vs_while: false
|
59
|
+
map_flatten_vs_flat_map: true
|
60
|
+
reverse_each_vs_reverse_each: true
|
61
|
+
select_first_vs_detect: true
|
62
|
+
sort_vs_sort_by: true
|
63
|
+
fetch_with_argument_vs_block: true
|
64
|
+
keys_each_vs_each_key: true
|
65
|
+
hash_merge_bang_vs_hash_brackets: true
|
66
|
+
block_vs_symbol_to_proc: true
|
67
|
+
proc_call_vs_yield: true
|
68
|
+
gsub_vs_tr: true
|
69
|
+
```
|
70
|
+
|
71
|
+
## TODOs:
|
72
|
+
|
73
|
+
4. find vs bsearch
|
74
|
+
5. Array#count vs Array#size
|
75
|
+
7. Enumerable#each + push vs Enumerable#map
|
76
|
+
17. Hash#merge vs Hash#merge!
|
77
|
+
20. String#casecmp vs String#downcase + ==
|
78
|
+
21. String concatenation
|
79
|
+
22. String#match vs String#start_with?/String#end_with?
|
80
|
+
23. String#gsub vs String#sub
|
81
|
+
|
82
|
+
# New
|
83
|
+
|
84
|
+
values each -> each_value
|
85
|
+
class_eval
|
86
|
+
|
87
|
+
## Contributing
|
88
|
+
|
89
|
+
1. Fork it ( https://github.com/DamirSvrtan/fasterer/fork )
|
90
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
91
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
92
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
93
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/fasterer
ADDED
data/fasterer.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fasterer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'fasterer'
|
8
|
+
spec.version = Fasterer::VERSION
|
9
|
+
spec.authors = ['Damir Svrtan']
|
10
|
+
spec.email = ['damir.svrtan@gmail.com']
|
11
|
+
spec.summary = 'Run Ruby more than fast. Fasterer'
|
12
|
+
spec.description = 'Use Fasterer to check various places in your code that could be faster.'
|
13
|
+
spec.homepage = 'https://github.com/DamirSvrtan/fasterer'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'colorize', '~> 0.7'
|
22
|
+
spec.add_dependency 'ruby_parser', '~> 3.6'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
27
|
+
spec.add_development_dependency 'pry', '~> 0.10'
|
28
|
+
end
|
data/lib/fasterer.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'fasterer/method_definition'
|
2
|
+
require 'fasterer/method_call'
|
3
|
+
require 'fasterer/rescue_call'
|
4
|
+
require 'fasterer/offense_collector'
|
5
|
+
require 'fasterer/parser'
|
6
|
+
require 'fasterer/parse_error'
|
7
|
+
require 'fasterer/scanners/method_call_scanner'
|
8
|
+
require 'fasterer/scanners/rescue_call_scanner'
|
9
|
+
require 'fasterer/scanners/method_definition_scanner'
|
10
|
+
|
11
|
+
module Fasterer
|
12
|
+
class Analyzer
|
13
|
+
attr_reader :file_path
|
14
|
+
alias_method :path, :file_path
|
15
|
+
|
16
|
+
def initialize(file_path)
|
17
|
+
@file_path = file_path
|
18
|
+
@file_content = File.read(file_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def scan
|
22
|
+
sexp_tree = Fasterer::Parser.parse(@file_content)
|
23
|
+
fail ParseError.new(file_path) if sexp_tree.nil?
|
24
|
+
traverse_sexp_tree(sexp_tree)
|
25
|
+
end
|
26
|
+
|
27
|
+
def errors
|
28
|
+
@errors ||= Fasterer::OffenseCollector.new
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def traverse_sexp_tree(sexp_tree)
|
34
|
+
return unless sexp_tree.is_a?(Sexp)
|
35
|
+
|
36
|
+
token = sexp_tree.first
|
37
|
+
|
38
|
+
scan_by_token(token, sexp_tree)
|
39
|
+
|
40
|
+
case token
|
41
|
+
when :call, :iter
|
42
|
+
method_call = MethodCall.new(sexp_tree)
|
43
|
+
traverse_sexp_tree(method_call.receiver_element) if method_call.receiver_element
|
44
|
+
traverse_sexp_tree(method_call.arguments_element)
|
45
|
+
traverse_sexp_tree(method_call.block_body) if method_call.has_block?
|
46
|
+
else
|
47
|
+
sexp_tree.each { |element| traverse_sexp_tree(element) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def scan_by_token(token, element)
|
52
|
+
case token
|
53
|
+
when :defn
|
54
|
+
scan_method_definitions(element)
|
55
|
+
when :call, :iter
|
56
|
+
scan_method_calls(element)
|
57
|
+
when :masgn
|
58
|
+
scan_parallel_assignment(element)
|
59
|
+
when :for
|
60
|
+
scan_for_loop(element)
|
61
|
+
when :resbody
|
62
|
+
scan_rescue(element)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def scan_method_definitions(element)
|
67
|
+
method_definition_scanner = MethodDefinitionScanner.new(element)
|
68
|
+
|
69
|
+
if method_definition_scanner.offense_detected?
|
70
|
+
errors.push(method_definition_scanner.offense)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def scan_method_calls(element)
|
75
|
+
method_call_scanner = MethodCallScanner.new(element)
|
76
|
+
|
77
|
+
if method_call_scanner.offense_detected?
|
78
|
+
errors.push(method_call_scanner.offense)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def scan_parallel_assignment(element)
|
83
|
+
errors.push(Fasterer::Offense.new(:parallel_assignment, element.line))
|
84
|
+
end
|
85
|
+
|
86
|
+
def scan_for_loop(element)
|
87
|
+
errors.push(Fasterer::Offense.new(:for_loop_vs_each, element.line))
|
88
|
+
end
|
89
|
+
|
90
|
+
def scan_rescue(element)
|
91
|
+
rescue_call_scanner = RescueCallScanner.new(element)
|
92
|
+
|
93
|
+
if rescue_call_scanner.offense_detected?
|
94
|
+
errors.push(rescue_call_scanner.offense)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
data/lib/fasterer/cli.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'colorize'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require_relative 'analyzer'
|
6
|
+
|
7
|
+
module Fasterer
|
8
|
+
class FileTraverser
|
9
|
+
|
10
|
+
CONFIG_FILE_NAME = '.fasterer.yml'
|
11
|
+
|
12
|
+
attr_reader :ignored_speedups
|
13
|
+
|
14
|
+
def initialize(path)
|
15
|
+
@path = Pathname(path)
|
16
|
+
@parse_error_paths = []
|
17
|
+
set_ignored_speedups
|
18
|
+
end
|
19
|
+
|
20
|
+
def traverse
|
21
|
+
if @path.directory?
|
22
|
+
traverse_directory(@path)
|
23
|
+
else
|
24
|
+
scan_file(@path)
|
25
|
+
end
|
26
|
+
output_parse_errors if parse_error_paths.any?
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_ignored_speedups
|
30
|
+
@ignored_speedups = if config_file
|
31
|
+
config_file['speedups'].select {|_, value| value == false }.keys.map(&:to_sym)
|
32
|
+
end || []
|
33
|
+
end
|
34
|
+
|
35
|
+
def config_file
|
36
|
+
File.exists?(CONFIG_FILE_NAME) && YAML.load_file(CONFIG_FILE_NAME)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :parse_error_paths
|
42
|
+
|
43
|
+
def scan_file(path)
|
44
|
+
analyzer = Analyzer.new(path)
|
45
|
+
analyzer.scan
|
46
|
+
rescue Fasterer::ParseError, RubyParser::SyntaxError, Racc::ParseError
|
47
|
+
parse_error_paths.push(path)
|
48
|
+
else
|
49
|
+
output(analyzer) if offenses_grouped_by_type(analyzer).any?
|
50
|
+
end
|
51
|
+
|
52
|
+
def traverse_directory(path)
|
53
|
+
Dir["#{path}/**/*.rb"].each do |ruby_file|
|
54
|
+
scan_file(ruby_file.split('/').drop(1).join('/'))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def output(analyzer)
|
59
|
+
puts analyzer.file_path.colorize(:red)
|
60
|
+
|
61
|
+
offenses_grouped_by_type(analyzer).each do |error_group_name, error_occurences|
|
62
|
+
puts "#{Fasterer::Offense::EXPLANATIONS[error_group_name]}. Occured at lines: #{error_occurences.map(&:line_number).join(', ')}."
|
63
|
+
end
|
64
|
+
|
65
|
+
puts
|
66
|
+
end
|
67
|
+
|
68
|
+
def offenses_grouped_by_type(analyzer)
|
69
|
+
analyzer.errors.group_by(&:name).delete_if {|offense_name, _| ignored_speedups.include?(offense_name) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def output_parse_errors
|
73
|
+
puts 'Fasterer was unable to process some files because the'
|
74
|
+
puts 'internal parser is not able to read some characters.'
|
75
|
+
puts 'Unprocessable files were:'
|
76
|
+
puts '-----------------------------------------------------'
|
77
|
+
puts parse_error_paths
|
78
|
+
puts
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|