ruby-lint 0.0.1a

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.
Files changed (80) hide show
  1. data/.gitignore +5 -0
  2. data/.rbenv-version +1 -0
  3. data/.yardopts +10 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +19 -0
  6. data/MANIFEST +79 -0
  7. data/README.md +48 -0
  8. data/Rakefile +14 -0
  9. data/bin/rlint +6 -0
  10. data/doc/.gitkeep +0 -0
  11. data/doc/build/.gitkeep +0 -0
  12. data/doc/css/.gitkeep +0 -0
  13. data/doc/css/common.css +68 -0
  14. data/lib/rlint/analyze/coding_style.rb +407 -0
  15. data/lib/rlint/analyze/definitions.rb +244 -0
  16. data/lib/rlint/analyze/method_validation.rb +104 -0
  17. data/lib/rlint/analyze/shadowing_variables.rb +37 -0
  18. data/lib/rlint/analyze/undefined_variables.rb +99 -0
  19. data/lib/rlint/analyze/unused_variables.rb +103 -0
  20. data/lib/rlint/callback.rb +67 -0
  21. data/lib/rlint/cli.rb +167 -0
  22. data/lib/rlint/constant_importer.rb +102 -0
  23. data/lib/rlint/definition.rb +230 -0
  24. data/lib/rlint/formatter/text.rb +54 -0
  25. data/lib/rlint/helper/definition_resolver.rb +143 -0
  26. data/lib/rlint/helper/scoping.rb +138 -0
  27. data/lib/rlint/iterator.rb +193 -0
  28. data/lib/rlint/options.rb +58 -0
  29. data/lib/rlint/parser.rb +1252 -0
  30. data/lib/rlint/parser_error.rb +42 -0
  31. data/lib/rlint/report.rb +98 -0
  32. data/lib/rlint/token/assignment_token.rb +46 -0
  33. data/lib/rlint/token/begin_rescue_token.rb +57 -0
  34. data/lib/rlint/token/block_token.rb +17 -0
  35. data/lib/rlint/token/case_token.rb +44 -0
  36. data/lib/rlint/token/class_token.rb +24 -0
  37. data/lib/rlint/token/method_definition_token.rb +64 -0
  38. data/lib/rlint/token/method_token.rb +58 -0
  39. data/lib/rlint/token/parameters_token.rb +99 -0
  40. data/lib/rlint/token/regexp_token.rb +15 -0
  41. data/lib/rlint/token/statement_token.rb +69 -0
  42. data/lib/rlint/token/token.rb +162 -0
  43. data/lib/rlint/token/variable_token.rb +18 -0
  44. data/lib/rlint/version.rb +3 -0
  45. data/lib/rlint.rb +36 -0
  46. data/ruby-lint.gemspec +23 -0
  47. data/spec/benchmarks/memory.rb +52 -0
  48. data/spec/benchmarks/parse_parser.rb +16 -0
  49. data/spec/helper.rb +4 -0
  50. data/spec/rlint/analyze/coding_style.rb +224 -0
  51. data/spec/rlint/analyze/definitions/classes.rb +114 -0
  52. data/spec/rlint/analyze/definitions/methods.rb +91 -0
  53. data/spec/rlint/analyze/definitions/modules.rb +207 -0
  54. data/spec/rlint/analyze/definitions/variables.rb +103 -0
  55. data/spec/rlint/analyze/method_validation.rb +177 -0
  56. data/spec/rlint/analyze/shadowing_variables.rb +30 -0
  57. data/spec/rlint/analyze/undefined_variables.rb +230 -0
  58. data/spec/rlint/analyze/unused_variables.rb +225 -0
  59. data/spec/rlint/callback.rb +28 -0
  60. data/spec/rlint/constant_importer.rb +27 -0
  61. data/spec/rlint/definition.rb +96 -0
  62. data/spec/rlint/formatter/text.rb +21 -0
  63. data/spec/rlint/iterator.rb +452 -0
  64. data/spec/rlint/parser/arrays.rb +147 -0
  65. data/spec/rlint/parser/classes.rb +152 -0
  66. data/spec/rlint/parser/errors.rb +19 -0
  67. data/spec/rlint/parser/hashes.rb +136 -0
  68. data/spec/rlint/parser/methods.rb +249 -0
  69. data/spec/rlint/parser/modules.rb +49 -0
  70. data/spec/rlint/parser/objects.rb +39 -0
  71. data/spec/rlint/parser/operators.rb +75 -0
  72. data/spec/rlint/parser/procs.rb +113 -0
  73. data/spec/rlint/parser/ranges.rb +49 -0
  74. data/spec/rlint/parser/regexp.rb +31 -0
  75. data/spec/rlint/parser/scalars.rb +93 -0
  76. data/spec/rlint/parser/statements.rb +550 -0
  77. data/spec/rlint/parser/variables.rb +181 -0
  78. data/spec/rlint/report.rb +30 -0
  79. data/task/test.rake +6 -0
  80. metadata +188 -0
