code_analyzer 0.5.1 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 792496737344902c984457c4a153f5e7e5717e7f9568f130cdc039c1779e9627
4
- data.tar.gz: 8b15a24c9ede966353b1100328fe1d5dcc14937fc6d2a4401a455cfe42176d27
3
+ metadata.gz: 4c37841a3a698b9ce2fa6c4aa80b0a03eb204a4f6ae43e3a0c8d48e78c5f8916
4
+ data.tar.gz: f4e3b26a9afb7ce80266d590a98e5f838944b9a892a8748374828aa4387aa592
5
5
  SHA512:
6
- metadata.gz: 2bd9cd8d09ffaab831f417207e0003082408ddb61e8a513884a0d137adb567c1c6f3aed5f68d2460d58a5799ef56a514cb49af4d1c5f2b92b017500193709e54
7
- data.tar.gz: dd4bf2b587ca333c7eeabcd088586eeebc421c9e41931d1637a7dd0bb3f1b403959b95c0cc697eb81cd6d818e198f4648b1fc8e1d585c8896600f528ec2511fe
6
+ metadata.gz: 60042c122b97be0ece07e2898f245430f4ff8d11f61d68008de00f1a37bd8fa4022d33f98f5d3d13c04138afaa4c6ce724ead33be9ead570b8194809742b7eb7
7
+ data.tar.gz: e4ee8925dadae37e1a594c114a0ddff4e09e2adabdc92621284323bdd2cb9247b4ec0829a252b6e3050dac5453c250b98b61d3b44f513bbae77aa45bac5c5ac1
@@ -0,0 +1,31 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: CI
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ matrix:
21
+ ruby-version: ['2.6', '2.7', '3.0', '3.1']
22
+
23
+ steps:
24
+ - uses: actions/checkout@v2
25
+ - name: Set up Ruby
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby-version }}
29
+ bundler-cache: true
30
+ - name: Run tests
31
+ run: bundle exec rspec spec
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.0
data/README.md CHANGED
@@ -1,11 +1,6 @@
1
1
  # CodeAnalyzer
2
2
 
