code_analyzer 0.5.0 → 0.5.4

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: 6c252e6214745ff2bcf507702a49553d0ca90c75a12614ee3e5c197c1994656c
4
- data.tar.gz: 85bb0e3b8ea846132ba4a159f4477749751cb54a94611a7402d241a2e296f1c6
3
+ metadata.gz: 6649593166b051c563e05a6a3a2130a1d369a6b828e5477a2f3d392f15ea691f
4
+ data.tar.gz: e78c03b663ad0951deee38f8202eaa73613a88690ccb5e43b07d81b3ca971f57
5
5
  SHA512:
6
- metadata.gz: 73fc0d1d771feafb646ff218837ae19e8de9556acd25b4fb3a3bad93b76899d950037145c603b1b5e48a38815b1be086102f65c3e77ad2bc2898931858988e6c
7
- data.tar.gz: 3fd7c957fc9c2ceeb6714cf4a6a4f1db7b00f7ea6d4a9e73553b460c59f0bd42a4f5d4538e7bf00bc2f39d441f29bed8891a3d200a65b0653830d30c735b7dc0
6
+ metadata.gz: 395be11e15e5a7ff181c381c1790b4b826c849d1ae4e1aadb1f002a9825f2976e3c696c4b710593c6b57d7e1d6cc742364ba24b2c9a4b5859e01ba86a1fd8a5b
7
+ data.tar.gz: 5aedb0a332cab72f10ad39dff8cc395133f8fb5170ae82ae7d01b8af9073a16d9d6c994af4046ab3f99ffd4edfbb0075fad5c0510b6bcbf83db6f0add433c03a
@@ -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,30 @@ 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 self[2] if :array == self[2].sexp_type
710
+
711
+ self[2].to_s
712
+ end
713
+ end
714
+
719
715
  # Get the array size.
720
716
  #
721
717
  # s(:array,
@@ -734,12 +730,9 @@ class Sexp
734
730
  if first_node
735
731
  while true
736
732
  array_size += 1
737
- first_node =
738
- s(:args_new) == first_node[1] ? first_node[2] : first_node[1]
733
+ first_node = s(:args_new) == first_node[1] ? first_node[2] : first_node[1]
739
734
  if :args_add != first_node.sexp_type
740
- if :array == first_node.sexp_type
741
- array_size += first_node.array_size
742
- end
735
+ array_size += first_node.array_size if :array == first_node.sexp_type
743
736
  break
744
737
  end
745
738
  end
@@ -765,13 +758,9 @@ class Sexp
765
758
  def array_values
766
759
  case sexp_type
767
760
  when :array
768
- if nil == self[1] ||
769
- %i[words_new qwords_new symbols_new qsymbols_new].include?(
770
- self[1].sexp_type
771
- )
761
+ if nil == self[1] || %i[words_new qwords_new symbols_new qsymbols_new].include?(self[1].sexp_type)
772
762
  []
773
- elsif %i[words_add qwords_add symbols_add qsymbols_add].include? self[1]
774
- .sexp_type
763
+ elsif %i[words_add qwords_add symbols_add qsymbols_add].include? self[1].sexp_type
775
764
  self[1].array_values
776
765
  else
777
766
  arguments.all
@@ -780,12 +769,10 @@ class Sexp
780
769
  values = []
781
770
  node = self
782
771
  while true
783
- if %i[words_add qwords_add symbols_add qsymbols_add].include? node
784
- .sexp_type
772
+ if %i[words_add qwords_add symbols_add qsymbols_add].include? node.sexp_type
785
773
  values.unshift node[2]
786
774
  node = node[1]
787
- elsif %i[words_new qwords_new symbols_new qsymbols_new].include? node
788
- .sexp_type
775
+ elsif %i[words_new qwords_new symbols_new qsymbols_new].include? node.sexp_type
789
776
  break
790
777
  end
791
778
  end
@@ -842,9 +829,8 @@ class Sexp
842
829
  # @return [String] to_s
843
830
  def to_s
844
831
  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
832
+ when :string_literal, :xstring_literal, :string_content, :const_ref, :symbol_literal, :symbol, :args_add_block, :var_ref,
833
+ :vcall, :var_field, :@ident, :@tstring_content, :@const, :@ivar, :@kw, :@gvar, :@cvar, :@period
848
834
  self[1].to_s
849
835
  when :string_add
850
836
  s(:string_content) == self[1] ? self[2].to_s : self[1].to_s
@@ -871,11 +857,7 @@ class Sexp
871
857
 
872
858
  # check if the self node is a const.
873
859
  def const?
874
- :@const == self.sexp_type ||
875
- (
876
- %i[var_ref vcall].include?(self.sexp_type) &&
877
- :@const == self[1].sexp_type
878
- )
860
+ :@const == self.sexp_type || (%i[var_ref vcall].include?(self.sexp_type) && :@const == self[1].sexp_type)
879
861
  end
880
862
 
881
863
  # true
@@ -892,14 +874,10 @@ class Sexp
892
874
  def remove_line_and_column
893
875
  node = self.clone
894
876
  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)
877
+ if Sexp === last_node && last_node.size == 2 && last_node.first.is_a?(Integer) && last_node.last.is_a?(Integer)
898
878
  node.delete_at(-1)
899
879
  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
880
+ node.sexp_body.each_with_index { |child, index| node[index + 1] = child.remove_line_and_column if Sexp === child }
903
881
  node
904
882
  end
905
883
 
@@ -922,9 +900,7 @@ class Sexp
922
900
  class_eval <<-EOS
923
901
  alias_method :origin_#{method}, :#{method}
924
902
 
925
- def #{
926
- method
927
- }
903
+ def #{method}
928
904
  ret = origin_#{
929
905
  method
930
906
  }
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module CodeAnalyzer
3
- VERSION = '0.5.0'
4
+ VERSION = '0.5.4'
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