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