3
- | Project | code_analyzer
4
- |:---------|:--------------------------------------------
5
- | Homepage | https://github.com/flyerhzm/code_analyzer
6
- | Document | http://rubydoc.info/gems/code_analyzer/frames
7
- | CI | [![Build Status](https://travis-ci.org/flyerhzm/code_analyzer.png)](https://travis-ci.org/flyerhzm/code_analyzer)
8
- | Author | [Richard Huang][0]
3
+ [![CI](https://github.com/flyerhzm/code_analyzer/actions/workflows/main.yml/badge.svg)](https://github.com/flyerhzm/code_analyzer/actions/workflows/main.yml)
9
4
 
10
5
  code_analyzer is extracted from [rails_best_practices][1], it helps you
11
6
  easily build your own code analyzer tool.
@@ -36,5 +31,4 @@ Or install it yourself as:
36
31
  4. Push to the branch (`git push origin my-new-feature`)
37
32
  5. Create new Pull Request
38
33
 
39
- [0]: http://huangzhimin.com
40
34
  [1]: https://github.com/railsbp/rails_best_practices
@@ -1,4 +1,5 @@
1
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  require File.expand_path('../lib/code_analyzer/version', __FILE__)
3
4
 
4
5
  Gem::Specification.new do |gem|
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer
3
4
  class AnalyzerException < Exception; end
4
5
  end
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer
3
4
  # A checker class that takes charge of checking the sexp.
4
5
  class Checker
@@ -28,8 +29,7 @@ module CodeAnalyzer
28
29
  # @param [Sexp] node
29
30
  def node_start(node)
30
31
  @node = node
31
- self.class.get_callbacks("start_#{node.sexp_type}".to_sym)
32
- .each { |block| self.instance_exec(node, &block) }
32
+ self.class.get_callbacks("start_#{node.sexp_type}".to_sym).each { |block| self.instance_exec(node, &block) }
33
33
  end
34
34
 
35
35
  # delegate to end_### according to the sexp_type, like
@@ -40,9 +40,7 @@ module CodeAnalyzer
40
40
  # @param [Sexp] node
41
41
  def node_end(node)
42
42
  @node = node
43
- self.class.get_callbacks("end_#{node.sexp_type}".to_sym).each do |block|
44
- self.instance_exec(node, &block)
45
- end
43
+ self.class.get_callbacks("end_#{node.sexp_type}".to_sym).each { |block| self.instance_exec(node, &block) }
46
44
  end
47
45
 
48
46
  # add an warning.
@@ -50,13 +48,8 @@ module CodeAnalyzer
50
48
  # @param [String] message, is the warning message
51
49
  # @param [String] filename, is the filename of source code
52
50
  # @param [Integer] line_number, is the line number of the source code which is reviewing
53
- def add_warning(
54
- message, filename = @node.file, line_number = @node.line_number
55
- )
56
- warnings <<
57
- Warning.new(
58
- filename: filename, line_number: line_number, message: message
59
- )
51
+ def add_warning(message, filename = @node.file, line_number = @node.line_number)
52
+ warnings << Warning.new(filename: filename, line_number: line_number, message: message)
60
53
  end
61
54
 
62
55
  # all warnings.
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer::CheckingVisitor
3
4
  # Base class for checking visitor.
4
5
  class Base
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer::CheckingVisitor
3
4
  # This is the default checking visitor to check ruby sexp nodes.
4
5
  class Default < Base
@@ -39,9 +40,7 @@ module CodeAnalyzer::CheckingVisitor
39
40
  def parse(filename, content)
40
41
  Sexp.from_array(Ripper::SexpBuilder.new(content).parse)
41
42
  rescue Exception
42
- raise AnalyzerException.new(
43
- "#{filename} looks like it's not a valid Ruby file. Skipping..."
44
- )
43
+ raise AnalyzerException.new("#{filename} looks like it's not a valid Ruby file. Skipping...")
45
44
  end
46
45
 
47
46
  # recursively check ruby sexp node.
@@ -51,20 +50,14 @@ module CodeAnalyzer::CheckingVisitor
51
50
  # 3. it triggers the interesting checkers' end callbacks.
52
51
  def check_node(node)
53
52
  checkers = @checks[node.sexp_type]
54
- if checkers
55
- checkers.each do |checker|
56
- checker.node_start(node) if checker.parse_file?(node.file)
57
- end
58
- end
53
+
54
+ checkers.each { |checker| checker.node_start(node) if checker.parse_file?(node.file) } if checkers
59
55
  node.children.each do |child_node|
60
56
  child_node.file = node.file
61
57
  check_node(child_node)
62
58
  end
63
- if checkers
64
- checkers.each do |checker|
65
- checker.node_end(node) if checker.parse_file?(node.file)
66
- end
67
- end
59
+
60
+ checkers.each { |checker| checker.node_end(node) if checker.parse_file?(node.file) } if checkers
68
61
  end
69
62
  end
70
63
  end
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer::CheckingVisitor
3
4
  # This is the checking visitor to check ruby plain code.
4
5
  class Plain < Base
@@ -7,9 +8,7 @@ module CodeAnalyzer::CheckingVisitor
7
8
  # @param [String] filename is the filename of ruby code.
8
9
  # @param [String] content is the content of ruby file.
9
10
  def check(filename, content)
10
- @checkers.each do |checker|
11
- checker.check(filename, content) if checker.parse_file?(filename)
12
- end
11
+ @checkers.each { |checker| checker.check(filename, content) if checker.parse_file?(filename) }
13
12
  end
14
13
  end
15
14
  end
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer
3
4
  module CheckingVisitor
4
5
  autoload :Base, 'code_analyzer/checking_visitor/base'
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer
3
4
  # Fake nil.
4
5
  class Nil
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'sexp'
3
4
 
4
5
  class Sexp
@@ -13,21 +14,23 @@ class Sexp
13
14
  #
14
15
  # s(:@ident, "test", s(2, 12)
15
16
  # => 2
17
+
16
18
  def line_number
17
19
  case sexp_type
18
- when :def, :defs, :command, :command_call, :call, :fcall, :method_add_arg, :method_add_block,
19
- :var_ref, :vcall, :const_ref, :const_path_ref, :class, :module, :if, :unless,
20
- :elsif, :ifop, :if_mod, :unless_mod, :binary, :alias, :symbol_literal, :symbol,
21
- :aref, :hash, :assoc_new, :string_literal, :massign, :var_field
20
+ when :def, :defs, :command, :command_call, :call, :fcall, :method_add_arg, :method_add_block, :var_ref, :vcall,
21
+ :const_ref, :top_const_ref, :const_path_ref, :class, :module, :if, :unless, :elsif, :ifop, :if_mod, :unless_mod, :binary, :alias,
22
+ :symbol_literal, :symbol, :aref, :hash, :assoc_new, :string_literal, :massign, :var_field, :assign, :paren, :dot2, :dot3
22
23
  self[1].line_number
23
24
  when :assoclist_from_args, :bare_assoc_hash
24
25
  self[1][0].line_number
25
- when :string_add, :opassign
26
+ when :string_add, :opassign, :unary, :stmts_add
26
27
  self[2].line_number
27
28
  when :array
28
29
  array_values.first.line_number
29
30
  when :mlhs_add
30
31
  self.last.line_number
32
+ when :params
33
+ self[1][0].line_number if self[1].is_a? Array
31
34
  else
32
35
  self.last.first if self.last.is_a? Array
33
36
  end
@@ -68,45 +71,16 @@ class Sexp
68
71
  to_s = options[:to_s]
69
72
  self.recursive_children do |child|
70
73
  if (
71
- !sexp_type ||
72
- (
73
- if sexp_type.is_a?(Array)
74
- sexp_type.include?(child.sexp_type)
75
- else
76
- sexp_type == child.sexp_type
77
- end
78
- )
79
- ) &&
80
- (
81
- !receiver ||
82
- (
83
- if receiver.is_a?(Array)
84
- receiver.include?(child.receiver.to_s)
85
- else
86
- receiver == child.receiver.to_s
87
- end
88
- )
89
- ) &&
90
- (
91
- !message ||
92
- (
93
- if message.is_a?(Array)
94
- message.include?(child.message.to_s)
95
- else
96
- message == child.message.to_s
97
- end
98
- )
74
+ !sexp_type || (sexp_type.is_a?(Array) ? sexp_type.include?(child.sexp_type) : sexp_type == child.sexp_type)
99
75
  ) &&
100
- (
101
- !to_s ||
102
- (
103
- if to_s.is_a?(Array)
104
- to_s.include?(child.to_s)
105
- else
106
- to_s == child.to_s
107
- end
108
- )
109
- )
76
+ (
77
+ !receiver ||
78
+ (receiver.is_a?(Array) ? receiver.include?(child.receiver.to_s) : receiver == child.receiver.to_s)
79
+ ) &&
80
+ (
81
+ !message || (message.is_a?(Array) ? message.include?(child.message.to_s) : message == child.message.to_s)
82
+ ) &&
83
+ (!to_s || (to_s.is_a?(Array) ? to_s.include?(child.to_s) : to_s == child.to_s))
110
84
  yield child
111
85
  end
112
86
  end
@@ -391,14 +365,12 @@ class Sexp
391
365
  def all_conditions
392
366
  nodes = []
393
367
  if :binary == sexp_type && %w[&& || and or].include?(self[2].to_s)
394
- if :binary == self[1].sexp_type &&
395
- %w[&& || and or].include?(self[1][2].to_s)
368
+ if :binary == self[1].sexp_type && %w[&& || and or].include?(self[1][2].to_s)
396
369
  nodes += self[1].all_conditions
397
370
  else
398
371
  nodes << self[1]
399
372
  end
400
- if :binary == self[3].sexp_type &&
401
- %w[&& || and or].include?(self[3][2].to_s)
373
+ if :binary == self[3].sexp_type && %w[&& || and or].include?(self[3][2].to_s)
402
374
  nodes += self[3].all_conditions
403
375
  else
404
376
  nodes << self[3]
@@ -418,6 +390,7 @@ class Sexp
418
390
  # => s(:@ident, "show", s(1, 4)),
419
391
  #
420
392
  # @return [Sexp] method name node
393
+
421
394
  def method_name
422
395
  case sexp_type
423
396
  when :def
@@ -455,6 +428,7 @@ class Sexp
455
428
  # )
456
429
  #
457
430
  # @return [Sexp] body node
431
+
458
432
  def body
459
433
  case sexp_type
460
434
  when :else
@@ -571,6 +545,7 @@ class Sexp
571
545
  def exception_classes
572
546
  if :rescue == sexp_type
573
547
  return [] unless self[1]
548
+
574
549
  if :mrhs_add == self[1].sexp_type
575
550
  exceptions = Array.new(self[1][2])
576
551
  arg_nodes = self[1][1][1]
@@ -621,11 +596,8 @@ class Sexp
621
596
  else
622
597
 
623
598
  end
624
- if pair_nodes
625
- pair_nodes.size.times do |i|
626
- return pair_nodes[i][2] if key == pair_nodes[i][1].to_s
627
- end
628
- end
599
+
600
+ pair_nodes.size.times { |i| return pair_nodes[i][2] if key == pair_nodes[i][1].to_s } if pair_nodes
629
601
  CodeAnalyzer::Nil.new
630
602
  end
631
603
 
@@ -716,6 +688,31 @@ class Sexp
716
688
  end
717
689
  end
718
690
 
691
+ # Get the hash key
692
+ #
693
+ # s(:assoc_new, s(:@label, "first_name:", s(1, 1)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14)))))
694
+ # =>
695
+ # s(:@label, "first_name:", s(1, 1))
696
+ def key
697
+ if :assoc_new == sexp_type
698
+ self[1].to_s
699
+ end
700
+ end
701
+
702
+ # Get the hash value
703
+ #
704
+ # s(:assoc_new, s(:@label, "first_name:", s(1, 1)), s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14)))))
705
+ # =>
706
+ # s(:string_literal, s(:string_add, s(:string_content), s(:@tstring_content, "Richard", s(1, 14))))
707
+ def value
708
+ if :assoc_new == sexp_type
709
+ return nil if self[2].nil?
710
+ return self[2] if :array == self[2].sexp_type
711
+
712
+ self[2].to_s
713
+ end
714
+ end
715
+
719
716
  # Get the array size.
720
717
  #
721
718
  # s(:array,
@@ -734,12 +731,9 @@ class Sexp
734
731
  if first_node
735
732
  while true
736
733
  array_size += 1
737
- first_node =
738
- s(:args_new) == first_node[1] ? first_node[2] : first_node[1]
734
+ first_node = s(:args_new) == first_node[1] ? first_node[2] : first_node[1]
739
735
  if :args_add != first_node.sexp_type
740
- if :array == first_node.sexp_type
741
- array_size += first_node.array_size
742
- end
736
+ array_size += first_node.array_size if :array == first_node.sexp_type
743
737
  break
744
738
  end
745
739
  end
@@ -765,13 +759,9 @@ class Sexp
765
759
  def array_values
766
760
  case sexp_type
767
761
  when :array
768
- if nil == self[1] ||
769
- %i[words_new qwords_new symbols_new qsymbols_new].include?(
770
- self[1].sexp_type
771
- )
762
+ if nil == self[1] || %i[words_new qwords_new symbols_new qsymbols_new].include?(self[1].sexp_type)
772
763
  []
773
- elsif %i[words_add qwords_add symbols_add qsymbols_add].include? self[1]
774
- .sexp_type
764
+ elsif %i[words_add qwords_add symbols_add qsymbols_add].include? self[1].sexp_type
775
765
  self[1].array_values
776
766
  else
777
767
  arguments.all
@@ -780,12 +770,10 @@ class Sexp
780
770
  values = []
781
771
  node = self
782
772
  while true
783
- if %i[words_add qwords_add symbols_add qsymbols_add].include? node
784
- .sexp_type
773
+ if %i[words_add qwords_add symbols_add qsymbols_add].include? node.sexp_type
785
774
  values.unshift node[2]
786
775
  node = node[1]
787
- elsif %i[words_new qwords_new symbols_new qsymbols_new].include? node
788
- .sexp_type
776
+ elsif %i[words_new qwords_new symbols_new qsymbols_new].include? node.sexp_type
789
777
  break
790
778
  end
791
779
  end
@@ -842,9 +830,8 @@ class Sexp
842
830
  # @return [String] to_s
843
831
  def to_s
844
832
  case sexp_type
845
- when :string_literal, :xstring_literal, :string_content, :const_ref,
846
- :symbol_literal, :symbol, :args_add_block, :var_ref, :vcall, :var_field,
847
- :@ident, :@tstring_content, :@const, :@ivar, :@kw, :@gvar, :@cvar, :@period
833
+ when :string_literal, :xstring_literal, :string_content, :const_ref, :symbol_literal, :symbol, :args_add_block, :var_ref,
834
+ :vcall, :var_field, :@ident, :@tstring_content, :@const, :@ivar, :@kw, :@gvar, :@cvar, :@period
848
835
  self[1].to_s
849
836
  when :string_add
850
837
  s(:string_content) == self[1] ? self[2].to_s : self[1].to_s
@@ -871,11 +858,7 @@ class Sexp
871
858
 
872
859
  # check if the self node is a const.
873
860
  def const?
874
- :@const == self.sexp_type ||
875
- (
876
- %i[var_ref vcall].include?(self.sexp_type) &&
877
- :@const == self[1].sexp_type
878
- )
861
+ :@const == self.sexp_type || (%i[var_ref vcall].include?(self.sexp_type) && :@const == self[1].sexp_type)
879
862
  end
880
863
 
881
864
  # true
@@ -892,14 +875,10 @@ class Sexp
892
875
  def remove_line_and_column
893
876
  node = self.clone
894
877
  last_node = node.last
895
- if Sexp === last_node && last_node.size == 2 &&
896
- last_node.first.is_a?(Integer) &&
897
- last_node.last.is_a?(Integer)
878
+ if Sexp === last_node && last_node.size == 2 && last_node.first.is_a?(Integer) && last_node.last.is_a?(Integer)
898
879
  node.delete_at(-1)
899
880
  end
900
- node.sexp_body.each_with_index do |child, index|
901
- node[index + 1] = child.remove_line_and_column if Sexp === child
902
- end
881
+ node.sexp_body.each_with_index { |child, index| node[index + 1] = child.remove_line_and_column if Sexp === child }
903
882
  node
904
883
  end
905
884
 
@@ -922,9 +901,7 @@ class Sexp
922
901
  class_eval <<-EOS
923
902
  alias_method :origin_#{method}, :#{method}
924
903
 
925
- def #{
926
- method
927
- }
904
+ def #{method}
928
905
  ret = origin_#{
929
906
  method
930
907
  }
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer
3
- VERSION = '0.5.1'
4
+ VERSION = '0.5.5'
4
5
  end
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer
3
4
  # Warning is the violation.
4
5
  #
data/lib/code_analyzer.rb CHANGED
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'ripper'
3
4
  require 'code_analyzer/version'
4
5
  require 'code_analyzer/nil'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module CodeAnalyzer
@@ -28,16 +30,12 @@ module CodeAnalyzer
28
30
 
29
31
  context '#parse_file?' do
30
32
  it 'should return true if node_file matches pattern' do
31
- allow(checker).to receive(:interesting_files).and_return(
32
- [%r{spec\/.*\.rb}, %r{lib\/.*\.rb}]
33
- )
33
+ allow(checker).to receive(:interesting_files).and_return([%r{spec\/.*\.rb}, %r{lib\/.*\.rb}])
34
34
  expect(checker.parse_file?('lib/code_analyzer.rb')).to be true
35
35
  end
36
36
 
37
37
  it "should return false if node_file doesn't match pattern" do
38
- allow(checker).to receive(:interesting_files).and_return(
39
- [%r{spec\/.*\.rb}]
40
- )
38
+ allow(checker).to receive(:interesting_files).and_return([%r{spec\/.*\.rb}])
41
39
  expect(checker.parse_file?('lib/code_analyzer.rb')).to be false
42
40
  end
43
41
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module CodeAnalyzer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module CodeAnalyzer::CheckingVisitor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module CodeAnalyzer::CheckingVisitor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module CodeAnalyzer