ruby-lint 2.2.0 → 2.3.0

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
  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