ruby-lint 0.0.2 → 0.0.3
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.tar.gz.asc +17 -0
- data/.gitignore +1 -0
- data/.travis.yml +25 -0
- data/.yardopts +4 -0
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/MANIFEST +238 -49
- data/README.md +84 -131
- data/Rakefile +6 -0
- data/bin/ruby-lint +2 -2
- data/checksum/.gitkeep +0 -0
- data/doc/DCO.md +26 -0
- data/doc/architecture.md +63 -0
- data/doc/code_analysis.md +90 -0
- data/doc/configuration.md +86 -0
- data/doc/contributing.md +16 -0
- data/doc/graphviz/flow.dot +7 -0
- data/doc/images/.gitkeep +0 -0
- data/doc/images/flow.png +0 -0
- data/lib/ruby-lint.rb +35 -35
- data/lib/ruby-lint/analyze/argument_amount.rb +73 -0
- data/lib/ruby-lint/analyze/shadowing_variables.rb +19 -24
- data/lib/ruby-lint/analyze/undefined_methods.rb +68 -0
- data/lib/ruby-lint/analyze/undefined_variables.rb +42 -69
- data/lib/ruby-lint/analyze/unused_variables.rb +23 -78
- data/lib/ruby-lint/base.rb +85 -0
- data/lib/ruby-lint/cli.rb +23 -167
- data/lib/ruby-lint/cli/analyze.rb +99 -0
- data/lib/ruby-lint/cli/ast.rb +35 -0
- data/lib/ruby-lint/cli/base.rb +120 -0
- data/lib/ruby-lint/configuration.rb +112 -0
- data/lib/ruby-lint/constant_loader.rb +92 -0
- data/lib/ruby-lint/definition/ruby_method.rb +248 -0
- data/lib/ruby-lint/definition/ruby_object.rb +757 -0
- data/lib/ruby-lint/definition_generator.rb +155 -0
- data/lib/ruby-lint/definitions/core.rb +5 -0
- data/lib/ruby-lint/definitions/core/arg0.rb +7 -0
- data/lib/ruby-lint/definitions/core/argf.rb +7 -0
- data/lib/ruby-lint/definitions/core/argument_error.rb +12 -0
- data/lib/ruby-lint/definitions/core/argv.rb +7 -0
- data/lib/ruby-lint/definitions/core/array.rb +414 -0
- data/lib/ruby-lint/definitions/core/autoload.rb +39 -0
- data/lib/ruby-lint/definitions/core/basic_object.rb +46 -0
- data/lib/ruby-lint/definitions/core/bignum.rb +128 -0
- data/lib/ruby-lint/definitions/core/binding.rb +52 -0
- data/lib/ruby-lint/definitions/core/class.rb +23 -0
- data/lib/ruby-lint/definitions/core/comparable.rb +38 -0
- data/lib/ruby-lint/definitions/core/complex.rb +195 -0
- data/lib/ruby-lint/definitions/core/condition_variable.rb +19 -0
- data/lib/ruby-lint/definitions/core/continuation.rb +8 -0
- data/lib/ruby-lint/definitions/core/data.rb +8 -0
- data/lib/ruby-lint/definitions/core/date.rb +706 -0
- data/lib/ruby-lint/definitions/core/date_time.rb +381 -0
- data/lib/ruby-lint/definitions/core/default_record_separator.rb +7 -0
- data/lib/ruby-lint/definitions/core/digest.rb +166 -0
- data/lib/ruby-lint/definitions/core/dir.rb +496 -0
- data/lib/ruby-lint/definitions/core/encoding.rb +2030 -0
- data/lib/ruby-lint/definitions/core/encoding_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/enumerable.rb +352 -0
- data/lib/ruby-lint/definitions/core/enumerator.rb +37 -0
- data/lib/ruby-lint/definitions/core/env.rb +7 -0
- data/lib/ruby-lint/definitions/core/eoferror.rb +8 -0
- data/lib/ruby-lint/definitions/core/erb.rb +304 -0
- data/lib/ruby-lint/definitions/core/errno.rb +3331 -0
- data/lib/ruby-lint/definitions/core/etc.rb +138 -0
- data/lib/ruby-lint/definitions/core/exception.rb +72 -0
- data/lib/ruby-lint/definitions/core/false.rb +7 -0
- data/lib/ruby-lint/definitions/core/false_class.rb +30 -0
- data/lib/ruby-lint/definitions/core/fatal_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/fiber.rb +35 -0
- data/lib/ruby-lint/definitions/core/fiber_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/file.rb +1277 -0
- data/lib/ruby-lint/definitions/core/file_list.rb +727 -0
- data/lib/ruby-lint/definitions/core/file_test.rb +106 -0
- data/lib/ruby-lint/definitions/core/file_utils.rb +1027 -0
- data/lib/ruby-lint/definitions/core/fixnum.rb +156 -0
- data/lib/ruby-lint/definitions/core/float.rb +307 -0
- data/lib/ruby-lint/definitions/core/float_domain_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/gc.rb +57 -0
- data/lib/ruby-lint/definitions/core/gem.rb +3161 -0
- data/lib/ruby-lint/definitions/core/hash.rb +512 -0
- data/lib/ruby-lint/definitions/core/immediate_value.rb +19 -0
- data/lib/ruby-lint/definitions/core/index_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/integer.rb +100 -0
- data/lib/ruby-lint/definitions/core/interrupt.rb +14 -0
- data/lib/ruby-lint/definitions/core/io.rb +928 -0
- data/lib/ruby-lint/definitions/core/ioerror.rb +8 -0
- data/lib/ruby-lint/definitions/core/kernel.rb +504 -0
- data/lib/ruby-lint/definitions/core/key_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/load_error.rb +28 -0
- data/lib/ruby-lint/definitions/core/local_jump_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/main.rb +25 -0
- data/lib/ruby-lint/definitions/core/marshal.rb +466 -0
- data/lib/ruby-lint/definitions/core/match_data.rb +73 -0
- data/lib/ruby-lint/definitions/core/math.rb +205 -0
- data/lib/ruby-lint/definitions/core/memory_segmention_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/method.rb +61 -0
- data/lib/ruby-lint/definitions/core/module.rb +262 -0
- data/lib/ruby-lint/definitions/core/monitor.rb +39 -0
- data/lib/ruby-lint/definitions/core/monitor_mixin.rb +59 -0
- data/lib/ruby-lint/definitions/core/mutex.rb +32 -0
- data/lib/ruby-lint/definitions/core/name_error.rb +16 -0
- data/lib/ruby-lint/definitions/core/nil.rb +7 -0
- data/lib/ruby-lint/definitions/core/nil_class.rb +46 -0
- data/lib/ruby-lint/definitions/core/no_memory_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/no_method_error.rb +18 -0
- data/lib/ruby-lint/definitions/core/not_implemented_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/numeric.rb +123 -0
- data/lib/ruby-lint/definitions/core/object.rb +31 -0
- data/lib/ruby-lint/definitions/core/object_space.rb +41 -0
- data/lib/ruby-lint/definitions/core/open_struct.rb +49 -0
- data/lib/ruby-lint/definitions/core/option_parser.rb +1355 -0
- data/lib/ruby-lint/definitions/core/precision.rb +21 -0
- data/lib/ruby-lint/definitions/core/primitive_failure.rb +8 -0
- data/lib/ruby-lint/definitions/core/proc.rb +109 -0
- data/lib/ruby-lint/definitions/core/process.rb +602 -0
- data/lib/ruby-lint/definitions/core/psych.rb +2231 -0
- data/lib/ruby-lint/definitions/core/queue.rb +44 -0
- data/lib/ruby-lint/definitions/core/rake.rb +4784 -0
- data/lib/ruby-lint/definitions/core/rake_file_utils.rb +203 -0
- data/lib/ruby-lint/definitions/core/rakeversion.rb +7 -0
- data/lib/ruby-lint/definitions/core/random.rb +38 -0
- data/lib/ruby-lint/definitions/core/range.rb +104 -0
- data/lib/ruby-lint/definitions/core/range_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/rational.rb +96 -0
- data/lib/ruby-lint/definitions/core/rb_config.rb +36 -0
- data/lib/ruby-lint/definitions/core/regexp.rb +396 -0
- data/lib/ruby-lint/definitions/core/regexp_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/rubinius.rb +16637 -0
- data/lib/ruby-lint/definitions/core/ruby_copyright.rb +7 -0
- data/lib/ruby-lint/definitions/core/ruby_description.rb +7 -0
- data/lib/ruby-lint/definitions/core/ruby_engine.rb +7 -0
- data/lib/ruby-lint/definitions/core/ruby_lint.rb +93 -0
- data/lib/ruby-lint/definitions/core/ruby_patchlevel.rb +7 -0
- data/lib/ruby-lint/definitions/core/ruby_platform.rb +7 -0
- data/lib/ruby-lint/definitions/core/ruby_release_date.rb +7 -0
- data/lib/ruby-lint/definitions/core/ruby_version.rb +7 -0
- data/lib/ruby-lint/definitions/core/runtime_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/scan_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/script_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/security_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/shellwords.rb +37 -0
- data/lib/ruby-lint/definitions/core/signal.rb +37 -0
- data/lib/ruby-lint/definitions/core/signal_exception.rb +19 -0
- data/lib/ruby-lint/definitions/core/singleton.rb +37 -0
- data/lib/ruby-lint/definitions/core/sized_queue.rb +42 -0
- data/lib/ruby-lint/definitions/core/standard_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/stderr.rb +7 -0
- data/lib/ruby-lint/definitions/core/stdin.rb +7 -0
- data/lib/ruby-lint/definitions/core/stdout.rb +7 -0
- data/lib/ruby-lint/definitions/core/stop_iteration.rb +8 -0
- data/lib/ruby-lint/definitions/core/string.rb +713 -0
- data/lib/ruby-lint/definitions/core/string_io.rb +287 -0
- data/lib/ruby-lint/definitions/core/string_scanner.rb +158 -0
- data/lib/ruby-lint/definitions/core/struct.rb +357 -0
- data/lib/ruby-lint/definitions/core/syck.rb +30 -0
- data/lib/ruby-lint/definitions/core/symbol.rb +90 -0
- data/lib/ruby-lint/definitions/core/syntax_error.rb +44 -0
- data/lib/ruby-lint/definitions/core/system_call_error.rb +31 -0
- data/lib/ruby-lint/definitions/core/system_exit.rb +19 -0
- data/lib/ruby-lint/definitions/core/system_stack_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/thread.rb +209 -0
- data/lib/ruby-lint/definitions/core/thread_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/thread_group.rb +22 -0
- data/lib/ruby-lint/definitions/core/time.rb +233 -0
- data/lib/ruby-lint/definitions/core/toplevel_binding.rb +7 -0
- data/lib/ruby-lint/definitions/core/true.rb +7 -0
- data/lib/ruby-lint/definitions/core/true_class.rb +30 -0
- data/lib/ruby-lint/definitions/core/type_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/unbound_method.rb +51 -0
- data/lib/ruby-lint/definitions/core/unmarshalable.rb +13 -0
- data/lib/ruby-lint/definitions/core/unsupported_library_error.rb +8 -0
- data/lib/ruby-lint/definitions/core/weak_ref.rb +42 -0
- data/lib/ruby-lint/definitions/core/zero_division_error.rb +8 -0
- data/lib/ruby-lint/definitions_builder.rb +692 -0
- data/lib/ruby-lint/extensions/string.rb +15 -0
- data/lib/ruby-lint/helper/constant_paths.rb +41 -0
- data/lib/ruby-lint/helper/conversion.rb +33 -0
- data/lib/ruby-lint/helper/current_scope.rb +98 -0
- data/lib/ruby-lint/helper/methods.rb +91 -0
- data/lib/ruby-lint/inspector.rb +191 -0
- data/lib/ruby-lint/iterator.rb +187 -127
- data/lib/ruby-lint/node.rb +107 -0
- data/lib/ruby-lint/parser.rb +510 -1137
- data/lib/ruby-lint/parser_error.rb +15 -27
- data/lib/ruby-lint/presenter/json.rb +19 -0
- data/lib/ruby-lint/presenter/text.rb +37 -0
- data/lib/ruby-lint/report.rb +95 -53
- data/lib/ruby-lint/report/entry.rb +71 -0
- data/lib/ruby-lint/template/definition.erb +24 -0
- data/lib/ruby-lint/template/scope.rb +25 -0
- data/lib/ruby-lint/variable_predicates.rb +109 -0
- data/lib/ruby-lint/version.rb +1 -1
- data/ruby-lint.gemspec +19 -8
- data/spec/helper.rb +10 -2
- data/spec/ruby-lint/analyze/argument_amount.rb +91 -0
- data/spec/ruby-lint/analyze/shadowing_variables.rb +69 -14
- data/spec/ruby-lint/analyze/undefined_methods.rb +174 -0
- data/spec/ruby-lint/analyze/undefined_variables.rb +70 -179
- data/spec/ruby-lint/analyze/unused_variables.rb +63 -183
- data/spec/ruby-lint/configuration.rb +15 -0
- data/spec/ruby-lint/constant_loader.rb +32 -0
- data/spec/ruby-lint/definition/dsl.rb +142 -0
- data/spec/ruby-lint/definition/method_calls.rb +26 -0
- data/spec/ruby-lint/definition/ruby_method.rb +175 -0
- data/spec/ruby-lint/definition/ruby_object.rb +228 -0
- data/spec/ruby-lint/definitions_builder/assignments/arrays.rb +71 -0
- data/spec/ruby-lint/definitions_builder/assignments/hashes.rb +65 -0
- data/spec/ruby-lint/definitions_builder/assignments/objects.rb +23 -0
- data/spec/ruby-lint/definitions_builder/assignments/optional.rb +22 -0
- data/spec/ruby-lint/definitions_builder/assignments/return_values.rb +78 -0
- data/spec/ruby-lint/definitions_builder/assignments/variables.rb +71 -0
- data/spec/ruby-lint/definitions_builder/associate_nodes.rb +17 -0
- data/spec/ruby-lint/definitions_builder/blocks.rb +40 -0
- data/spec/ruby-lint/definitions_builder/classes.rb +230 -0
- data/spec/ruby-lint/definitions_builder/for.rb +16 -0
- data/spec/ruby-lint/definitions_builder/methods.rb +147 -0
- data/spec/ruby-lint/definitions_builder/modules.rb +175 -0
- data/spec/ruby-lint/definitions_builder/reference_amount.rb +31 -0
- data/spec/ruby-lint/definitions_builder/unused.rb +15 -0
- data/spec/ruby-lint/extensions/string.rb +7 -0
- data/spec/ruby-lint/iterator.rb +42 -417
- data/spec/ruby-lint/node.rb +38 -0
- data/spec/ruby-lint/parser/assignments.rb +225 -0
- data/spec/ruby-lint/parser/classes.rb +80 -122
- data/spec/ruby-lint/parser/errors.rb +7 -14
- data/spec/ruby-lint/parser/metadata.rb +17 -0
- data/spec/ruby-lint/parser/method_definitions.rb +111 -0
- data/spec/ruby-lint/parser/methods.rb +184 -216
- data/spec/ruby-lint/parser/modules.rb +54 -33
- data/spec/ruby-lint/parser/operators.rb +30 -65
- data/spec/ruby-lint/parser/statements/begin.rb +55 -0
- data/spec/ruby-lint/parser/statements/case.rb +34 -0
- data/spec/ruby-lint/parser/statements/defined.rb +11 -0
- data/spec/ruby-lint/parser/statements/for.rb +34 -0
- data/spec/ruby-lint/parser/statements/if.rb +46 -0
- data/spec/ruby-lint/parser/statements/return.rb +14 -0
- data/spec/ruby-lint/parser/statements/super.rb +49 -0
- data/spec/ruby-lint/parser/statements/unless.rb +42 -0
- data/spec/ruby-lint/parser/statements/until.rb +25 -0
- data/spec/ruby-lint/parser/statements/while.rb +25 -0
- data/spec/ruby-lint/parser/statements/yield.rb +18 -0
- data/spec/ruby-lint/parser/types/arrays.rb +47 -0
- data/spec/ruby-lint/parser/types/booleans.rb +11 -0
- data/spec/ruby-lint/parser/types/constants.rb +32 -0
- data/spec/ruby-lint/parser/types/hashes.rb +55 -0
- data/spec/ruby-lint/parser/types/nil.rb +7 -0
- data/spec/ruby-lint/parser/types/numbers.rb +11 -0
- data/spec/ruby-lint/parser/types/procs.rb +11 -0
- data/spec/ruby-lint/parser/types/ranges.rb +11 -0
- data/spec/ruby-lint/parser/types/regexp.rb +27 -0
- data/spec/ruby-lint/parser/types/strings.rb +44 -0
- data/spec/ruby-lint/parser/types/symbols.rb +15 -0
- data/spec/ruby-lint/presenter/json.rb +31 -0
- data/spec/ruby-lint/presenter/text.rb +22 -0
- data/spec/ruby-lint/report.rb +45 -15
- data/spec/ruby-lint/report/entry.rb +24 -0
- data/spec/support/bacon.rb +33 -0
- data/spec/support/building.rb +43 -0
- data/spec/support/definitions.rb +23 -0
- data/spec/support/parsing.rb +23 -0
- data/spec/support/simplecov.rb +16 -0
- data/task/build.rake +9 -0
- data/task/checksum.rake +13 -0
- data/task/coverage.rake +6 -0
- data/task/doc.rake +5 -0
- data/task/generate.rake +34 -0
- data/task/graphviz.rake +12 -0
- data/task/stdlib.rake +2 -9
- data/task/tag.rake +6 -0
- metadata +337 -68
- metadata.gz.asc +17 -0
- data/.rbenv-version +0 -1
- data/lib/ruby-lint/analyze/coding_style.rb +0 -407
- data/lib/ruby-lint/analyze/definitions.rb +0 -244
- data/lib/ruby-lint/analyze/method_validation.rb +0 -104
- data/lib/ruby-lint/callback.rb +0 -67
- data/lib/ruby-lint/constant_importer.rb +0 -112
- data/lib/ruby-lint/definition.rb +0 -230
- data/lib/ruby-lint/formatter/text.rb +0 -54
- data/lib/ruby-lint/helper/definition_resolver.rb +0 -143
- data/lib/ruby-lint/helper/scoping.rb +0 -138
- data/lib/ruby-lint/options.rb +0 -58
- data/lib/ruby-lint/token/assignment_token.rb +0 -35
- data/lib/ruby-lint/token/begin_rescue_token.rb +0 -57
- data/lib/ruby-lint/token/block_token.rb +0 -26
- data/lib/ruby-lint/token/case_token.rb +0 -44
- data/lib/ruby-lint/token/class_token.rb +0 -24
- data/lib/ruby-lint/token/keyword_token.rb +0 -43
- data/lib/ruby-lint/token/method_definition_token.rb +0 -64
- data/lib/ruby-lint/token/method_token.rb +0 -56
- data/lib/ruby-lint/token/parameters_token.rb +0 -99
- data/lib/ruby-lint/token/regexp_token.rb +0 -15
- data/lib/ruby-lint/token/statement_token.rb +0 -69
- data/lib/ruby-lint/token/token.rb +0 -176
- data/lib/ruby-lint/token/variable_token.rb +0 -18
- data/spec/benchmarks/memory.rb +0 -52
- data/spec/benchmarks/parse_parser.rb +0 -16
- data/spec/fixtures/stdlib/un.rb +0 -348
- data/spec/ruby-lint/analyze/coding_style.rb +0 -224
- data/spec/ruby-lint/analyze/complex/un.rb +0 -29
- data/spec/ruby-lint/analyze/definitions/classes.rb +0 -114
- data/spec/ruby-lint/analyze/definitions/methods.rb +0 -91
- data/spec/ruby-lint/analyze/definitions/modules.rb +0 -207
- data/spec/ruby-lint/analyze/definitions/variables.rb +0 -103
- data/spec/ruby-lint/analyze/method_validation.rb +0 -177
- data/spec/ruby-lint/callback.rb +0 -28
- data/spec/ruby-lint/constant_importer.rb +0 -27
- data/spec/ruby-lint/definition.rb +0 -96
- data/spec/ruby-lint/formatter/text.rb +0 -21
- data/spec/ruby-lint/parser/arrays.rb +0 -147
- data/spec/ruby-lint/parser/expander_assignments.rb +0 -183
- data/spec/ruby-lint/parser/hashes.rb +0 -136
- data/spec/ruby-lint/parser/keywords.rb +0 -89
- data/spec/ruby-lint/parser/objects.rb +0 -39
- data/spec/ruby-lint/parser/procs.rb +0 -113
- data/spec/ruby-lint/parser/ranges.rb +0 -49
- data/spec/ruby-lint/parser/regexp.rb +0 -31
- data/spec/ruby-lint/parser/scalars.rb +0 -93
- data/spec/ruby-lint/parser/statements.rb +0 -591
- data/spec/ruby-lint/parser/variables.rb +0 -230
|
@@ -1,36 +1,31 @@
|
|
|
1
1
|
module RubyLint
|
|
2
2
|
module Analyze
|
|
3
3
|
##
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# The ShadowingVariables class checks for the use of variables in a block
|
|
5
|
+
# that shadow outer variables. "Shadowing" means that a variable is used
|
|
6
|
+
# with the same name as a variable in the surrounding scope. A simple
|
|
7
|
+
# example:
|
|
6
8
|
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
DESCRIPTION = 'Checks for variables that shadow other variables.'
|
|
9
|
+
# number = 10
|
|
10
|
+
#
|
|
11
|
+
# [10, 20, 30].each do |number|
|
|
12
|
+
# puts number # `number` is being shadowed
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
class ShadowingVariables < Iterator
|
|
16
|
+
include Helper::CurrentScope
|
|
16
17
|
|
|
17
18
|
##
|
|
18
|
-
#
|
|
19
|
-
# parameters of the block shadow existing local variables defined in the
|
|
20
|
-
# outer scope.
|
|
19
|
+
# @param [RubyLint::Node] node
|
|
21
20
|
#
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if scope.lookup(param.type, param.name)
|
|
27
|
-
warning(
|
|
28
|
-
"shadowing outer local variable #{param.name}",
|
|
29
|
-
param.line,
|
|
30
|
-
param.column
|
|
31
|
-
)
|
|
21
|
+
def on_block(node)
|
|
22
|
+
node.each_argument do |param|
|
|
23
|
+
if current_scope.has_definition?(param.type, param.name)
|
|
24
|
+
warning("shadowing outer local variable #{param.name}", param)
|
|
32
25
|
end
|
|
33
26
|
end
|
|
27
|
+
|
|
28
|
+
super
|
|
34
29
|
end
|
|
35
30
|
end # ShadowingVariables
|
|
36
31
|
end # Analyze
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module RubyLint
|
|
2
|
+
module Analyze
|
|
3
|
+
##
|
|
4
|
+
# The UndefinedMethods class checks for the use of undefined methods/local
|
|
5
|
+
# variables and adds errors whenever needed. Based on the receiver of a
|
|
6
|
+
# method call the corresponding error message differs to make it easier to
|
|
7
|
+
# understand what is going on.
|
|
8
|
+
#
|
|
9
|
+
# A simple example:
|
|
10
|
+
#
|
|
11
|
+
# foobar # => undefined method foobar
|
|
12
|
+
# 'test'.foobar # => undefined method foobar on an instance of String
|
|
13
|
+
#
|
|
14
|
+
class UndefinedMethods < Iterator
|
|
15
|
+
include Helper::Methods
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
# @param [RubyLint::Node] node
|
|
19
|
+
#
|
|
20
|
+
def on_method(node)
|
|
21
|
+
# Don't add errors for non existing receivers as these are handled by
|
|
22
|
+
# classes such as UndefinedVariables.
|
|
23
|
+
return if invalid_receiver?(node)
|
|
24
|
+
|
|
25
|
+
valid = method_defined?(node)
|
|
26
|
+
error = "undefined method #{node.name}"
|
|
27
|
+
|
|
28
|
+
# Methods called on block variables should be ignored since these
|
|
29
|
+
# variables don't carry any class information with them.
|
|
30
|
+
if !valid and node.receiver
|
|
31
|
+
receiver = method_receiver(node.receiver)
|
|
32
|
+
valid = receiver && receiver.ignore
|
|
33
|
+
|
|
34
|
+
if receiver.variable? and receiver.value
|
|
35
|
+
receiver = receiver.value
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if receiver
|
|
39
|
+
error = receiver_error(node.name, receiver)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
error(error, node) unless valid
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# Creates an error message for a method call on a receiver.
|
|
50
|
+
#
|
|
51
|
+
# @param [String] name
|
|
52
|
+
# @param [RubyLint::Definition::RubyObject] receiver
|
|
53
|
+
# @return [String]
|
|
54
|
+
#
|
|
55
|
+
def receiver_error(name, receiver)
|
|
56
|
+
error = "undefined method #{name} on #{receiver.name}"
|
|
57
|
+
receiver_name = receiver.ruby_class || receiver.name
|
|
58
|
+
|
|
59
|
+
if receiver.instance?
|
|
60
|
+
error = "undefined method #{name} on an instance " \
|
|
61
|
+
"of #{receiver_name}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return error
|
|
65
|
+
end
|
|
66
|
+
end # UndefinedMethods
|
|
67
|
+
end # Analyze
|
|
68
|
+
end # RubyLint
|
|
@@ -1,98 +1,71 @@
|
|
|
1
1
|
module RubyLint
|
|
2
2
|
module Analyze
|
|
3
3
|
##
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# The UndefinedVariables class checks for the use of undefined variables
|
|
5
|
+
# (such as instance variables and constants). The order of definition and
|
|
6
|
+
# use of a variable does not matter.
|
|
6
7
|
#
|
|
7
|
-
class
|
|
8
|
-
|
|
8
|
+
# This analysis class does *not* check for undefined local variables. Ruby
|
|
9
|
+
# treats these as method calls and as result they are handled by
|
|
10
|
+
# {RubyLint::Analyze::UndefinedMethods} instead.
|
|
11
|
+
#
|
|
12
|
+
class UndefinedVariables < Iterator
|
|
13
|
+
include Helper::CurrentScope
|
|
9
14
|
|
|
10
15
|
##
|
|
11
|
-
#
|
|
16
|
+
# Hash containing the various variable types to add errors for whenever
|
|
17
|
+
# they are used but not defined.
|
|
12
18
|
#
|
|
13
|
-
# @return [
|
|
19
|
+
# @return [Hash]
|
|
14
20
|
#
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
|
|
21
|
-
'constant'
|
|
22
|
-
].each do |name|
|
|
23
|
-
readable = name.gsub('_', ' ')
|
|
21
|
+
VARIABLE_TYPES = {
|
|
22
|
+
:global_variable => 'global variable',
|
|
23
|
+
:instance_variable => 'instance variable',
|
|
24
|
+
:class_variable => 'class variable',
|
|
25
|
+
:constant => 'constant'
|
|
26
|
+
}
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
token.column
|
|
31
|
-
)
|
|
28
|
+
VARIABLE_TYPES.each do |type, label|
|
|
29
|
+
define_method("on_#{type}") do |node|
|
|
30
|
+
if !current_scope.has_definition?(type, node.name) \
|
|
31
|
+
and !@in_constant_path
|
|
32
|
+
error("undefined #{label} #{node.name}", node)
|
|
32
33
|
end
|
|
33
34
|
end
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
##
|
|
37
|
-
#
|
|
38
|
-
# paths before assigning data to them.
|
|
38
|
+
# Validates each segment of a constant path in the correct scope.
|
|
39
39
|
#
|
|
40
|
-
# @param [RubyLint::
|
|
40
|
+
# @param [RubyLint::Node] node
|
|
41
41
|
#
|
|
42
|
-
def
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
def on_constant_path(node)
|
|
43
|
+
definitions = current_scope
|
|
44
|
+
@in_constant_path = true
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# @param [RubyLint::Token::VariableToken] token
|
|
50
|
-
#
|
|
51
|
-
def on_constant_path(token)
|
|
52
|
-
current = scope
|
|
53
|
-
segments = []
|
|
46
|
+
# The first constant check should take data from parent scopes into
|
|
47
|
+
# account. The following segments should not.
|
|
48
|
+
method = :has_definition?
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
found = current.lookup(:constant, segment)
|
|
50
|
+
node.children.each do |segment|
|
|
51
|
+
name = segment.name
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
else
|
|
62
|
-
error(
|
|
63
|
-
"undefined constant #{segments.join('::')}",
|
|
64
|
-
token.line,
|
|
65
|
-
token.column
|
|
66
|
-
)
|
|
53
|
+
unless definitions.send(method, :constant, name)
|
|
54
|
+
error("undefined constant #{name}", segment)
|
|
67
55
|
|
|
68
|
-
|
|
56
|
+
break
|
|
69
57
|
end
|
|
58
|
+
|
|
59
|
+
definitions = definitions.lookup(:constant, name)
|
|
60
|
+
method = :defines?
|
|
70
61
|
end
|
|
71
62
|
end
|
|
72
63
|
|
|
73
64
|
##
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
# @param [RubyLint::Token::MethodToken] token
|
|
65
|
+
# @param [RubyLint::Node] node
|
|
77
66
|
#
|
|
78
|
-
def
|
|
79
|
-
|
|
80
|
-
kernel = scope.lookup(:constant, 'Kernel')
|
|
81
|
-
|
|
82
|
-
if kernel.lookup(:method, token.name) \
|
|
83
|
-
or kernel.lookup(:instance_method, token.name)
|
|
84
|
-
kernel_method = true
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
if !token.receiver \
|
|
88
|
-
and !kernel_method \
|
|
89
|
-
and !definition_exists?(:instance_method, token)
|
|
90
|
-
error(
|
|
91
|
-
"undefined local variable or method #{token.name}",
|
|
92
|
-
token.line,
|
|
93
|
-
token.column
|
|
94
|
-
)
|
|
95
|
-
end
|
|
67
|
+
def after_constant_path(node)
|
|
68
|
+
@in_constant_path = false
|
|
96
69
|
end
|
|
97
70
|
end # UndefinedVariables
|
|
98
71
|
end # Analyze
|
|
@@ -1,102 +1,47 @@
|
|
|
1
1
|
module RubyLint
|
|
2
2
|
module Analyze
|
|
3
3
|
##
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# The UnusedVariables class checks for variables that are defined but never
|
|
5
|
+
# used. Whenever it finds one of these variables it will add a
|
|
6
|
+
# corresponding warning message.
|
|
6
7
|
#
|
|
7
|
-
class UnusedVariables <
|
|
8
|
-
include Helper::
|
|
8
|
+
class UnusedVariables < Iterator
|
|
9
|
+
include Helper::CurrentScope
|
|
10
|
+
include Helper::ConstantPaths
|
|
9
11
|
|
|
10
12
|
##
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# @return [String]
|
|
14
|
-
#
|
|
15
|
-
DESCRIPTION = 'Checks for variables that are assigned but unused.'
|
|
16
|
-
|
|
17
|
-
##
|
|
18
|
-
# Hash containing the human readable names for various variable types.
|
|
13
|
+
# Hash containing the various variable types for which to add warnings
|
|
14
|
+
# and human readable names for these types.
|
|
19
15
|
#
|
|
20
16
|
# @return [Hash]
|
|
21
17
|
#
|
|
22
|
-
|
|
18
|
+
VARIABLE_TYPES = {
|
|
23
19
|
:local_variable => 'local variable',
|
|
20
|
+
:global_variable => 'global variable',
|
|
24
21
|
:instance_variable => 'instance variable',
|
|
25
22
|
:class_variable => 'class variable',
|
|
26
|
-
:
|
|
23
|
+
:constant => 'constant'
|
|
27
24
|
}
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# @return [Array]
|
|
33
|
-
#
|
|
34
|
-
UNUSED_VARIABLES = [
|
|
35
|
-
:on_local_variable,
|
|
36
|
-
:on_instance_variable,
|
|
37
|
-
:on_class_variable,
|
|
38
|
-
:on_global_variable
|
|
39
|
-
]
|
|
26
|
+
VARIABLE_TYPES.each do |type, label|
|
|
27
|
+
define_method("on_#{type}") do |node|
|
|
28
|
+
variable = current_scope.lookup(node.type, node.name)
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
if variable and !variable.used?
|
|
31
|
+
warning("unused #{label} #{node.name}", node)
|
|
32
|
+
end
|
|
44
33
|
end
|
|
45
34
|
end
|
|
46
35
|
|
|
47
36
|
##
|
|
48
|
-
# @
|
|
49
|
-
#
|
|
50
|
-
def initialize(*args)
|
|
51
|
-
super
|
|
52
|
-
|
|
53
|
-
@unused_variables = [{}]
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
##
|
|
57
|
-
# Called when a new scope is found.
|
|
58
|
-
#
|
|
59
|
-
def on_new_scope
|
|
60
|
-
@unused_variables << {}
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
##
|
|
64
|
-
# Called after a new scope has ended.
|
|
37
|
+
# @param [RubyLint::Node] node
|
|
65
38
|
#
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
warning(
|
|
72
|
-
"assigned but unused #{readable} #{token.name}",
|
|
73
|
-
token.line,
|
|
74
|
-
token.column
|
|
75
|
-
)
|
|
39
|
+
def on_constant_path(node)
|
|
40
|
+
iterate_constant_path(node) do |name, segment, definition|
|
|
41
|
+
if definition and !definition.used?
|
|
42
|
+
warning("unused constant #{name}", segment)
|
|
43
|
+
end
|
|
76
44
|
end
|
|
77
|
-
|
|
78
|
-
@unused_variables.pop
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
##
|
|
82
|
-
# Called when a variable is assigned.
|
|
83
|
-
#
|
|
84
|
-
# @param [RubyLint::Token::AssignmentToken] token
|
|
85
|
-
#
|
|
86
|
-
def on_assignment(token)
|
|
87
|
-
unused_variables[token.name] = token
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
private
|
|
91
|
-
|
|
92
|
-
##
|
|
93
|
-
# Returns the Hash to use for storing unused variables for the current
|
|
94
|
-
# scope.
|
|
95
|
-
#
|
|
96
|
-
# @return [Hash]
|
|
97
|
-
#
|
|
98
|
-
def unused_variables
|
|
99
|
-
return @unused_variables[-1]
|
|
100
45
|
end
|
|
101
46
|
end # UnusedVariables
|
|
102
47
|
end # Analyze
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module RubyLint
|
|
2
|
+
##
|
|
3
|
+
# @return [RubyLint::GlobalScope]
|
|
4
|
+
#
|
|
5
|
+
def self.global_scope
|
|
6
|
+
return @global_scope ||= Definition::RubyObject.new(
|
|
7
|
+
:name => 'global',
|
|
8
|
+
:type => :global
|
|
9
|
+
)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Looks up the given constant in the global scope. If it does not exist this
|
|
14
|
+
# method will try to load it from one of the existing definitions.
|
|
15
|
+
#
|
|
16
|
+
# @param [String] name
|
|
17
|
+
# @return [RubyLint::Definition::RubyObject]
|
|
18
|
+
#
|
|
19
|
+
def self.global_constant(name)
|
|
20
|
+
found = global_scope.lookup(:constant, name)
|
|
21
|
+
|
|
22
|
+
if !found and !constant_loader.loaded?(name)
|
|
23
|
+
constant_loader.load(name)
|
|
24
|
+
|
|
25
|
+
found = global_scope.lookup(:constant, name)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
return found
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Provides a simple DSL for configuring ruby-lint.
|
|
33
|
+
#
|
|
34
|
+
# @yieldparam [RubyLint::Configuration]
|
|
35
|
+
#
|
|
36
|
+
def self.configure
|
|
37
|
+
yield configuration
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# @return [RubyLint::Configuration]
|
|
42
|
+
#
|
|
43
|
+
def self.configuration
|
|
44
|
+
return @configuration ||= Configuration.new
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# @param [RubyLint::Configuration] config
|
|
49
|
+
#
|
|
50
|
+
def self.configuration=(config)
|
|
51
|
+
@configuration = config
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# @return [RubyLint::ConstantLoader]
|
|
56
|
+
#
|
|
57
|
+
def self.constant_loader
|
|
58
|
+
return @constant_loader ||= ConstantLoader.new
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# Returns an Array of locations from which to load configuration files.
|
|
63
|
+
#
|
|
64
|
+
# @return [Array]
|
|
65
|
+
#
|
|
66
|
+
def self.configuration_files
|
|
67
|
+
return [
|
|
68
|
+
File.join(Dir.pwd, 'ruby-lint.rb'),
|
|
69
|
+
File.expand_path('~/.ruby-lint.rb', __FILE__)
|
|
70
|
+
]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
##
|
|
74
|
+
# Tries to load a configuration file from one of the locations in
|
|
75
|
+
# {RubyLint.configuration_files}.
|
|
76
|
+
#
|
|
77
|
+
def self.load_configuration
|
|
78
|
+
configuration_files.each do |path|
|
|
79
|
+
if File.file?(path)
|
|
80
|
+
require(path)
|
|
81
|
+
break
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end # RubyLint
|