ruby-lint 1.0.2 → 1.0.3
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 +4 -4
- data/doc/changelog.md +17 -0
- data/lib/ruby-lint/analysis/argument_amount.rb +9 -1
- data/lib/ruby-lint/analysis/base.rb +4 -1
- data/lib/ruby-lint/definition/ruby_object.rb +23 -3
- data/lib/ruby-lint/definition_builder/ruby_method.rb +9 -4
- data/lib/ruby-lint/definition_builder/ruby_module.rb +1 -1
- data/lib/ruby-lint/definitions/core/array.rb +28 -2
- data/lib/ruby-lint/definitions/core/range.rb +5 -2
- data/lib/ruby-lint/file_scanner.rb +8 -3
- data/lib/ruby-lint/parser.rb +37 -3
- data/lib/ruby-lint/runner.rb +6 -1
- data/lib/ruby-lint/version.rb +1 -1
- data/lib/ruby-lint/virtual_machine.rb +6 -3
- data/spec/ruby-lint/analysis/argument_amount_spec.rb +14 -0
- data/spec/ruby-lint/analysis/base_spec.rb +8 -0
- data/spec/ruby-lint/definition/ruby_object_spec.rb +34 -0
- data/spec/ruby-lint/file_scanner_spec.rb +8 -0
- data/spec/ruby-lint/parser_spec.rb +7 -0
- data/spec/ruby-lint/virtual_machine/classes/sclass_spec.rb +5 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b345fdf9724a766a2684c0977f862cd7e408ce9
|
4
|
+
data.tar.gz: a6d56efba7d749595035211678c38c8a4323c94d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efe10626ab798f0d8069d5bceb3c39efb634c1afbf009490c0a01670ca2f049ddabbbf9f17f3f9a84058cb69fe14c9b42f3031da4d9211c1d8f075d3889596af
|
7
|
+
data.tar.gz: 14f98dd7fdf7875035021f5830da8574c0f4ab82bbbc7775a1476a26e56052dd4259ba0d67e9c8a1893e090bc5c4db3dc069e6f2ac2d0ddd4ceae06617872813
|
data/doc/changelog.md
CHANGED
@@ -5,6 +5,23 @@ 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
|
+
## 1.0.3 - 2013-12-23
|
9
|
+
|
10
|
+
* `self` is now defined as a class and instance method to ensure that the right
|
11
|
+
data is used in these two scopes. See
|
12
|
+
`28f604ded884be2e43ef7ce93892a3cade4c93d7` for a more in depth explanation.
|
13
|
+
* Block arguments passed to methods are now ignored by the `ArgumentAmount`
|
14
|
+
analysis class.
|
15
|
+
* Configuration objects are now passed to analysis classes.
|
16
|
+
* ruby-lint can now parse empty Ruby files! Previously this would crash the
|
17
|
+
parser.
|
18
|
+
* Range now inherits from Enumerable.
|
19
|
+
* The definitions for Array have been re-generated.
|
20
|
+
* Fix for searching for Ruby files when no directories were given to the file
|
21
|
+
scanner class. Previously this would cause ruby-lint to start scanning from
|
22
|
+
`/`. See <https://github.com/YorickPeterse/ruby-lint/issues/83> for more
|
23
|
+
information.
|
24
|
+
|
8
25
|
## 1.0.2 - 2013-12-19
|
9
26
|
|
10
27
|
This release changes the default file scanner directories from `$PWD` to
|
@@ -27,7 +27,7 @@ module RubyLint
|
|
27
27
|
|
28
28
|
return unless method
|
29
29
|
|
30
|
-
given = args
|
30
|
+
given = argument_amount(args)
|
31
31
|
min, max = argument_range(method)
|
32
32
|
|
33
33
|
unless correct_argument_amount(min, max, given)
|
@@ -112,6 +112,14 @@ module RubyLint
|
|
112
112
|
|
113
113
|
return min, max
|
114
114
|
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# @param [RubyLint::AST::Node] nodes
|
118
|
+
# @return [Fixnum]
|
119
|
+
#
|
120
|
+
def argument_amount(nodes)
|
121
|
+
return nodes.reject { |n| n.type == :block_pass }.length
|
122
|
+
end
|
115
123
|
end # ArgumentAmount
|
116
124
|
end # Analysis
|
117
125
|
end # RubyLint
|
@@ -10,8 +10,11 @@ module RubyLint
|
|
10
10
|
# @!attribute [r] vm
|
11
11
|
# @return [RubyLint::VirtualMachine]
|
12
12
|
#
|
13
|
+
# @!attribute [r] config
|
14
|
+
# @return [RubyLint::Configuration]
|
15
|
+
#
|
13
16
|
class Base < Iterator
|
14
|
-
attr_reader :report, :vm
|
17
|
+
attr_reader :report, :vm, :config
|
15
18
|
|
16
19
|
##
|
17
20
|
# Array containing the callback names for which a new scope should be
|
@@ -83,7 +83,6 @@ module RubyLint
|
|
83
83
|
:gvar,
|
84
84
|
:instance_method,
|
85
85
|
:ivar,
|
86
|
-
:keyword,
|
87
86
|
:method
|
88
87
|
].freeze
|
89
88
|
|
@@ -107,7 +106,6 @@ module RubyLint
|
|
107
106
|
:gvar,
|
108
107
|
:instance_method,
|
109
108
|
:ivar,
|
110
|
-
:keyword,
|
111
109
|
:kwoptarg,
|
112
110
|
:lvar,
|
113
111
|
:member,
|
@@ -543,7 +541,7 @@ module RubyLint
|
|
543
541
|
definition = add_child_definition(:const, name, &block)
|
544
542
|
end
|
545
543
|
|
546
|
-
definition.
|
544
|
+
definition.define_self
|
547
545
|
|
548
546
|
return definition
|
549
547
|
end
|
@@ -610,6 +608,28 @@ module RubyLint
|
|
610
608
|
self.parents.concat(definitions)
|
611
609
|
end
|
612
610
|
|
611
|
+
##
|
612
|
+
# Defines `self` on the current definition as both a class and instance
|
613
|
+
# method.
|
614
|
+
#
|
615
|
+
def define_self
|
616
|
+
if instance?
|
617
|
+
self_instance = self
|
618
|
+
self_class = instance(:instance_type => :class)
|
619
|
+
else
|
620
|
+
self_instance = self.instance
|
621
|
+
self_class = self
|
622
|
+
end
|
623
|
+
|
624
|
+
define_method('self') do |method|
|
625
|
+
method.returns(self_class)
|
626
|
+
end
|
627
|
+
|
628
|
+
define_instance_method('self') do |method|
|
629
|
+
method.returns(self_instance)
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
613
633
|
##
|
614
634
|
# Returns a pretty formatted String that shows some info about the
|
615
635
|
# current definition.
|
@@ -51,17 +51,22 @@ module RubyLint
|
|
51
51
|
# @return [RubyLint::Definition::RubyObject]
|
52
52
|
#
|
53
53
|
def new_definition(parents)
|
54
|
-
type
|
54
|
+
type = options[:type]
|
55
|
+
instance_type = :instance
|
55
56
|
|
56
|
-
|
57
|
-
|
57
|
+
# FIXME: setting the instance type of a method to a `class` is a bit of
|
58
|
+
# a hack to ensure that class methods cause lookups inside them to be
|
59
|
+
# performed on class level.
|
60
|
+
if has_receiver? and options[:receiver].class?
|
61
|
+
type = :method
|
62
|
+
instance_type = :class
|
58
63
|
end
|
59
64
|
|
60
65
|
return Definition::RubyMethod.new(
|
61
66
|
:name => method_name,
|
62
67
|
:parents => parents,
|
63
68
|
:type => type,
|
64
|
-
:instance_type =>
|
69
|
+
:instance_type => instance_type,
|
65
70
|
:visibility => options[:visibility],
|
66
71
|
:line => node.line,
|
67
72
|
:column => node.column,
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# This file was automatically generated, any manual changes will be lost the
|
2
2
|
# next time this file is generated.
|
3
3
|
#
|
4
|
-
# Created: 2013-
|
5
|
-
# Platform: rbx 2.
|
4
|
+
# Created: 2013-12-23 09:38:51 +0100
|
5
|
+
# Platform: rbx 2.2.1
|
6
6
|
|
7
7
|
RubyLint::GlobalScope.definitions.define_constant('Array') do |klass|
|
8
8
|
klass.inherits(RubyLint::GlobalScope.constant_proxy('Object'))
|
@@ -17,6 +17,8 @@ RubyLint::GlobalScope.definitions.define_constant('Array') do |klass|
|
|
17
17
|
method.define_argument('obj')
|
18
18
|
end
|
19
19
|
|
20
|
+
klass.define_method('yaml_tag_subclasses?')
|
21
|
+
|
20
22
|
klass.define_instance_method('&') do |method|
|
21
23
|
method.define_argument('other')
|
22
24
|
end
|
@@ -217,6 +219,11 @@ RubyLint::GlobalScope.definitions.define_constant('Array') do |klass|
|
|
217
219
|
method.define_optional_argument('obj')
|
218
220
|
end
|
219
221
|
|
222
|
+
klass.define_instance_method('initialize') do |method|
|
223
|
+
method.define_optional_argument('size_or_array')
|
224
|
+
method.define_optional_argument('obj')
|
225
|
+
end
|
226
|
+
|
220
227
|
klass.define_instance_method('inject') do |method|
|
221
228
|
method.define_optional_argument('initial')
|
222
229
|
method.define_optional_argument('sym')
|
@@ -396,6 +403,10 @@ RubyLint::GlobalScope.definitions.define_constant('Array') do |klass|
|
|
396
403
|
|
397
404
|
klass.define_instance_method('start=')
|
398
405
|
|
406
|
+
klass.define_instance_method('taguri')
|
407
|
+
|
408
|
+
klass.define_instance_method('taguri=')
|
409
|
+
|
399
410
|
klass.define_instance_method('take') do |method|
|
400
411
|
method.define_argument('n')
|
401
412
|
end
|
@@ -416,6 +427,10 @@ RubyLint::GlobalScope.definitions.define_constant('Array') do |klass|
|
|
416
427
|
|
417
428
|
klass.define_instance_method('to_tuple')
|
418
429
|
|
430
|
+
klass.define_instance_method('to_yaml') do |method|
|
431
|
+
method.define_optional_argument('opts')
|
432
|
+
end
|
433
|
+
|
419
434
|
klass.define_instance_method('total')
|
420
435
|
|
421
436
|
klass.define_instance_method('total=')
|
@@ -442,6 +457,11 @@ RubyLint::GlobalScope.definitions.define_constant('Array') do |klass|
|
|
442
457
|
method.define_argument('memo')
|
443
458
|
end
|
444
459
|
|
460
|
+
klass.define_instance_method('yaml_initialize') do |method|
|
461
|
+
method.define_argument('tag')
|
462
|
+
method.define_argument('val')
|
463
|
+
end
|
464
|
+
|
445
465
|
klass.define_instance_method('zip') do |method|
|
446
466
|
method.define_rest_argument('others')
|
447
467
|
end
|
@@ -536,6 +556,12 @@ RubyLint::GlobalScope.definitions.define_constant('Array::Enumerator') do |klass
|
|
536
556
|
method.define_argument('obj')
|
537
557
|
end
|
538
558
|
|
559
|
+
klass.define_instance_method('initialize') do |method|
|
560
|
+
method.define_optional_argument('receiver_or_size')
|
561
|
+
method.define_optional_argument('method_name')
|
562
|
+
method.define_rest_argument('method_args')
|
563
|
+
end
|
564
|
+
|
539
565
|
klass.define_instance_method('inject') do |method|
|
540
566
|
method.define_optional_argument('initial')
|
541
567
|
method.define_optional_argument('sym')
|
@@ -4,7 +4,10 @@
|
|
4
4
|
# Platform: rbx 2.0.0.rc1
|
5
5
|
#
|
6
6
|
RubyLint::GlobalScope.definitions.define_constant('Range') do |klass|
|
7
|
-
klass.inherits(
|
7
|
+
klass.inherits(
|
8
|
+
RubyLint::GlobalScope.constant_proxy('Object'),
|
9
|
+
RubyLint::GlobalScope.constant_proxy('Enumerable')
|
10
|
+
)
|
8
11
|
|
9
12
|
klass.define_method('__class_init__')
|
10
13
|
|
@@ -103,4 +106,4 @@ RubyLint::GlobalScope.definitions.define_constant('Range::SortedElement') do |kl
|
|
103
106
|
klass.define_instance_method('value')
|
104
107
|
end
|
105
108
|
|
106
|
-
RubyLint::GlobalScope.definitions.lookup(:const, 'Range').deep_freeze
|
109
|
+
RubyLint::GlobalScope.definitions.lookup(:const, 'Range').deep_freeze
|
@@ -60,9 +60,7 @@ module RubyLint
|
|
60
60
|
# @return [Array]
|
61
61
|
#
|
62
62
|
def scan(constant)
|
63
|
-
|
64
|
-
# than running a Dir.glob for every call to #scan.
|
65
|
-
@glob_cache ||= Dir.glob("#{directories.join(',')}/**/*.rb")
|
63
|
+
@glob_cache ||= directories.empty? ? [] : glob_ruby_files
|
66
64
|
|
67
65
|
unless constant_paths_cached?(constant)
|
68
66
|
build_constant_paths_cache(constant)
|
@@ -73,6 +71,13 @@ module RubyLint
|
|
73
71
|
|
74
72
|
private
|
75
73
|
|
74
|
+
##
|
75
|
+
# @return [Array]
|
76
|
+
#
|
77
|
+
def glob_ruby_files
|
78
|
+
return Dir.glob("#{directories.join(',')}/**/*.rb")
|
79
|
+
end
|
80
|
+
|
76
81
|
##
|
77
82
|
# Searches all the files that could potentially define the given constant
|
78
83
|
# and caches them.
|
data/lib/ruby-lint/parser.rb
CHANGED
@@ -39,13 +39,47 @@ module RubyLint
|
|
39
39
|
buffer = ::Parser::Source::Buffer.new(file, line)
|
40
40
|
buffer.source = code
|
41
41
|
ast, comments = internal_parser.parse_with_comments(buffer)
|
42
|
-
associator = ::Parser::Source::Comment::Associator.new(ast, comments)
|
43
42
|
|
44
43
|
internal_parser.reset
|
45
44
|
|
46
|
-
|
45
|
+
associated = associate_comments(ast, comments)
|
47
46
|
|
48
|
-
return
|
47
|
+
return create_root_node(ast), associated
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
##
|
53
|
+
# @param [RubyLint::AST::Node|NilClass] ast
|
54
|
+
# @return [RubyLint::AST::Node]
|
55
|
+
#
|
56
|
+
def create_root_node(ast)
|
57
|
+
if ast
|
58
|
+
children = [ast]
|
59
|
+
location = ast.location
|
60
|
+
# empty input.
|
61
|
+
else
|
62
|
+
children = []
|
63
|
+
location = nil
|
64
|
+
end
|
65
|
+
|
66
|
+
return AST::Node.new(:root, children, :location => location)
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# @param [RubyLint::AST::Node|NilClass] ast
|
71
|
+
# @param [Mixed] comments
|
72
|
+
# @return [Hash]
|
73
|
+
#
|
74
|
+
def associate_comments(ast, comments)
|
75
|
+
if ast
|
76
|
+
associator = ::Parser::Source::Comment::Associator.new(ast, comments)
|
77
|
+
associated = associator.associate
|
78
|
+
else
|
79
|
+
associated = {}
|
80
|
+
end
|
81
|
+
|
82
|
+
return associated
|
49
83
|
end
|
50
84
|
end # Parser
|
51
85
|
end # RubyLint
|
data/lib/ruby-lint/runner.rb
CHANGED
@@ -175,7 +175,12 @@ module RubyLint
|
|
175
175
|
end
|
176
176
|
|
177
177
|
classes.each do |const|
|
178
|
-
instance = const.new(
|
178
|
+
instance = const.new(
|
179
|
+
:vm => vm,
|
180
|
+
:report => report,
|
181
|
+
:config => configuration
|
182
|
+
)
|
183
|
+
|
179
184
|
instance.iterate(ast)
|
180
185
|
end
|
181
186
|
end
|
data/lib/ruby-lint/version.rb
CHANGED
@@ -443,7 +443,10 @@ module RubyLint
|
|
443
443
|
# Pushes the value of `self` onto the current stack.
|
444
444
|
#
|
445
445
|
def on_self
|
446
|
-
|
446
|
+
scope = current_scope
|
447
|
+
method = scope.lookup(scope.method_call_type, 'self')
|
448
|
+
|
449
|
+
push_value(method.return_value)
|
447
450
|
end
|
448
451
|
|
449
452
|
##
|
@@ -522,7 +525,7 @@ module RubyLint
|
|
522
525
|
def on_sclass(node)
|
523
526
|
parent = node.children[0]
|
524
527
|
definition = evaluate_node(parent)
|
525
|
-
@method_type =
|
528
|
+
@method_type = definition.method_call_type
|
526
529
|
|
527
530
|
associate_node(node, definition)
|
528
531
|
|
@@ -748,7 +751,7 @@ Received: #{arguments.length}
|
|
748
751
|
:instance_type => :instance
|
749
752
|
)
|
750
753
|
|
751
|
-
definitions.
|
754
|
+
definitions.define_self
|
752
755
|
|
753
756
|
return definitions
|
754
757
|
end
|
@@ -114,4 +114,18 @@ Person.new(10, 20)
|
|
114
114
|
second.column.should == 1
|
115
115
|
second.message.should == 'wrong number of arguments (expected 1 but got 2)'
|
116
116
|
end
|
117
|
+
|
118
|
+
example 'ignore block arguments' do
|
119
|
+
code = <<-CODE
|
120
|
+
def example; end
|
121
|
+
|
122
|
+
block = proc {}
|
123
|
+
|
124
|
+
example(&block)
|
125
|
+
CODE
|
126
|
+
|
127
|
+
report = build_report(code, RubyLint::Analysis::ArgumentAmount)
|
128
|
+
|
129
|
+
report.entries.empty?.should == true
|
130
|
+
end
|
117
131
|
end
|
@@ -10,6 +10,14 @@ describe RubyLint::Analysis::Base do
|
|
10
10
|
blk.should_not raise_error
|
11
11
|
end
|
12
12
|
|
13
|
+
example 'allow config objects to be passed in' do
|
14
|
+
vm = RubyLint::VirtualMachine.new
|
15
|
+
config = RubyLint::Configuration.new
|
16
|
+
base = RubyLint::Analysis::Base.new(:vm => vm, :config => config)
|
17
|
+
|
18
|
+
base.config.should == config
|
19
|
+
end
|
20
|
+
|
13
21
|
example 'enable analysis by default' do
|
14
22
|
RubyLint::Analysis::Base.analyze?(double(:ast), double(:vm)).should == true
|
15
23
|
end
|
@@ -227,4 +227,38 @@ describe ruby_object do
|
|
227
227
|
@method.callers.frozen?.should == true
|
228
228
|
end
|
229
229
|
end
|
230
|
+
|
231
|
+
context 'defining self' do
|
232
|
+
before do
|
233
|
+
@class = ruby_object.new(:instance_type => :class)
|
234
|
+
@instance = ruby_object.new(:instance_type => :instance)
|
235
|
+
|
236
|
+
@class.define_self
|
237
|
+
@instance.define_self
|
238
|
+
end
|
239
|
+
|
240
|
+
example 'define instance level self for an instance' do
|
241
|
+
@instance.lookup(:instance_method, 'self')
|
242
|
+
.return_value
|
243
|
+
.should == @instance
|
244
|
+
end
|
245
|
+
|
246
|
+
example 'define class level self for an instance' do
|
247
|
+
@instance.lookup(:method, 'self')
|
248
|
+
.return_value
|
249
|
+
.parents
|
250
|
+
.should == [@instance]
|
251
|
+
end
|
252
|
+
|
253
|
+
example 'define instance level self for a class' do
|
254
|
+
@class.lookup(:instance_method, 'self')
|
255
|
+
.return_value
|
256
|
+
.parents
|
257
|
+
.should == [@class]
|
258
|
+
end
|
259
|
+
|
260
|
+
example 'define class level self for a class' do
|
261
|
+
@class.lookup(:method, 'self').return_value.should == @class
|
262
|
+
end
|
263
|
+
end
|
230
264
|
end
|
@@ -61,4 +61,12 @@ describe RubyLint::FileScanner do
|
|
61
61
|
|
62
62
|
scanner.scan('Example::User').empty?.should == true
|
63
63
|
end
|
64
|
+
|
65
|
+
example 'do not scan when there are no directories' do
|
66
|
+
scanner = RubyLint::FileScanner.new([])
|
67
|
+
|
68
|
+
scanner.should_not receive(:glob_ruby_files)
|
69
|
+
|
70
|
+
scanner.scan('Foo')
|
71
|
+
end
|
64
72
|
end
|
@@ -20,7 +20,7 @@ end
|
|
20
20
|
.should == true
|
21
21
|
end
|
22
22
|
|
23
|
-
example 'define
|
23
|
+
example 'define an instance method using `class << self` in the global scope' do
|
24
24
|
code = <<-CODE
|
25
25
|
class << self
|
26
26
|
def example
|
@@ -30,7 +30,9 @@ end
|
|
30
30
|
|
31
31
|
defs = build_definitions(code)
|
32
32
|
|
33
|
-
defs.lookup(:
|
33
|
+
defs.lookup(:instance_method, 'example')
|
34
|
+
.is_a?(ruby_method)
|
35
|
+
.should == true
|
34
36
|
end
|
35
37
|
|
36
38
|
example 'define a class method using `class << String`' do
|
@@ -91,4 +93,4 @@ end
|
|
91
93
|
.should == true
|
92
94
|
end
|
93
95
|
end
|
94
|
-
end
|
96
|
+
end
|
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: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yorick Peterse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|