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
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ doc/build/*
2
+ !doc/build/.gitkeep
3
+
4
+ pkg
5
+ Gemfile.lock
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p194
data/.yardopts ADDED
@@ -0,0 +1,10 @@
1
+ ./lib/rlint/**/*.rb ./lib/rlint.rb
2
+ -m markdown
3
+ -M redcarpet
4
+ -o ./doc/build
5
+ -r ./README.md
6
+ --private
7
+ --protected
8
+ --asset ./doc/css/common.css:css/common.css
9
+ -
10
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012, Yorick Peterse
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/MANIFEST ADDED
@@ -0,0 +1,79 @@
1
+ .gitignore
2
+ .rbenv-version
3
+ .yardopts
4
+ Gemfile
5
+ LICENSE
6
+ MANIFEST
7
+ README.md
8
+ Rakefile
9
+ bin/rlint
10
+ doc/.gitkeep
11
+ doc/build/.gitkeep
12
+ doc/css/.gitkeep
13
+ doc/css/common.css
14
+ lib/rlint.rb
15
+ lib/rlint/analyze/coding_style.rb
16
+ lib/rlint/analyze/definitions.rb
17
+ lib/rlint/analyze/method_validation.rb
18
+ lib/rlint/analyze/shadowing_variables.rb
19
+ lib/rlint/analyze/undefined_variables.rb
20
+ lib/rlint/analyze/unused_variables.rb
21
+ lib/rlint/callback.rb
22
+ lib/rlint/cli.rb
23
+ lib/rlint/constant_importer.rb
24
+ lib/rlint/definition.rb
25
+ lib/rlint/formatter/text.rb
26
+ lib/rlint/helper/definition_resolver.rb
27
+ lib/rlint/helper/scoping.rb
28
+ lib/rlint/iterator.rb
29
+ lib/rlint/options.rb
30
+ lib/rlint/parser.rb
31
+ lib/rlint/parser_error.rb
32
+ lib/rlint/report.rb
33
+ lib/rlint/token/assignment_token.rb
34
+ lib/rlint/token/begin_rescue_token.rb
35
+ lib/rlint/token/block_token.rb
36
+ lib/rlint/token/case_token.rb
37
+ lib/rlint/token/class_token.rb
38
+ lib/rlint/token/method_definition_token.rb
39
+ lib/rlint/token/method_token.rb
40
+ lib/rlint/token/parameters_token.rb
41
+ lib/rlint/token/regexp_token.rb
42
+ lib/rlint/token/statement_token.rb
43
+ lib/rlint/token/token.rb
44
+ lib/rlint/token/variable_token.rb
45
+ lib/rlint/version.rb
46
+ ruby-lint.gemspec
47
+ spec/benchmarks/memory.rb
48
+ spec/benchmarks/parse_parser.rb
49
+ spec/helper.rb
50
+ spec/rlint/analyze/coding_style.rb
51
+ spec/rlint/analyze/definitions/classes.rb
52
+ spec/rlint/analyze/definitions/methods.rb
53
+ spec/rlint/analyze/definitions/modules.rb
54
+ spec/rlint/analyze/definitions/variables.rb
55
+ spec/rlint/analyze/method_validation.rb
56
+ spec/rlint/analyze/shadowing_variables.rb
57
+ spec/rlint/analyze/undefined_variables.rb
58
+ spec/rlint/analyze/unused_variables.rb
59
+ spec/rlint/callback.rb
60
+ spec/rlint/constant_importer.rb
61
+ spec/rlint/definition.rb
62
+ spec/rlint/formatter/text.rb
63
+ spec/rlint/iterator.rb
64
+ spec/rlint/parser/arrays.rb
65
+ spec/rlint/parser/classes.rb
66
+ spec/rlint/parser/errors.rb
67
+ spec/rlint/parser/hashes.rb
68
+ spec/rlint/parser/methods.rb
69
+ spec/rlint/parser/modules.rb
70
+ spec/rlint/parser/objects.rb
71
+ spec/rlint/parser/operators.rb
72
+ spec/rlint/parser/procs.rb
73
+ spec/rlint/parser/ranges.rb
74
+ spec/rlint/parser/regexp.rb
75
+ spec/rlint/parser/scalars.rb
76
+ spec/rlint/parser/statements.rb
77
+ spec/rlint/parser/variables.rb
78
+ spec/rlint/report.rb
79
+ task/test.rake
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # README
2
+
3
+ **Rlint is currently alpha quality, expect things to break and change without
4
+ notice. Patches and bug reports are more than welcome.**
5
+
6
+ Rlint (short name for Ruby Lint) is a linter and static code analysis tool for
7
+ Ruby inspired by similar tools such as JSHint. It makes it possible for
8
+ developers to detect errors such as undefined (or unused) variables and the
9
+ use of non existing methods.
10
+
11
+ ## Requirements
12
+
13
+ * Ruby 1.9 or newer
14
+ * Ripper (comes bundled with Ruby 1.9)
15
+
16
+ ## Installation
17
+
18
+ Rlint can be installed by running the following command:
19
+
20
+ $ gem install ruby-lint
21
+
22
+ Please note that there already is an existing gem called "rlint". This Gem is
23
+ **not** the same, it just happens to be a similar project (one that seems
24
+ abandoned) that uses the same name.
25
+
26
+ ## Compatibility Issues
27
+
28
+ Currently Rlint can only be executed using MRI 1.9.3, it does not run on MRI
29
+ 1.8.x due to the lack of Ripper. It also does not yet run without errors on
30
+ MRI 2.0 as the addition of named variables changes the Ripper output, something
31
+ Rlint doesn't properly handle at the moment.
32
+
33
+ For the time being Rlint will stick to using Ripper which means it's also
34
+ limited to MRI 1.9.x/2.0.x. I've been looking around for alternatives so that
35
+ Rlint can be run on Jruby/Rubinius in the future but so far I haven't really
36
+ found a worthy alternative. For now I'd rather focus on making Rlint work on
37
+ one implementation instead of a number of different ones.
38
+
39
+ Also keep in mind that while in theory Rlint should run on MRI 1.8.x I couldn't
40
+ get the "ripper" gem to install properly, thus I'm unable to confirm this. Feel
41
+ free to try it out but I won't bother with MRI 1.8.x myself if it requires more
42
+ than a few minutes worth of work.
43
+
44
+ ## License
45
+
46
+ All source code in this repository is licensed under the MIT license unless
47
+ specified otherwise. A copy of this license can be found in the file "LICENSE"
48
+ in the root directory of this repository.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems/package_task'
2
+
3
+ GEMSPEC = Gem::Specification.load('ruby-lint.gemspec')
4
+
5
+ Dir['./task/*.rake'].each do |task|
6
+ import(task)
7
+ end
8
+
9
+ Gem::PackageTask.new(GEMSPEC) do |pkg|
10
+ pkg.need_tar = false
11
+ pkg.need_zip = false
12
+ end
13
+
14
+ task :default => :test
data/bin/rlint ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path('../../lib/rlint', __FILE__)
4
+ require 'rlint/cli'
5
+
6
+ Rlint::CLI.new.run
data/doc/.gitkeep ADDED
File without changes
File without changes
data/doc/css/.gitkeep ADDED
File without changes
@@ -0,0 +1,68 @@
1
+ body
2
+ {
3
+ font-size: 14px;
4
+ line-height: 1.6;
5
+ margin: 0 auto;
6
+ max-width: 960px;
7
+ }
8
+
9
+ p code
10
+ {
11
+ background: #f2f2f2;
12
+ padding-left: 3px;
13
+ padding-right: 3px;
14
+ }
15
+
16
+ pre.code
17
+ {
18
+ font-size: 13px;
19
+ line-height: 1.4;
20
+ }
21
+
22
+ /**
23
+ * YARD uses generic table styles, using a special class means those tables
24
+ * don't get messed up.
25
+ */
26
+ .table
27
+ {
28
+ border: 1px solid #ccc;
29
+ border-right: none;
30
+ border-collapse: separate;
31
+ border-spacing: 0;
32
+ text-align: left;
33
+ }
34
+
35
+ .table.full
36
+ {
37
+ width: 100%;
38
+ }
39
+
40
+ .table .field_name
41
+ {
42
+ min-width: 160px;
43
+ }
44
+
45
+ .table thead tr th.no_sort:first-child
46
+ {
47
+ width: 25px;
48
+ }
49
+
50
+ .table thead tr th, .table tbody tr td
51
+ {
52
+ border-bottom: 1px solid #ccc;
53
+ border-right: 1px solid #ccc;
54
+ min-width: 20px;
55
+ padding: 8px 5px;
56
+ text-align: left;
57
+ vertical-align: top;
58
+ }
59
+
60
+ .table tbody tr:last-child td
61
+ {
62
+ border-bottom: none;
63
+ }
64
+
65
+ .table tr:nth-child(odd) td
66
+ {
67
+ background: #f9f9f9;
68
+ }
@@ -0,0 +1,407 @@
1
+ module Rlint
2
+ module Analyze
3
+ ##
4
+ # {Rlint::Analyze::CodingStyle} checks if a block of code matches a given
5
+ # set of coding standards. While none of the problems found by this class
6
+ # are considered harmful they are usually frowned upon as they do not
7
+ # follow the unofficial but generally accepted Ruby coding standards.
8
+ #
9
+ # ## Standards References
10
+ #
11
+ # The following was used to determine the standards this class should
12
+ # assume to be correct:
13
+ #
14
+ # * https://github.com/styleguide/ruby
15
+ # * https://github.com/bbatsov/ruby-style-guide
16
+ # * http://confluence.jetbrains.net/display/RUBYDEV/RubyMine+Inspections
17
+ # * My own opinion
18
+ #
19
+ # ## Checks
20
+ #
21
+ # This class checks for the following:
22
+ #
23
+ # * The length of method and variable names, should be less than the value
24
+ # set in {Rlint::Analyze::CodingStyle::MAXIMUM\_NAME\_LENGTH}.
25
+ # * The use of class variables (it's relatively rare that you actually need
26
+ # those).
27
+ # * The use of parenthesis around various statements: these are not needed
28
+ # in Ruby.
29
+ # * The use of camelCase for method and variable names instead of
30
+ # `snake_case`, the latter is what Ruby code should use.
31
+ # * Whether or not predicate methods are named correctly.
32
+ # * If a particular method name should be replaced by a different one (e.g.
33
+ # "map" instead of "collect").
34
+ #
35
+ class CodingStyle < Rlint::Callback
36
+ ##
37
+ # A short description of this class.
38
+ #
39
+ # @return [String]
40
+ #
41
+ DESCRIPTION = 'Checks the coding style of a block of code.'
42
+
43
+ ##
44
+ # The maximum length for method and variable names.
45
+ #
46
+ # @return [Fixnum]
47
+ #
48
+ MAXIMUM_NAME_LENGTH = 30
49
+
50
+ ##
51
+ # Hash containing the names of method names and the names that should be
52
+ # used instead.
53
+ #
54
+ # @return [Hash]
55
+ #
56
+ RECOMMENDED_METHOD_NAMES = {
57
+ 'collect' => 'map',
58
+ 'detect' => 'find',
59
+ 'find_all' => 'select',
60
+ 'inject' => 'reduce',
61
+ 'length' => 'size'
62
+ }
63
+
64
+ ##
65
+ # @see Rlint::Callback#initialize
66
+ #
67
+ def initialize(*args)
68
+ super
69
+
70
+ @in_method = false
71
+ @predicate_method = false
72
+ end
73
+
74
+ ##
75
+ # Called when an instance variable is found.
76
+ #
77
+ # The following checks are run for instance variables:
78
+ #
79
+ # * Whether or not instance variables are `snake_cased` instead of
80
+ # camelCased.
81
+ # * Whether or not the length of an instance variable is smaller than the
82
+ # value defined in {Rlint::Analyze::CodingStyle::MAXIMUM\_NAME\_LENGTH}.
83
+ #
84
+ # @param [Rlint::Token::VariableToken] token The token containing details
85
+ # about the variable.
86
+ #
87
+ def on_instance_variable(token)
88
+ validate_name(token)
89
+ end
90
+
91
+ ##
92
+ # Called when a class variable is found.
93
+ #
94
+ # This method will check for the same things as
95
+ # {Rlint::Analyze::CodingStyle#on_instance_variable} along with adding an
96
+ # info message about class variables being discouraged.
97
+ #
98
+ # @see Rlint::Analyze::CodingStyle#on_instance_variable
99
+ #
100
+ def on_class_variable(token)
101
+ validate_name(token)
102
+
103
+ info(
104
+ 'the use of class variables is discouraged',
105
+ token.line,
106
+ token.column
107
+ )
108
+ end
109
+
110
+ ##
111
+ # Called when a constant is found.
112
+ #
113
+ # @see Rlint::Analyze::CodingStyle#on_instance_variable
114
+ #
115
+ def on_constant(token)
116
+ validate_name_length(token)
117
+ end
118
+
119
+ ##
120
+ # Called when a global variable is found.
121
+ #
122
+ # @see Rlint::Analyze::CodingStyle#on_instance_variable
123
+ #
124
+ def on_global_variable(token)
125
+ validate_name(token)
126
+ end
127
+
128
+ ##
129
+ # Called when an instance variable is found.
130
+ #
131
+ # @see Rlint::Analyze::CodingStyle#on_instance_variable
132
+ #
133
+ def on_local_variable(token)
134
+ validate_name(token)
135
+ end
136
+
137
+ ##
138
+ # Called when a value is assigned.
139
+ #
140
+ # This method checks for the name of the used variable (similar to
141
+ # instance variables) as well as adding a warning when an instance
142
+ # variable is assigned.
143
+ #
144
+ # @see Rlint::Analyze::CodingStyle#on_instance_variable
145
+ # @see Rlint::Analyze::CodingStyle#on_class_variable
146
+ #
147
+ def on_assignment(token)
148
+ validate_name(token)
149
+
150
+ if token.type == :class_variable
151
+ info(
152
+ 'the use of class variables is discouraged',
153
+ token.line,
154
+ token.column
155
+ )
156
+ end
157
+ end
158
+
159
+ ##
160
+ # Called when a return statement is found.
161
+ #
162
+ # @param [Rlint::Token::StatementToken] token The token of the return
163
+ # statement.
164
+ #
165
+ def on_return(token)
166
+ if !token.value or token.value.empty? or !@in_method
167
+ return
168
+ end
169
+
170
+ token.value.each do |value|
171
+ # TODO: this probably won't work very well if there's a lambda inside
172
+ # a method that returns `true` or `false`.
173
+ if value.type == :keyword \
174
+ and (value.name == 'true' or value.name == 'false')
175
+ @predicate_method = true
176
+
177
+ break
178
+ end
179
+ end
180
+ end
181
+
182
+ ##
183
+ # Called when a method is defined. This method validates the name similar
184
+ # to instance variables as well as checking if the method definition
185
+ # modifies a core Ruby constant.
186
+ #
187
+ # @see Rlint::Analyze::CodingStyle#on_instance_variable
188
+ #
189
+ def on_method_definition(token)
190
+ validate_name(token)
191
+
192
+ if token.receiver
193
+ validate_ruby_constant_modification(token.receiver)
194
+ end
195
+
196
+ @in_method = true
197
+ end
198
+
199
+ ##
200
+ # Called when a class is created. This callback adds a warning if a core
201
+ # Ruby constant is modified.
202
+ #
203
+ # @param [Rlint::Token::ClassToken] token Token class containing details
204
+ # about the newly created class.
205
+ #
206
+ def on_class(token)
207
+ validate_ruby_constant_modification(token)
208
+ end
209
+
210
+ ##
211
+ # Called after a method token has been processed. This callback checks if
212
+ # a method is a predicate method and if so if the name is set correctly.
213
+ #
214
+ # @param [Rlint::Token::MethodDefinitionToken] token The token containing
215
+ # details about the method definition.
216
+ # @todo This method currently only performs a very limited check for
217
+ # predicate methods. Once a proper scoping system has been implemented
218
+ # this method should be updated accordingly.
219
+ #
220
+ def after_method_definition(token)
221
+ if @predicate_method and token.name !~ /\?$/
222
+ info(
223
+ 'predicate methods should end with a question mark',
224
+ token.line,
225
+ token.column
226
+ )
227
+ end
228
+
229
+ @in_method = false
230
+ @predicate_method = false
231
+ end
232
+
233
+ ##
234
+ # Called when a method call is found.
235
+ #
236
+ # This method checks if the used method should be named differently
237
+ # instead (e.g. "map" instead of "collect").
238
+ #
239
+ # @param [Rlint::Token::MethodToken] token Token containing details about
240
+ # the method.
241
+ #
242
+ def on_method(token)
243
+ if RECOMMENDED_METHOD_NAMES.key?(token.name)
244
+ recommended = RECOMMENDED_METHOD_NAMES[token.name]
245
+
246
+ info(
247
+ 'it is recommended to use the method "%s" instead of "%s"' % [
248
+ recommended,
249
+ token.name
250
+ ],
251
+ token.line,
252
+ token.column
253
+ )
254
+ end
255
+ end
256
+
257
+ ##
258
+ # Called when an if statement is found.
259
+ #
260
+ # This method checks to see if there are any parenthesis around the
261
+ # statement and adds an info message if this is the case.
262
+ #
263
+ # @param [Rlint::Token::StatementToken] token The token containing
264
+ # details about the if statement.
265
+ #
266
+ def on_if(token)
267
+ validate_parenthesis(token)
268
+ end
269
+
270
+ ##
271
+ # Called when an elsif statement is found.
272
+ #
273
+ # @see Rlint::Analyze::CodingStyle#on_if
274
+ #
275
+ def on_elsif(token)
276
+ validate_parenthesis(token)
277
+ end
278
+
279
+ ##
280
+ # Called when a while statement is found.
281
+ #
282
+ # @see Rlint::Analyze::CodingStyle#on_if
283
+ #
284
+ def on_while(token)
285
+ validate_parenthesis(token)
286
+ end
287
+
288
+ ##
289
+ # Called when a case statement is found.
290
+ #
291
+ # @see Rlint::Analyze::CodingStyle#on_if
292
+ #
293
+ def on_case(token)
294
+ validate_parenthesis(token)
295
+ end
296
+
297
+ ##
298
+ # Called when a when statement is found.
299
+ #
300
+ # @see Rlint::Analyze::CodingStyle#on_if
301
+ #
302
+ def on_when(token)
303
+ validate_parenthesis(token)
304
+ end
305
+
306
+ ##
307
+ # Called when an until statement is found.
308
+ #
309
+ # @see Rlint::Analyze::CodingStyle#on_if
310
+ #
311
+ def on_until(token)
312
+ validate_parenthesis(token)
313
+ end
314
+
315
+ ##
316
+ # Called when an unless statement is found.
317
+ #
318
+ # @see Rlint::Analyze::CodingStyle#on_if
319
+ #
320
+ def on_unless(token)
321
+ validate_parenthesis(token)
322
+ end
323
+
324
+ private
325
+
326
+ ##
327
+ # Validates the name of the specified token. This method will check for
328
+ # the use of camelCase as well as checking for the length of the name.
329
+ #
330
+ # @param [Rlint::Token::Token] token The token to validate.
331
+ #
332
+ def validate_name(token)
333
+ if !token.respond_to?(:name) or !token.name
334
+ return
335
+ end
336
+
337
+ if token.name =~ /[a-z]+[A-Z]+/
338
+ info(
339
+ 'the use of camelCase for names is discouraged',
340
+ token.line,
341
+ token.column
342
+ )
343
+ end
344
+
345
+ validate_name_length(token)
346
+ end
347
+
348
+ ##
349
+ # Checks if the name of the given token is too long or not. The maximum
350
+ # length of names is set in
351
+ # {Rlint::Analyze::CodingStyle::MAXIMUM\_NAME\_LENGTH}.
352
+ #
353
+ # @param [Rlint::Token::Token] token The token to validate.
354
+ #
355
+ def validate_name_length(token)
356
+ if !token.respond_to?(:name) or !token.name
357
+ return
358
+ end
359
+
360
+ if token.name.length > MAXIMUM_NAME_LENGTH
361
+ info(
362
+ "method and variable names should not be longer than " \
363
+ "#{MAXIMUM_NAME_LENGTH} characters",
364
+ token.line,
365
+ token.column
366
+ )
367
+ end
368
+ end
369
+
370
+ ##
371
+ # Checks if there are any parenthesis wrapped around a statement.
372
+ #
373
+ # @param [Rlint::Token::Token] token The token to validate.
374
+ #
375
+ def validate_parenthesis(token)
376
+ if token.code =~ /#{token.type}\s*\(/
377
+ info(
378
+ 'the use of parenthesis for statements is discouraged',
379
+ token.line,
380
+ token.column
381
+ )
382
+ end
383
+ end
384
+
385
+ ##
386
+ # Adds a warning for modifying a core Ruby constant.
387
+ #
388
+ # @param [Rlint::Token::Token] token The token class to validate.
389
+ #
390
+ def validate_ruby_constant_modification(token)
391
+ if token.name.is_a?(Array)
392
+ name = token.name.join('::')
393
+ else
394
+ name = token.name
395
+ end
396
+
397
+ if Object.constants.include?(name.to_sym)
398
+ warning(
399
+ 'modification of a core Ruby constant',
400
+ token.line,
401
+ token.column
402
+ )
403
+ end
404
+ end
405
+ end # CodingStyle
406
+ end # Analyze
407
+ end # Rlint