ruby-lint 0.0.1a

Sign up to get free protection for your applications and to get access to all the features.
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,147 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse an Array' do
5
+ token = Rlint::Parser.new('[10, 20]').parse[0]
6
+
7
+ token.class.should == Rlint::Token::Token
8
+ token.type.should == :array
9
+
10
+ token.value.class.should == Array
11
+ token.value.length.should == 2
12
+
13
+ token.line.should == 1
14
+ token.column.should == 8
15
+ token.code.should == '[10, 20]'
16
+
17
+ token.value[0].class.should == Rlint::Token::Token
18
+ token.value[0].type.should == :integer
19
+ token.value[0].value.should == '10'
20
+
21
+ token.value[1].class.should == Rlint::Token::Token
22
+ token.value[1].type.should == :integer
23
+ token.value[1].value.should == '20'
24
+ end
25
+
26
+ it 'Parse an Array using %w{}' do
27
+ token = Rlint::Parser.new('%w{10 20}').parse[0]
28
+
29
+ token.class.should == Rlint::Token::Token
30
+ token.type.should == :array
31
+
32
+ token.value.class.should == Array
33
+ token.value.length.should == 2
34
+
35
+ token.line.should == 1
36
+ token.column.should == 9
37
+ token.code.should == '%w{10 20}'
38
+
39
+ token.value[0].class.should == Rlint::Token::Token
40
+ token.value[0].type.should == :string
41
+ token.value[0].value.should == '10'
42
+
43
+ token.value[1].class.should == Rlint::Token::Token
44
+ token.value[1].type.should == :string
45
+ token.value[1].value.should == '20'
46
+ end
47
+
48
+ it 'Parse an Array using %W{}' do
49
+ token = Rlint::Parser.new('%W{10 20}').parse[0]
50
+
51
+ token.class.should == Rlint::Token::Token
52
+ token.type.should == :array
53
+
54
+ token.value.class.should == Array
55
+ token.value.length.should == 2
56
+
57
+ token.line.should == 1
58
+ token.column.should == 9
59
+ token.code.should == '%W{10 20}'
60
+
61
+ token.value[0].class.should == Rlint::Token::Token
62
+ token.value[0].type.should == :string
63
+ token.value[0].value.should == '10'
64
+
65
+ token.value[1].class.should == Rlint::Token::Token
66
+ token.value[1].type.should == :string
67
+ token.value[1].value.should == '20'
68
+ end
69
+
70
+ it 'Parse an Array index reference' do
71
+ token = Rlint::Parser.new("[10][0]").parse[0]
72
+
73
+ token.class.should == Rlint::Token::Token
74
+ token.line.should == 1
75
+ token.column.should == 4
76
+ token.code.should == '[10][0]'
77
+
78
+ token.key.class.should == Array
79
+ token.key.length.should == 1
80
+
81
+ token.key[0].class.should == Rlint::Token::Token
82
+ token.key[0].type.should == :integer
83
+ token.key[0].value.should == '0'
84
+ end
85
+
86
+ it 'Parse an Array index reference using a variable' do
87
+ token = Rlint::Parser.new("numbers = [10]\nnumbers[0]").parse[1]
88
+
89
+ token.class.should == Rlint::Token::VariableToken
90
+ token.line.should == 2
91
+ token.column.should == 0
92
+ token.name.should == 'numbers'
93
+ token.code.should == 'numbers[0]'
94
+
95
+ token.key.class.should == Array
96
+ token.key.length.should == 1
97
+
98
+ token.key[0].class.should == Rlint::Token::Token
99
+ token.key[0].type.should == :integer
100
+ token.key[0].value.should == '0'
101
+ end
102
+
103
+ it 'Parse multiple Array index references' do
104
+ token = Rlint::Parser.new("numbers = [10]\nnumbers[0,1]").parse[1]
105
+
106
+ token.class.should == Rlint::Token::VariableToken
107
+ token.line.should == 2
108
+ token.column.should == 0
109
+ token.name.should == 'numbers'
110
+ token.code.should == 'numbers[0,1]'
111
+
112
+ token.key.class.should == Array
113
+ token.key.length.should == 2
114
+
115
+ token.key[0].class.should == Rlint::Token::Token
116
+ token.key[0].type.should == :integer
117
+ token.key[0].value.should == '0'
118
+
119
+ token.key[1].class.should == Rlint::Token::Token
120
+ token.key[1].type.should == :integer
121
+ token.key[1].value.should == '1'
122
+ end
123
+
124
+ it 'Parse the assignment of a value to an array index' do
125
+ token = Rlint::Parser.new("numbers = []\nnumbers[0] = 10").parse[1]
126
+
127
+ token.class.should == Rlint::Token::AssignmentToken
128
+
129
+ token.line.should == 2
130
+ token.column.should == 12
131
+ token.code.should == 'numbers[0] = 10'
132
+
133
+ token.value.class.should == Rlint::Token::Token
134
+ token.value.type.should == :integer
135
+ token.value.value.should == '10'
136
+
137
+ token.receiver.class.should == Rlint::Token::VariableToken
138
+ token.receiver.name.should == 'numbers'
139
+
140
+ token.receiver.key.class.should == Array
141
+ token.receiver.key.length.should == 1
142
+
143
+ token.receiver.key[0].class.should == Rlint::Token::Token
144
+ token.receiver.key[0].type.should == :integer
145
+ token.receiver.key[0].value.should == '0'
146
+ end
147
+ end
@@ -0,0 +1,152 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse a class declaration' do
5
+ token = Rlint::Parser.new('class Foo; end').parse[0]
6
+
7
+ token.class.should == Rlint::Token::ClassToken
8
+ token.name.should == ['Foo']
9
+ token.type.should == :class
10
+ token.line.should == 1
11
+ token.column.should == 6
12
+ token.code.should == 'class Foo; end'
13
+
14
+ token.value.class.should == Array
15
+ token.value.length.should == 0
16
+ end
17
+
18
+ it 'Parse a top level class declaration' do
19
+ token = Rlint::Parser.new('class ::Foo; end').parse[0]
20
+
21
+ token.class.should == Rlint::Token::ClassToken
22
+ token.name.should == ['Foo']
23
+ token.type.should == :class
24
+ end
25
+
26
+ it 'Parse a class declaration with a parent class' do
27
+ token = Rlint::Parser.new('class Foo < Bar; end').parse[0]
28
+
29
+ token.class.should == Rlint::Token::ClassToken
30
+ token.name.should == ['Foo']
31
+ token.parent.should == ['Bar']
32
+ token.type.should == :class
33
+ token.line.should == 1
34
+ token.column.should == 6
35
+ token.code.should == 'class Foo < Bar; end'
36
+
37
+ token.value.class.should == Array
38
+ token.value.length.should == 0
39
+ end
40
+
41
+ it 'Parse a class declaration with multiple name segments' do
42
+ token = Rlint::Parser.new('class Foo::Bar < A::B; end').parse[0]
43
+
44
+ token.class.should == Rlint::Token::ClassToken
45
+ token.type.should == :class
46
+ token.name.should == ['Foo', 'Bar']
47
+
48
+ token.parent.should == ['A', 'B']
49
+ token.line.should == 1
50
+ token.column.should == 6
51
+ token.code.should == 'class Foo::Bar < A::B; end'
52
+ end
53
+
54
+ it 'Parse a top level class declaration with multiple name segments' do
55
+ token = Rlint::Parser.new('class ::Foo::Bar; end').parse[0]
56
+
57
+ token.class.should == Rlint::Token::ClassToken
58
+ token.type.should == :class
59
+ token.name.should == ['Foo', 'Bar']
60
+ token.line.should == 1
61
+ token.column.should == 8
62
+ token.code.should == 'class ::Foo::Bar; end'
63
+ end
64
+
65
+ it 'Parse the assignments of method visibilities' do
66
+ code = <<-CODE
67
+ class First
68
+ private
69
+
70
+ def private_method
71
+ return 'private method'
72
+ end
73
+ end
74
+
75
+ def public_method
76
+ return 'public method'
77
+ end
78
+
79
+ class Second
80
+ protected
81
+
82
+ def protected_method
83
+ return 'protected method'
84
+ end
85
+ end
86
+ CODE
87
+
88
+ first, pub_method, second = Rlint::Parser.new(code).parse
89
+
90
+ first.class.should == Rlint::Token::ClassToken
91
+ first.name.should == ['First']
92
+ first.line.should == 1
93
+ first.column.should == 6
94
+ first.code.should == 'class First'
95
+
96
+ first.value[0].class.should == Rlint::Token::MethodDefinitionToken
97
+ first.value[0].name.should == 'private_method'
98
+ first.value[0].visibility.should == :private
99
+ first.value[0].line.should == 4
100
+ first.value[0].column.should == 6
101
+ first.value[0].code.should == ' def private_method'
102
+
103
+ pub_method.class.should == Rlint::Token::MethodDefinitionToken
104
+ pub_method.name.should == 'public_method'
105
+ pub_method.visibility.should == :public
106
+
107
+ second.class.should == Rlint::Token::ClassToken
108
+ second.name.should == ['Second']
109
+
110
+ second.value[0].class.should == Rlint::Token::MethodDefinitionToken
111
+ second.value[0].name.should == 'protected_method'
112
+ second.value[0].visibility.should == :protected
113
+ end
114
+
115
+ it 'Parse the creation of methods using class << self' do
116
+ code = <<-CODE
117
+ class Person
118
+ class << self
119
+ def class_method_1
120
+
121
+ end
122
+
123
+ def class_method_2
124
+
125
+ end
126
+ end
127
+ end
128
+ CODE
129
+
130
+ token = Rlint::Parser.new(code).parse[0]
131
+
132
+ token.class.should == Rlint::Token::ClassToken
133
+ token.name.should == ['Person']
134
+
135
+ token.value.class.should == Array
136
+ token.value.length.should == 2
137
+
138
+ method_1, method_2 = token.value
139
+
140
+ method_1.class.should == Rlint::Token::MethodDefinitionToken
141
+ method_1.name.should == 'class_method_1'
142
+
143
+ method_1.receiver.class.should == Rlint::Token::VariableToken
144
+ method_1.receiver.name.should == 'self'
145
+
146
+ method_2.class.should == Rlint::Token::MethodDefinitionToken
147
+ method_2.name.should == 'class_method_2'
148
+
149
+ method_2.receiver.class.should == Rlint::Token::VariableToken
150
+ method_2.receiver.name.should == 'self'
151
+ end
152
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse a syntax error' do
5
+ code = <<-CODE
6
+ def example
7
+ -
8
+ end
9
+ CODE
10
+
11
+ error = should.raise?(Rlint::ParserError) do
12
+ Rlint::Parser.new(code).parse
13
+ end
14
+
15
+ error.file.should == '(rlint)'
16
+ error.line.should == 3
17
+ error.column.should == 3
18
+ end
19
+ end
@@ -0,0 +1,136 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ describe 'Rlint::Parser' do
4
+ it 'Parse a Hash' do
5
+ input = '{"name" => "Ruby", "Foo" => "Bar"}'
6
+ token = Rlint::Parser.new(input).parse[0]
7
+
8
+ token.class.should == Rlint::Token::Token
9
+ token.line.should == 1
10
+ token.column.should == 2
11
+ token.code.should == input
12
+
13
+ token.value.class.should == Array
14
+ token.value.length.should == 2
15
+
16
+ first = token.value[0]
17
+ last = token.value[1]
18
+
19
+ first.class.should == Rlint::Token::Token
20
+ first.name.should == 'name'
21
+ first.type.should == :string
22
+
23
+ first.value.class.should == Rlint::Token::Token
24
+ first.value.type.should == :string
25
+ first.value.value.should == 'Ruby'
26
+
27
+ last.class.should == Rlint::Token::Token
28
+ last.name.should == 'Foo'
29
+ last.type.should == :string
30
+
31
+ last.value.class.should == Rlint::Token::Token
32
+ last.value.type.should == :string
33
+ last.value.value.should == 'Bar'
34
+ end
35
+
36
+ it 'Parse a Hash using symbols' do
37
+ input = '{:name => "Ruby", :Foo => "Bar"}'
38
+ token = Rlint::Parser.new(input).parse[0]
39
+
40
+ token.class.should == Rlint::Token::Token
41
+ token.line.should == 1
42
+ token.column.should == 2
43
+ token.code.should == input
44
+
45
+ token.value.class.should == Array
46
+ token.value.length.should == 2
47
+
48
+ first = token.value[0]
49
+ last = token.value[1]
50
+
51
+ first.class.should == Rlint::Token::Token
52
+ first.name.should == 'name'
53
+ first.type.should == :symbol
54
+
55
+ first.value.class.should == Rlint::Token::Token
56
+ first.value.type.should == :string
57
+ first.value.value.should == 'Ruby'
58
+
59
+ last.class.should == Rlint::Token::Token
60
+ last.name.should == 'Foo'
61
+ last.type.should == :symbol
62
+
63
+ last.value.class.should == Rlint::Token::Token
64
+ last.value.type.should == :string
65
+ last.value.value.should == 'Bar'
66
+ end
67
+
68
+ it 'Parse a Hash using symbols and the JSON syntax' do
69
+ input = '{name: "Ruby"}'
70
+ token = Rlint::Parser.new(input).parse[0]
71
+
72
+ token.class.should == Rlint::Token::Token
73
+ token.line.should == 1
74
+ token.column.should == 1
75
+ token.code.should == input
76
+
77
+ token.value.class.should == Array
78
+ token.value.length.should == 1
79
+
80
+ pair = token.value[0]
81
+
82
+ pair.name.should == 'name:'
83
+ pair.type.should == :symbol
84
+
85
+ pair.value.class.should == Rlint::Token::Token
86
+ pair.value.type.should == :string
87
+ pair.value.value.should == 'Ruby'
88
+ end
89
+
90
+ it 'Parse a Hash key reference' do
91
+ input = '{:name => "Ruby"}[:name]'
92
+ token = Rlint::Parser.new(input).parse[0]
93
+
94
+ token.class.should == Rlint::Token::Token
95
+ token.type.should == :hash
96
+ token.line.should == 1
97
+ token.column.should == 2
98
+ token.code.should == input
99
+
100
+ token.key.class.should == Array
101
+ token.key.length.should == 1
102
+
103
+ token.key[0].class.should == Rlint::Token::Token
104
+ token.key[0].type.should == :symbol
105
+ token.key[0].value.should == 'name'
106
+
107
+ token.value.class.should == Array
108
+ token.value.length.should == 1
109
+
110
+ pair = token.value[0]
111
+
112
+ pair.class.should == Rlint::Token::Token
113
+ pair.type.should == :symbol
114
+ pair.name.should == 'name'
115
+
116
+ pair.value.class.should == Rlint::Token::Token
117
+ pair.value.value.should == 'Ruby'
118
+ pair.value.type.should == :string
119
+ end
120
+
121
+ it 'Parse a Hash key reference using a variable' do
122
+ token = Rlint::Parser.new("hash = {:name => 'Ruby'}\nhash[:name]").parse[1]
123
+
124
+ token.class.should == Rlint::Token::VariableToken
125
+ token.line.should == 2
126
+ token.column.should == 0
127
+ token.code.should == 'hash[:name]'
128
+
129
+ token.key.class.should == Array
130
+ token.key.length.should == 1
131
+
132
+ token.key[0].class.should == Rlint::Token::Token
133
+ token.key[0].value.should == 'name'
134
+ token.key[0].type.should == :symbol
135
+ end
136
+ end