code_analyzer 0.5.1 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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