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 +4 -4
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +1 -0
- data/README.md +1 -1
- data/checksum/ruby-lint-2.2.0.gem.sha512 +1 -0
- data/doc/changelog.md +39 -0
- data/doc/graphviz/flow.dot +3 -0
- data/doc/images/flow.png +0 -0
- data/lib/ruby-lint/analysis/argument_amount.rb +2 -1
- data/lib/ruby-lint/analysis/loop_keywords.rb +8 -3
- data/lib/ruby-lint/constant_loader.rb +52 -4
- data/lib/ruby-lint/constant_path.rb +3 -12
- data/lib/ruby-lint/definition/ruby_object.rb +20 -8
- data/lib/ruby-lint/report/entry.rb +1 -1
- data/lib/ruby-lint/runner.rb +0 -6
- data/lib/ruby-lint/variable_predicates.rb +1 -0
- data/lib/ruby-lint/version.rb +1 -1
- data/lib/ruby-lint/virtual_machine.rb +11 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 331ac16aeefe37d7fe272112bdde394e57e8cfe4
|
4
|
+
data.tar.gz: b78010d6fd3e7cd0ffba8e69166427671ebb1646
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84d955c9da5d706926efab593310f5fd211cf10b72e2f1f9e7562768c9af1ddaf3a5c647ed3b5fb4a8a441bbb3642083b74643b616813bdf4865ba9ff61afb5b
|
7
|
+
data.tar.gz: 8e43b5ca6ca4b22c38eea2b63072982930551f73d7fe51b094cf8072c8fbb16dded067efd622d77ed98e09cc3da542c210ca814d1a789549637a44f40de810bb
|
data/.yardopts
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -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
|
data/doc/changelog.md
CHANGED
@@ -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
|
data/doc/graphviz/flow.dot
CHANGED
data/doc/images/flow.png
CHANGED
Binary file
|
@@ -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
|
-
@
|
52
|
+
@loop_nesting += 1
|
48
53
|
end
|
49
54
|
|
50
55
|
define_method("after_#{statement}") do
|
51
|
-
@
|
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
|
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
|
-
'
|
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
|
-
|
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
|
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]
|
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
|
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
|
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
|
data/lib/ruby-lint/runner.rb
CHANGED
@@ -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|
|
data/lib/ruby-lint/version.rb
CHANGED
@@ -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.
|
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-
|
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
|