@@ -0,0 +1,249 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse a method definition' do
5
+ token = Rlint::Parser.new('def number; return 10; end').parse[0]
6
+
7
+ token.class.should == Rlint::Token::MethodDefinitionToken
8
+ token.line.should == 1
9
+ token.column.should == 4
10
+ token.name.should == 'number'
11
+ token.visibility.should == :public
12
+ token.type.should == :method_definition
13
+
14
+ token.parameters.class.should == Rlint::Token::ParametersToken
15
+
16
+ token.value.class.should == Array
17
+ token.value.length.should == 1
18
+
19
+ token.value[0].class.should == Rlint::Token::StatementToken
20
+ token.value[0].type.should == :return
21
+
22
+ token.value[0].value.class.should == Array
23
+ token.value[0].value.length.should == 1
24
+
25
+ value = token.value[0].value[0]
26
+
27
+ value.class.should == Rlint::Token::Token
28
+ value.type.should == :integer
29
+ value.value.should == '10'
30
+ end
31
+
32
+ it 'Parse a method definition with parameters' do
33
+ code = <<-CODE
34
+ def number(a, b = 10, *args, more, &block)
35
+ return num
36
+ end
37
+ CODE
38
+
39
+ token = Rlint::Parser.new(code).parse[0]
40
+
41
+ token.class.should == Rlint::Token::MethodDefinitionToken
42
+ token.name.should == 'number'
43
+ token.line.should == 1
44
+ token.column.should == 4
45
+
46
+ params = token.parameters
47
+
48
+ params.class.should == Rlint::Token::ParametersToken
49
+ params.value.class.should == Array
50
+
51
+ # Required parameters
52
+ params.value.length.should == 1
53
+ params.value[0].class.should == Rlint::Token::VariableToken
54
+ params.value[0].name.should == 'a'
55
+
56
+ # Optional parameters
57
+ params.optional.class.should == Array
58
+ params.optional.length.should == 1
59
+
60
+ optional = params.optional[0]
61
+
62
+ optional.class.should == Rlint::Token::VariableToken
63
+ optional.name.should == 'b'
64
+
65
+ optional.value.class.should == Rlint::Token::Token
66
+ optional.value.type.should == :integer
67
+ optional.value.value.should == '10'
68
+
69
+ # Rest parameters
70
+ params.rest.name.should == 'args'
71
+ params.rest.class.should == Rlint::Token::VariableToken
72
+
73
+ # More parameters
74
+ params.more.class.should == Array
75
+ params.more.length.should == 1
76
+ params.more[0].name.should == 'more'
77
+
78
+ # Block parameters
79
+ params.block.class.should == Rlint::Token::VariableToken
80
+ params.block.name.should == 'block'
81
+ end
82
+
83
+ it 'Parse a class method definition' do
84
+ code = <<-CODE
85
+ def self.example(number = 10)
86
+ return number
87
+ end
88
+ CODE
89
+
90
+ token = Rlint::Parser.new(code).parse[0]
91
+
92
+ token.class.should == Rlint::Token::MethodDefinitionToken
93
+ token.name.should == 'example'
94
+
95
+ token.receiver.class.should == Rlint::Token::VariableToken
96
+ token.receiver.name.should == 'self'
97
+ token.receiver.type.should == :keyword
98
+
99
+ token.operator.class.should == Rlint::Token::Token
100
+ token.operator.value.should == '.'
101
+ token.operator.type.should == :period
102
+
103
+ token.parameters.class.should == Rlint::Token::ParametersToken
104
+ token.parameters.optional.class.should == Array
105
+ token.parameters.optional.length.should == 1
106
+ end
107
+
108
+ it 'Parse a private method definition' do
109
+ code = <<-CODE
110
+ private
111
+
112
+ def example
113
+ return 10
114
+ end
115
+ CODE
116
+
117
+ token = Rlint::Parser.new(code).parse[1]
118
+
119
+ token.class.should == Rlint::Token::MethodDefinitionToken
120
+ token.name.should == 'example'
121
+ token.visibility.should == :private
122
+
123
+ token.value.class.should == Array
124
+ token.value.length.should == 1
125
+ end
126
+
127
+ it 'Parse a method call' do
128
+ token = Rlint::Parser.new('puts').parse[0]
129
+
130
+ token.class.should == Rlint::Token::MethodToken
131
+ token.name.should == 'puts'
132
+ end
133
+
134
+ it 'Parse a method call with parenthesis' do
135
+ token = Rlint::Parser.new('puts()').parse[0]
136
+
137
+ token.class.should == Rlint::Token::MethodToken
138
+ token.name.should == 'puts'
139
+ end
140
+
141
+ it 'Parse a method call with parenthesis and parameters' do
142
+ token = Rlint::Parser.new('puts(10)').parse[0]
143
+
144
+ token.class.should == Rlint::Token::MethodToken
145
+ token.name.should == 'puts'
146
+
147
+ token.parameters.class.should == Array
148
+ token.parameters.length.should == 1
149
+
150
+ param = token.parameters[0]
151
+
152
+ param.class.should == Rlint::Token::Token
153
+ param.type.should == :integer
154
+ param.value.should == '10'
155
+ end
156
+
157
+ it 'Parse a method call with parameters but without parenthesis' do
158
+ token = Rlint::Parser.new('puts 10').parse[0]
159
+
160
+ token.class.should == Rlint::Token::MethodToken
161
+ token.name.should == 'puts'
162
+
163
+ token.parameters.class.should == Array
164
+ token.parameters.length.should == 1
165
+
166
+ param = token.parameters[0]
167
+
168
+ param.class.should == Rlint::Token::Token
169
+ param.type.should == :integer
170
+ param.value.should == '10'
171
+ end
172
+
173
+ it 'Parse a method called on an object with parenthesis' do
174
+ token = Rlint::Parser.new('Struct.new(:name)').parse[0]
175
+
176
+ token.class.should == Rlint::Token::MethodToken
177
+ token.name.should == 'new'
178
+
179
+ token.receiver.class.should == Rlint::Token::VariableToken
180
+ token.receiver.type.should == :constant
181
+ token.receiver.name.should == 'Struct'
182
+
183
+ token.parameters.class.should == Array
184
+ token.parameters.length.should == 1
185
+
186
+ token.parameters[0].class.should == Rlint::Token::Token
187
+ token.parameters[0].type.should == :symbol
188
+ token.parameters[0].value.should == 'name'
189
+ end
190
+
191
+ it 'Parse a method called on an object without parenthesis' do
192
+ token = Rlint::Parser.new('Struct.new :name').parse[0]
193
+
194
+ token.class.should == Rlint::Token::MethodToken
195
+ token.name.should == 'new'
196
+
197
+ token.receiver.class.should == Rlint::Token::VariableToken
198
+ token.receiver.type.should == :constant
199
+ token.receiver.name.should == 'Struct'
200
+
201
+ token.parameters.class.should == Array
202
+ token.parameters.length.should == 1
203
+
204
+ token.parameters[0].class.should == Rlint::Token::Token
205
+ token.parameters[0].type.should == :symbol
206
+ token.parameters[0].value.should == 'name'
207
+ end
208
+
209
+ it 'Parse a method called on an object with a block passed' do
210
+ token = Rlint::Parser.new('Foo.bar { |example| example }').parse[0]
211
+
212
+ token.class.should == Rlint::Token::MethodToken
213
+ token.name.should == 'bar'
214
+
215
+ token.receiver.class.should == Rlint::Token::VariableToken
216
+ token.receiver.type.should == :constant
217
+ token.receiver.name.should == 'Foo'
218
+
219
+ token.block.class.should == Rlint::Token::BlockToken
220
+ token.block.parameters.class.should == Rlint::Token::ParametersToken
221
+
222
+ token.block.parameters.value.class.should == Array
223
+ token.block.parameters.value.length.should == 1
224
+ end
225
+
226
+ it 'Parse a method call with a bare Hash as a parameter' do
227
+ token = Rlint::Parser.new('language(:name => "Ruby")').parse[0]
228
+
229
+ token.class.should == Rlint::Token::MethodToken
230
+
231
+ token.parameters.class.should == Array
232
+ token.parameters.length.should == 1
233
+
234
+ token.parameters[0].class.should == Rlint::Token::Token
235
+ token.parameters[0].type.should == :hash
236
+ end
237
+
238
+ it 'Parse a method call with a bare JSON style Hash as a parameter' do
239
+ token = Rlint::Parser.new('language(name: "Ruby")').parse[0]
240
+
241
+ token.class.should == Rlint::Token::MethodToken
242
+
243
+ token.parameters.class.should == Array
244
+ token.parameters.length.should == 1
245
+
246
+ token.parameters[0].class.should == Rlint::Token::Token
247
+ token.parameters[0].type.should == :hash
248
+ end
249
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse a module' do
5
+ code = <<-CODE
6
+ module Foo
7
+ def foo
8
+ return 'foo'
9
+ end
10
+ end
11
+ CODE
12
+
13
+ token = Rlint::Parser.new(code).parse[0]
14
+
15
+ token.class.should == Rlint::Token::Token
16
+ token.type.should == :module
17
+ token.name.should == ['Foo']
18
+ token.line.should == 1
19
+ token.column.should == 7
20
+
21
+ token.value.class.should == Array
22
+ token.value.length.should == 1
23
+
24
+ token.value[0].class.should == Rlint::Token::MethodDefinitionToken
25
+ token.value[0].name.should == 'foo'
26
+ end
27
+
28
+ it 'Parse a module with multiple name segments' do
29
+ token = Rlint::Parser.new('module A::B; end').parse[0]
30
+
31
+ token.class.should == Rlint::Token::Token
32
+ token.type.should == :module
33
+ token.name.should == ['A', 'B']
34
+
35
+ token.line.should == 1
36
+ token.column.should == 7
37
+ end
38
+
39
+ it 'Parse a top level module' do
40
+ token = Rlint::Parser.new('module ::A::B; end').parse[0]
41
+
42
+ token.class.should == Rlint::Token::Token
43
+ token.type.should == :module
44
+ token.name.should == ['A', 'B']
45
+
46
+ token.line.should == 1
47
+ token.column.should == 9
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse the reference of an object attribute' do
5
+ code = <<-CODE
6
+ obj = Struct.new(:name).new('Ruby')
7
+ obj.name
8
+ CODE
9
+
10
+ token = Rlint::Parser.new(code).parse[1]
11
+
12
+ token.class.should == Rlint::Token::MethodToken
13
+ token.name.should == 'name'
14
+
15
+ token.receiver.class.should == Rlint::Token::VariableToken
16
+ token.receiver.name.should == 'obj'
17
+ token.receiver.type.should == :local_variable
18
+ end
19
+
20
+ it 'Parse the assignment of a value to an object attribute' do
21
+ code = <<-CODE
22
+ obj = Struct.new(:name).new('Ruby')
23
+ obj.name = 'Ruby'
24
+ CODE
25
+
26
+ token = Rlint::Parser.new(code).parse[1]
27
+
28
+ token.class.should == Rlint::Token::AssignmentToken
29
+ token.name.should == 'name'
30
+
31
+ token.value.class.should == Rlint::Token::Token
32
+ token.value.type.should == :string
33
+ token.value.value.should == 'Ruby'
34
+
35
+ token.receiver.class.should == Rlint::Token::VariableToken
36
+ token.receiver.name.should == 'obj'
37
+ token.receiver.type.should == :local_variable
38
+ end
39
+ end
@@ -0,0 +1,75 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse the use of various operators' do
5
+ ['*', '-', '+', '/', '%', '^'].each do |operator|
6
+ token = Rlint::Parser.new("10 #{operator} 2").parse[0]
7
+
8
+ token.class.should == Rlint::Token::Token
9
+ token.type.should == :binary
10
+
11
+ token.value.class.should == Array
12
+ token.value.length.should == 3
13
+
14
+ left, op, right = token.value
15
+
16
+ left.class.should == Rlint::Token::Token
17
+ left.type.should == :integer
18
+ left.value.should == '10'
19
+
20
+ op.should == operator.to_sym
21
+
22
+ right.class.should == Rlint::Token::Token
23
+ right.type.should == :integer
24
+ right.value.should == '2'
25
+ end
26
+ end
27
+
28
+ it 'Parse the use of multiple operators' do
29
+ token = Rlint::Parser.new('10 and 20 and 30').parse[0]
30
+
31
+ token.class.should == Rlint::Token::Token
32
+ token.type.should == :binary
33
+
34
+ token.value.class.should == Array
35
+ token.value.length.should == 3
36
+
37
+ first = token.value[0]
38
+ last = token.value[2]
39
+
40
+ first.class.should == Rlint::Token::Token
41
+ first.type.should == :binary
42
+ first.value.length.should == 3
43
+
44
+ first.value[0].class.should == Rlint::Token::Token
45
+ first.value[0].type.should == :integer
46
+ first.value[0].value.should == '10'
47
+
48
+ first.value[1].should == :and
49
+
50
+ first.value[2].class.should == Rlint::Token::Token
51
+ first.value[2].type.should == :integer
52
+ first.value[2].value.should == '20'
53
+
54
+ token.value[1].should == :and
55
+
56
+ last.class.should == Rlint::Token::Token
57
+ last.type.should == :integer
58
+ last.value.should == '30'
59
+ end
60
+
61
+ it 'Parse unary operators' do
62
+ token = Rlint::Parser.new('!foobar').parse[0]
63
+
64
+ token.class.should == Rlint::Token::Token
65
+ token.type.should == :unary
66
+
67
+ token.value.class.should == Array
68
+ token.value.length.should == 2
69
+
70
+ token.value[0].should == :!
71
+
72
+ token.value[1].class.should == Rlint::Token::MethodToken
73
+ token.value[1].name.should == 'foobar'
74
+ end
75
+ end
@@ -0,0 +1,113 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse a Proc' do
5
+ token = Rlint::Parser.new('proc { |example| example }').parse[0]
6
+
7
+ token.class.should == Rlint::Token::MethodToken
8
+ token.name.should == 'proc'
9
+
10
+ token.block.class.should == Rlint::Token::BlockToken
11
+ token.block.parameters.class.should == Rlint::Token::ParametersToken
12
+ token.block.type.should == :block
13
+
14
+ params = token.block.parameters
15
+
16
+ params.value.class.should == Array
17
+ params.value.length.should == 1
18
+
19
+ params.value[0].class.should == Rlint::Token::VariableToken
20
+ params.value[0].type.should == :local_variable
21
+ params.value[0].name.should == 'example'
22
+
23
+ token.block.value.class.should == Array
24
+ token.block.value.length.should == 1
25
+ end
26
+
27
+ it 'Parse a proc using do/end instead of curly braces' do
28
+ token = Rlint::Parser.new('proc do |example|; example; end').parse[0]
29
+
30
+ token.class.should == Rlint::Token::MethodToken
31
+ token.name.should == 'proc'
32
+
33
+ token.block.class.should == Rlint::Token::BlockToken
34
+ token.block.parameters.class.should == Rlint::Token::ParametersToken
35
+ token.block.type.should == :block
36
+
37
+ params = token.block.parameters
38
+
39
+ params.value.class.should == Array
40
+ params.value.length.should == 1
41
+
42
+ params.value[0].class.should == Rlint::Token::VariableToken
43
+ params.value[0].type.should == :local_variable
44
+ params.value[0].name.should == 'example'
45
+
46
+ token.block.value.class.should == Array
47
+ token.block.value.length.should == 1
48
+ end
49
+
50
+ it 'Parse a Proc using Proc.new' do
51
+ token = Rlint::Parser.new('Proc.new { |example| example }').parse[0]
52
+
53
+ token.class.should == Rlint::Token::MethodToken
54
+ token.name.should == 'new'
55
+
56
+ token.receiver.class.should == Rlint::Token::VariableToken
57
+ token.receiver.name.should == 'Proc'
58
+ token.receiver.type.should == :constant
59
+
60
+ token.block.class.should == Rlint::Token::BlockToken
61
+ token.block.parameters.class.should == Rlint::Token::ParametersToken
62
+ token.block.type.should == :block
63
+
64
+ token.block.parameters.value.class.should == Array
65
+ token.block.parameters.value.length.should == 1
66
+
67
+ param = token.block.parameters.value[0]
68
+
69
+ param.class.should == Rlint::Token::VariableToken
70
+ param.name.should == 'example'
71
+ param.type.should == :local_variable
72
+ end
73
+
74
+ it 'Parse a Lambda' do
75
+ token = Rlint::Parser.new('lambda { |example| example }').parse[0]
76
+
77
+ token.class.should == Rlint::Token::MethodToken
78
+ token.name.should == 'lambda'
79
+
80
+ token.block.class.should == Rlint::Token::BlockToken
81
+ token.block.type.should == :block
82
+
83
+ token.block.parameters.class.should == Rlint::Token::ParametersToken
84
+ token.block.parameters.value.class.should == Array
85
+ token.block.parameters.value.length.should == 1
86
+
87
+ param = token.block.parameters.value[0]
88
+
89
+ param.class.should == Rlint::Token::VariableToken
90
+ param.name.should == 'example'
91
+ param.type.should == :local_variable
92
+ end
93
+
94
+ it 'Parse a Lambda using the dash rocket syntax' do
95
+ token = Rlint::Parser.new('-> example { example }').parse[0]
96
+
97
+ token.class.should == Rlint::Token::BlockToken
98
+ token.type.should == :lambda
99
+
100
+ token.parameters.class.should == Rlint::Token::ParametersToken
101
+ token.parameters.value.class.should == Array
102
+ token.parameters.value.length.should == 1
103
+
104
+ param = token.parameters.value[0]
105
+
106
+ param.class.should == Rlint::Token::VariableToken
107
+ param.name.should == 'example'
108
+ param.type.should == :local_variable
109
+
110
+ token.value.class.should == Array
111
+ token.value.length.should == 1
112
+ end
113
+ end