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.
- data/.gitignore +5 -0
- data/.rbenv-version +1 -0
- data/.yardopts +10 -0
- data/Gemfile +3 -0
- data/LICENSE +19 -0
- data/MANIFEST +79 -0
- data/README.md +48 -0
- data/Rakefile +14 -0
- data/bin/rlint +6 -0
- data/doc/.gitkeep +0 -0
- data/doc/build/.gitkeep +0 -0
- data/doc/css/.gitkeep +0 -0
- data/doc/css/common.css +68 -0
- data/lib/rlint/analyze/coding_style.rb +407 -0
- data/lib/rlint/analyze/definitions.rb +244 -0
- data/lib/rlint/analyze/method_validation.rb +104 -0
- data/lib/rlint/analyze/shadowing_variables.rb +37 -0
- data/lib/rlint/analyze/undefined_variables.rb +99 -0
- data/lib/rlint/analyze/unused_variables.rb +103 -0
- data/lib/rlint/callback.rb +67 -0
- data/lib/rlint/cli.rb +167 -0
- data/lib/rlint/constant_importer.rb +102 -0
- data/lib/rlint/definition.rb +230 -0
- data/lib/rlint/formatter/text.rb +54 -0
- data/lib/rlint/helper/definition_resolver.rb +143 -0
- data/lib/rlint/helper/scoping.rb +138 -0
- data/lib/rlint/iterator.rb +193 -0
- data/lib/rlint/options.rb +58 -0
- data/lib/rlint/parser.rb +1252 -0
- data/lib/rlint/parser_error.rb +42 -0
- data/lib/rlint/report.rb +98 -0
- data/lib/rlint/token/assignment_token.rb +46 -0
- data/lib/rlint/token/begin_rescue_token.rb +57 -0
- data/lib/rlint/token/block_token.rb +17 -0
- data/lib/rlint/token/case_token.rb +44 -0
- data/lib/rlint/token/class_token.rb +24 -0
- data/lib/rlint/token/method_definition_token.rb +64 -0
- data/lib/rlint/token/method_token.rb +58 -0
- data/lib/rlint/token/parameters_token.rb +99 -0
- data/lib/rlint/token/regexp_token.rb +15 -0
- data/lib/rlint/token/statement_token.rb +69 -0
- data/lib/rlint/token/token.rb +162 -0
- data/lib/rlint/token/variable_token.rb +18 -0
- data/lib/rlint/version.rb +3 -0
- data/lib/rlint.rb +36 -0
- data/ruby-lint.gemspec +23 -0
- data/spec/benchmarks/memory.rb +52 -0
- data/spec/benchmarks/parse_parser.rb +16 -0
- data/spec/helper.rb +4 -0
- data/spec/rlint/analyze/coding_style.rb +224 -0
- data/spec/rlint/analyze/definitions/classes.rb +114 -0
- data/spec/rlint/analyze/definitions/methods.rb +91 -0
- data/spec/rlint/analyze/definitions/modules.rb +207 -0
- data/spec/rlint/analyze/definitions/variables.rb +103 -0
- data/spec/rlint/analyze/method_validation.rb +177 -0
- data/spec/rlint/analyze/shadowing_variables.rb +30 -0
- data/spec/rlint/analyze/undefined_variables.rb +230 -0
- data/spec/rlint/analyze/unused_variables.rb +225 -0
- data/spec/rlint/callback.rb +28 -0
- data/spec/rlint/constant_importer.rb +27 -0
- data/spec/rlint/definition.rb +96 -0
- data/spec/rlint/formatter/text.rb +21 -0
- data/spec/rlint/iterator.rb +452 -0
- data/spec/rlint/parser/arrays.rb +147 -0
- data/spec/rlint/parser/classes.rb +152 -0
- data/spec/rlint/parser/errors.rb +19 -0
- data/spec/rlint/parser/hashes.rb +136 -0
- data/spec/rlint/parser/methods.rb +249 -0
- data/spec/rlint/parser/modules.rb +49 -0
- data/spec/rlint/parser/objects.rb +39 -0
- data/spec/rlint/parser/operators.rb +75 -0
- data/spec/rlint/parser/procs.rb +113 -0
- data/spec/rlint/parser/ranges.rb +49 -0
- data/spec/rlint/parser/regexp.rb +31 -0
- data/spec/rlint/parser/scalars.rb +93 -0
- data/spec/rlint/parser/statements.rb +550 -0
- data/spec/rlint/parser/variables.rb +181 -0
- data/spec/rlint/report.rb +30 -0
- data/task/test.rake +6 -0
- metadata +188 -0
data/.gitignore
ADDED
data/.rbenv-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p194
|
data/.yardopts
ADDED
data/Gemfile
ADDED
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
data/doc/.gitkeep
ADDED
File without changes
|
data/doc/build/.gitkeep
ADDED
File without changes
|
data/doc/css/.gitkeep
ADDED
File without changes
|
data/doc/css/common.css
ADDED
@@ -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
|