ruby-lint 2.2.0 → 2.3.0

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
  SHA1:
3
- metadata.gz: 8bf37bd3d8da6b4f67786c1a253264d9834ae60c
4
- data.tar.gz: 55e7485469de13d24f95d09a3ba89e16b39e9d71
3
+ metadata.gz: 331ac16aeefe37d7fe272112bdde394e57e8cfe4
4
+ data.tar.gz: b78010d6fd3e7cd0ffba8e69166427671ebb1646
5
5
  SHA512:
6
- metadata.gz: 0c35b467c325e8ade9eedbc0804a6fd1eff49c0afdee96449378923b2394e7a692f88a2c42985262b7af5cac5eea515d90242edda76c455f2e33c644404cdc35
7
- data.tar.gz: a00707a3cbf48c2abf148c94417956d187bf2572f1d1f73c9468d255302605d818569cc5bd3b57a0733a05b9a7520f80631672d566c7aa1df96bf5db63ed27f2
6
+ metadata.gz: 84d955c9da5d706926efab593310f5fd211cf10b72e2f1f9e7562768c9af1ddaf3a5c647ed3b5fb4a8a441bbb3642083b74643b616813bdf4865ba9ff61afb5b
7
+ data.tar.gz: 8e43b5ca6ca4b22c38eea2b63072982930551f73d7fe51b094cf8072c8fbb16dded067efd622d77ed98e09cc3da542c210ca814d1a789549637a44f40de810bb
data/.yardopts CHANGED
@@ -13,3 +13,4 @@
13
13
  ./doc/*.md
14
14
  LICENSE
15
15
  CONTRIBUTING.md
16
+ COC.md
@@ -18,6 +18,7 @@ this CoC.
18
18
  * Wrap lines at 80 characters per line.
19
19
  * Git commits should have a <= 50 character summary, optionally followed by a
20
20
  blank line and a more in depth description of 80 characters per line.
21
+ * Write a summary of your contribution to the {file:changelog changelog}.
21
22
 
22
23
  ## Editor Setup
23
24
 
data/README.md CHANGED
@@ -78,7 +78,7 @@ the following output:
78
78
 
79
79
  test.rb: error: line 7, column 22: undefined instance variable @name
80
80
  test.rb: warning: line 12, column 1: unused local variable greeting
81
- test.rb: error: line 14, column 1: wrong number of arguments (expected 0 but got 1)
81
+ test.rb: error: line 14, column 1: wrong number of arguments for 'greet' (expected 0 but got 1)
82
82
 
83
83
  ## ruby-lint versus RuboCop
84
84
 
@@ -0,0 +1 @@
1
+ ee671e49cd231d715d6a680fc471b209f7c05c0d72cec2a7b1bc20301933e621be0be91bda12cb095f6349835c321d88a1b4806dc2673a46b5f7c69edc1a5f43
@@ -5,6 +5,45 @@ This document contains a short summary of the various releases of ruby-lint.
5
5
  For a full list of commits included in each release see the corresponding Git
6
6
  tags (named after the versions).
7
7
 
8
+ ## 2.3.0 - 2016-06-30
9
+
10
+ Analysis fixes:
11
+
12
+ * Absolute constant names, such as `::File`, are resolved correctly.
13
+ ([PR#188][PR188] by Martin Vidner)
14
+ * When a `Bar` constant is seen inside a `Foo` module, load the definitions
15
+ for `Foo::Bar`.
16
+ ([PR#184][PR184] by Martin Vidner)
17
+ * loop_keywords analysis is no longer fooled by nested loops.
18
+ ([PR#185][PR185] by Josef Reidinger)
19
+
20
+ Parsing fixes:
21
+
22
+ * Fixed an exception "Not enough argument definitions" when determining the
23
+ value of an empty regex (`//`), empty heredoc, or a bare `yield`.
24
+ ([PR#187][PR187] by Martin Vidner)
25
+ * Do not crash for `$10` and bigger.
26
+ ([PR#186][PR186] by Josef Reidinger)
27
+ * Analysis is no longer cut short by Ruby syntax warnings.
28
+ ([PR#177][PR177] by Martin Vidner)
29
+
30
+ Report improvements:
31
+
32
+ * argument_amount analysis mentions the method name in the report.
33
+ ([PR#172][PR172] by Martin Vidner)
34
+ * Reports are sorted by the whole pathname, then by line numbers, and newly
35
+ also by column numbers.
36
+ ([PR#176][PR176] by Martin Vidner)
37
+
38
+ [PR172]: https://github.com/YorickPeterse/ruby-lint/pull/172
39
+ [PR176]: https://github.com/YorickPeterse/ruby-lint/pull/176
40
+ [PR177]: https://github.com/YorickPeterse/ruby-lint/pull/177
41
+ [PR184]: https://github.com/YorickPeterse/ruby-lint/pull/184
42
+ [PR185]: https://github.com/YorickPeterse/ruby-lint/pull/185
43
+ [PR186]: https://github.com/YorickPeterse/ruby-lint/pull/186
44
+ [PR187]: https://github.com/YorickPeterse/ruby-lint/pull/187
45
+ [PR188]: https://github.com/YorickPeterse/ruby-lint/pull/188
46
+
8
47
  ## 2.2.0 - 2016-05-26
9
48
 
10
49
  * Martin Vidner added a present for Emacs, see commit
@@ -2,6 +2,9 @@
2
2
  // ruby-lint.
3
3
 
4
4
  digraph flow {
5
+ "Source" [shape=box];
6
+ "Report" [shape=box];
7
+
5
8
  "Source" -> "Parser" -> "Virtual Machine" -> "Analysis";
6
9
  "Analysis" -> "Report" -> "Presenter";
7
10
  }
Binary file
@@ -36,7 +36,8 @@ module RubyLint
36
36
  text = argument_text(method, given)
37
37
 
38
38
  error(
39
- "wrong number of arguments (expected #{text} but got #{given})",
39
+ "wrong number of arguments for '#{method.name}' " \
40
+ "(expected #{text} but got #{given})",
40
41
  node
41
42
  )
42
43
  end
@@ -24,6 +24,11 @@ module RubyLint
24
24
  class LoopKeywords < Base
25
25
  register 'loop_keywords'
26
26
 
27
+ def after_initialize
28
+ @loop_nesting = 0
29
+ super
30
+ end
31
+
27
32
  ##
28
33
  # List of keywords that can only be used inside a loop.
29
34
  #
@@ -44,11 +49,11 @@ module RubyLint
44
49
 
45
50
  STATEMENTS.each do |statement|
46
51
  define_method("on_#{statement}") do
47
- @allow_keyword = true
52
+ @loop_nesting += 1
48
53
  end
49
54
 
50
55
  define_method("after_#{statement}") do
51
- @allow_keyword = false
56
+ @loop_nesting -= 1
52
57
  end
53
58
  end
54
59
 
@@ -57,7 +62,7 @@ module RubyLint
57
62
  # @param [RubyLint::AST::Node] node
58
63
  #
59
64
  def verify_keyword(keyword, node)
60
- if current_scope.type != :block and !@allow_keyword
65
+ if current_scope.type != :block and @loop_nesting.zero?
61
66
  error("#{keyword} can only be used inside a loop/block", node)
62
67
  end
63
68
  end
@@ -16,8 +16,11 @@ module RubyLint
16
16
  # @!attribute [r] definitions
17
17
  # @return [RubyLint::Definition::RubyObject]
18
18
  #
19
+ # @!attribute [r] module_nesting
20
+ # @return [Array<String>]
21
+ #
19
22
  class ConstantLoader < Iterator
20
- attr_reader :loaded, :definitions
23
+ attr_reader :loaded, :definitions, :module_nesting
21
24
 
22
25
  ##
23
26
  # Built-in definitions that should be bootstrapped.
@@ -34,10 +37,10 @@ module RubyLint
34
37
  BOOTSTRAP_GVARS = [
35
38
  '$!', '$$', '$&', '$\'', '$*', '$+', '$,', '$-0', '$-F', '$-I', '$-K',
36
39
  '$-W', '$-a', '$-d', '$-i', '$-l', '$-p', '$-v', '$-w', '$.', '$/', '$0',
37
- '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$:', '$;', '$<',
38
- '$=', '$>', '$?', '$@', '$DEBUG', '$FILENAME', '$KCODE',
40
+ '$:', '$;', '$<', '$=', '$>', '$?', '$@', '$DEBUG', '$FILENAME', '$KCODE',
39
41
  '$LOADED_FEATURES', '$LOAD_PATH', '$PROGRAM_NAME', '$SAFE', '$VERBOSE',
40
42
  '$\"', '$\\', '$_', '$`', '$stderr', '$stdin', '$stdout', '$~'
43
+ # Regexp $1, $2,... $99 are lazy loaded when first used
41
44
  ]
42
45
 
43
46
  ##
@@ -70,13 +73,36 @@ module RubyLint
70
73
  #
71
74
  def after_initialize
72
75
  @loaded = Set.new
76
+ @module_nesting = []
77
+ end
78
+
79
+ def on_module(node)
80
+ name, _body = *node
81
+ cp = ConstantPath.new(name)
82
+
83
+ @module_nesting.push(cp.to_s)
84
+ end
85
+
86
+ def after_module(_node)
87
+ @module_nesting.pop
88
+ end
89
+
90
+ def on_class(node)
91
+ name, _parent, _body = *node
92
+ cp = ConstantPath.new(name)
93
+
94
+ @module_nesting.push(cp.to_s)
95
+ end
96
+
97
+ def after_class(_node)
98
+ @module_nesting.pop
73
99
  end
74
100
 
75
101
  ##
76
102
  # @param [RubyLint::Node] node
77
103
  #
78
104
  def on_const(node)
79
- load_constant(ConstantPath.new(node).root_node[1])
105
+ load_nested_constant(ConstantPath.new(node).to_s)
80
106
  end
81
107
 
82
108
  ##
@@ -96,6 +122,28 @@ module RubyLint
96
122
  return RubyLint.registry
97
123
  end
98
124
 
125
+ ##
126
+ # Tries to load the definitions for the given constant.
127
+ # Takes into account what modules we are in to resolve the constant name.
128
+ #
129
+ # @param [String] constant name, possibly unqualified
130
+ #
131
+ def load_nested_constant(constant)
132
+ if constant.start_with?("::")
133
+ constant = constant.sub(/^::/, "")
134
+ else
135
+ # ["A", "B", "C"] -> ["A::B::C", "A::B", "A"]
136
+ namespaces = module_nesting.size.downto(1).map do |n|
137
+ module_nesting.take(n).join("::")
138
+ end
139
+
140
+ namespaces.each do |ns|
141
+ load_constant("#{ns}::#{constant}")
142
+ end
143
+ end
144
+ load_constant(constant)
145
+ end
146
+
99
147
  ##
100
148
  # Tries to load the definitions for the given constant.
101
149
  #
@@ -31,7 +31,7 @@ module RubyLint
31
31
  #
32
32
  # @param [RubyLint::Definition::RubyObject] scope The scope to use for the
33
33
  # lookups.
34
- # @return [RubyLint::Definition::RubyObject]
34
+ # @return [RubyLint::Definition::RubyObject|NilClass]
35
35
  #
36
36
  def resolve(scope)
37
37
  current = scope
@@ -40,7 +40,7 @@ module RubyLint
40
40
  type = REMAP_TYPES.fetch(type, type)
41
41
  found = current.lookup(type, name, index == 0)
42
42
 
43
- if found and found.const?
43
+ if found and (found.const? or found.type == :root)
44
44
  current = found
45
45
 
46
46
  # Local variables and the likes.
@@ -55,15 +55,6 @@ module RubyLint
55
55
  return current
56
56
  end
57
57
 
58
- ##
59
- # Returns the very first segment of the constant path as an AST node.
60
- #
61
- # @return [RubyLint::AST::Node]
62
- #
63
- def root_node
64
- return constant_segments.first
65
- end
66
-
67
58
  ##
68
59
  # Returns a String containing the full constant path, e.g.
69
60
  # "RubyLint::Runner".
@@ -78,7 +69,7 @@ module RubyLint
78
69
  # Returns an Array containing the segments of a constant path.
79
70
  #
80
71
  # @param [RubyLint::AST::Node] node
81
- # @return [Array<String>]
72
+ # @return [Array<Array(Symbol,String)>]
82
73
  #
83
74
  def constant_segments(node = self.node)
84
75
  segments = []
@@ -37,10 +37,12 @@ module RubyLint
37
37
  # @return [Symbol] The type of object, e.g. `:const`.
38
38
  #
39
39
  # @!attribute [r] definitions
40
- # @return [Hash] Hash containing all child the definitions.
40
+ # @return [Hash{Symbol => Hash{String => Object}}]
41
+ # Hash keyed by type and name, containing all child the definitions.
41
42
  #
42
43
  # @!attribute [rw] parents
43
- # @return [Array] Array containing the parent definitions.
44
+ # @return [Array<RubyLint::Definition::RubyObject>]
45
+ # Array containing the parent definitions.
44
46
  #
45
47
  # @!attribute [rw] reference_amount
46
48
  # @return [Numeric] The amount of times an object was referenced.
@@ -51,7 +53,7 @@ module RubyLint
51
53
  # instance.
52
54
  #
53
55
  # @!attribute [r] update_parents
54
- # @return [Array] A list of data types to also add to the parent
56
+ # @return [Array<Symbol>] A list of data types to also add to the parent
55
57
  # definitions when adding an object to the current one.
56
58
  #
57
59
  # @!attribute [r] members_as_value
@@ -79,7 +81,7 @@ module RubyLint
79
81
  # Array containing items that should be looked up in the parent
80
82
  # definition if they're not found in the current one.
81
83
  #
82
- # @return [Array]
84
+ # @return [Array<Symbol>]
83
85
  #
84
86
  LOOKUP_PARENT = [
85
87
  :const,
@@ -264,7 +266,8 @@ module RubyLint
264
266
  # @param [TrueClass|FalseClass] lookup_parent Whether definitions should
265
267
  # be looked up from parent definitions.
266
268
  #
267
- # @param [Array] exclude A list of definitions to skip when looking up
269
+ # @param [Array<RubyLint::Definition::RubyObject>] exclude
270
+ # A list of definitions to skip when looking up
268
271
  # parents. This list is used to prevent stack errors when dealing with
269
272
  # recursive definitions. A good example of this is `Logger` and
270
273
  # `Logger::Severity` which both inherit from each other.
@@ -278,6 +281,8 @@ module RubyLint
278
281
  if defines?(type, name)
279
282
  found = definitions[type][name]
280
283
 
284
+ elsif type == :cbase
285
+ found = top_scope
281
286
  # Look up the definition in the parent scope(s) (if any are set). This
282
287
  # takes the parents themselves also into account.
283
288
  elsif lookup_parent?(type) and lookup_parent
@@ -374,7 +379,8 @@ module RubyLint
374
379
  #
375
380
  # @param [#to_sym] type
376
381
  # @param [String] name
377
- # @param [Array] exclude Parent definitions to exclude.
382
+ # @param [Array<RubyLint::Definition::RubyObject>] exclude
383
+ # Parent definitions to exclude.
378
384
  # @return [TrueClass|FalseClass]
379
385
  #
380
386
  def has_definition?(type, name, exclude = [])
@@ -677,6 +683,12 @@ module RubyLint
677
683
  return %Q(#<#{self.class}:0x#{address} #{attributes.join(' ')}>)
678
684
  end
679
685
 
686
+ def top_scope
687
+ return self if type == :root
688
+ scope = parents.last # the enclosing scope
689
+ scope ? scope.top_scope : self
690
+ end
691
+
680
692
  private
681
693
 
682
694
  ##
@@ -697,7 +709,7 @@ module RubyLint
697
709
  # @param [RubyLint::Definition::RubyObject] parent
698
710
  # @param [Symbol] type
699
711
  # @param [String] name
700
- # @param [Array] exclude
712
+ # @param [Array<RubyLint::Definition::RubyObject>] exclude
701
713
  # @return [RubyLint::Definition::RubyObject]
702
714
  #
703
715
  def determine_parent(parent, type, name, exclude = [])
@@ -769,7 +781,7 @@ module RubyLint
769
781
  #
770
782
  # @param [#to_sym] type
771
783
  # @param [#to_s] name
772
- # @return [Array]
784
+ # @return [Array(Symbol,String)]
773
785
  #
774
786
  def prepare_lookup(type, name)
775
787
  return type.to_sym, name.to_s
@@ -67,7 +67,7 @@ module RubyLint
67
67
  # @return [Numeric]
68
68
  #
69
69
  def <=>(other)
70
- [filename, line] <=> [other.filename, other.line]
70
+ [file, line, column] <=> [other.file, other.line, other.column]
71
71
  end
72
72
  end # Entry
73
73
  end # Report
@@ -30,12 +30,6 @@ module RubyLint
30
30
 
31
31
  parser.consumer = proc do |diag|
32
32
  report_diagnostic(diag, report)
33
-
34
- # FIXME: there's a bug in the pure Ruby version of Racc causing it hang
35
- # after detecting a syntax error (it stays forever in recovery mode).
36
- # To work around this we'll have to bail out after detecting the first
37
- # syntax error.
38
- return presenter.present(report)
39
33
  end
40
34
 
41
35
  files.each do |file|
@@ -20,6 +20,7 @@ module RubyLint
20
20
  #
21
21
  RUBY_CLASSES = {
22
22
  :str => 'String',
23
+ :dstr => 'String',
23
24
  :sym => 'Symbol',
24
25
  :int => 'Fixnum',
25
26
  :float => 'Float',
@@ -1,3 +1,3 @@
1
1
  module RubyLint
2
- VERSION = '2.2.0'
2
+ VERSION = '2.3.0'
3
3
  end # RubyLint
@@ -103,7 +103,9 @@ module RubyLint
103
103
  :int,
104
104
  :float,
105
105
  :str,
106
+ :dstr,
106
107
  :sym,
108
+ :regexp,
107
109
  :true,
108
110
  :false,
109
111
  :nil,
@@ -352,6 +354,8 @@ module RubyLint
352
354
  #
353
355
  def on_nth_ref(node)
354
356
  var = definitions.lookup(:gvar, "$#{node.children[0]}")
357
+ # If the number is not found, then add it as there is no limit for them
358
+ var = definitions.define_global_variable(node.children[0]) if !var && node.children[0].is_a?(Fixnum)
355
359
 
356
360
  push_value(var.value)
357
361
  end
@@ -446,6 +450,13 @@ module RubyLint
446
450
  push_value(method.return_value)
447
451
  end
448
452
 
453
+ ##
454
+ # Pushes the return value of the block yielded to, that is, an unknown one.
455
+ #
456
+ def on_yield
457
+ push_unknown_value
458
+ end
459
+
449
460
  ##
450
461
  # Creates the definition for a module.
451
462
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yorick Peterse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-26 00:00:00.000000000 Z
11
+ date: 2016-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -172,6 +172,7 @@ files:
172
172
  - checksum/ruby-lint-2.0.4.gem.sha512
173
173
  - checksum/ruby-lint-2.0.5.gem.sha512
174
174
  - checksum/ruby-lint-2.1.0.gem.sha512
175
+ - checksum/ruby-lint-2.2.0.gem.sha512
175
176
  - doc/architecture.md
176
177
  - doc/changelog.md
177
178
  - doc/code_analysis.md