ruby-lint 0.0.4 → 0.0.5
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.asc +17 -0
- data.tar.gz.asc +14 -14
- data/.ruby-version +1 -0
- data/.travis.yml +0 -1
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +41 -0
- data/MANIFEST +99 -66
- data/README.md +36 -10
- data/Rakefile +6 -0
- data/checksum/ruby-lint-0.0.4.gem.sha512 +1 -0
- data/doc/changelog.md +94 -0
- data/lib/ruby-lint.rb +18 -1
- data/lib/ruby-lint/analysis/argument_amount.rb +43 -10
- data/lib/ruby-lint/analysis/base.rb +23 -17
- data/lib/ruby-lint/analysis/pedantics.rb +3 -1
- data/lib/ruby-lint/analysis/undefined_methods.rb +48 -10
- data/lib/ruby-lint/analysis/unused_variables.rb +27 -5
- data/lib/ruby-lint/ast/node.rb +10 -0
- data/lib/ruby-lint/cli/analyze.rb +22 -4
- data/lib/ruby-lint/cli/base.rb +8 -2
- data/lib/ruby-lint/configuration.rb +43 -4
- data/lib/ruby-lint/definition/constant_proxy.rb +10 -1
- data/lib/ruby-lint/definition/ruby_method.rb +45 -31
- data/lib/ruby-lint/definition/ruby_object.rb +56 -15
- data/lib/ruby-lint/definition_builder/base.rb +4 -0
- data/lib/ruby-lint/definition_builder/primitive.rb +1 -1
- data/lib/ruby-lint/definition_builder/ruby_array.rb +1 -1
- data/lib/ruby-lint/definition_builder/ruby_block.rb +1 -0
- data/lib/ruby-lint/definition_builder/ruby_class.rb +1 -1
- data/lib/ruby-lint/definition_builder/ruby_hash.rb +1 -1
- data/lib/ruby-lint/definition_builder/ruby_module.rb +3 -1
- data/lib/ruby-lint/definition_generator.rb +15 -7
- data/lib/ruby-lint/definitions/core/arg0.rb +1 -1
- data/lib/ruby-lint/definitions/core/argf.rb +1 -1
- data/lib/ruby-lint/definitions/core/argument_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/argv.rb +1 -1
- data/lib/ruby-lint/definitions/core/array.rb +6 -6
- data/lib/ruby-lint/definitions/core/autoload.rb +2 -2
- data/lib/ruby-lint/definitions/core/basic_object.rb +8 -12
- data/lib/ruby-lint/definitions/core/bignum.rb +2 -2
- data/lib/ruby-lint/definitions/core/binding.rb +2 -2
- data/lib/ruby-lint/definitions/core/class.rb +2 -2
- data/lib/ruby-lint/definitions/core/comparable.rb +1 -1
- data/lib/ruby-lint/definitions/core/complex.rb +4 -4
- data/lib/ruby-lint/definitions/core/condition_variable.rb +2 -2
- data/lib/ruby-lint/definitions/core/continuation.rb +2 -2
- data/lib/ruby-lint/definitions/core/data.rb +2 -2
- data/lib/ruby-lint/definitions/core/date.rb +34 -34
- data/lib/ruby-lint/definitions/core/date_time.rb +26 -26
- data/lib/ruby-lint/definitions/core/default_record_separator.rb +1 -1
- data/lib/ruby-lint/definitions/core/digest.rb +14 -14
- data/lib/ruby-lint/definitions/core/dir.rb +34 -34
- data/lib/ruby-lint/definitions/core/encoding.rb +237 -237
- data/lib/ruby-lint/definitions/core/encoding_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/enumerable.rb +15 -15
- data/lib/ruby-lint/definitions/core/enumerator.rb +2 -2
- data/lib/ruby-lint/definitions/core/env.rb +1 -1
- data/lib/ruby-lint/definitions/core/eoferror.rb +2 -2
- data/lib/ruby-lint/definitions/core/erb.rb +30 -23
- data/lib/ruby-lint/definitions/core/errno.rb +525 -525
- data/lib/ruby-lint/definitions/core/etc.rb +6 -6
- data/lib/ruby-lint/definitions/core/exception.rb +2 -2
- data/lib/ruby-lint/definitions/core/false.rb +1 -1
- data/lib/ruby-lint/definitions/core/false_class.rb +2 -2
- data/lib/ruby-lint/definitions/core/fatal_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/fiber.rb +2 -2
- data/lib/ruby-lint/definitions/core/fiber_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/file.rb +68 -68
- data/lib/ruby-lint/definitions/core/file_list.rb +2 -2
- data/lib/ruby-lint/definitions/core/file_test.rb +1 -1
- data/lib/ruby-lint/definitions/core/file_utils.rb +16 -16
- data/lib/ruby-lint/definitions/core/fixnum.rb +4 -4
- data/lib/ruby-lint/definitions/core/float.rb +16 -16
- data/lib/ruby-lint/definitions/core/float_domain_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/gc.rb +2 -2
- data/lib/ruby-lint/definitions/core/gem.rb +119 -119
- data/lib/ruby-lint/definitions/core/hash.rb +14 -14
- data/lib/ruby-lint/definitions/core/immediate_value.rb +1 -1
- data/lib/ruby-lint/definitions/core/index_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/integer.rb +2 -2
- data/lib/ruby-lint/definitions/core/interrupt.rb +2 -2
- data/lib/ruby-lint/definitions/core/io.rb +38 -38
- data/lib/ruby-lint/definitions/core/ioerror.rb +2 -2
- data/lib/ruby-lint/definitions/core/kernel.rb +113 -60
- data/lib/ruby-lint/definitions/core/key_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/load_error.rb +6 -6
- data/lib/ruby-lint/definitions/core/local_jump_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/marshal.rb +35 -35
- data/lib/ruby-lint/definitions/core/match_data.rb +2 -2
- data/lib/ruby-lint/definitions/core/math.rb +7 -7
- data/lib/ruby-lint/definitions/core/memory_segmention_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/method.rb +2 -2
- data/lib/ruby-lint/definitions/core/module.rb +39 -3
- data/lib/ruby-lint/definitions/core/monitor.rb +4 -4
- data/lib/ruby-lint/definitions/core/monitor_mixin.rb +5 -5
- data/lib/ruby-lint/definitions/core/mutex.rb +2 -2
- data/lib/ruby-lint/definitions/core/name_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/nil.rb +1 -1
- data/lib/ruby-lint/definitions/core/nil_class.rb +2 -2
- data/lib/ruby-lint/definitions/core/no_memory_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/no_method_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/not_implemented_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/numeric.rb +2 -2
- data/lib/ruby-lint/definitions/core/object.rb +2 -2
- data/lib/ruby-lint/definitions/core/object_space.rb +1 -1
- data/lib/ruby-lint/definitions/core/open_struct.rb +3 -3
- data/lib/ruby-lint/definitions/core/option_parser.rb +83 -83
- data/lib/ruby-lint/definitions/core/precision.rb +1 -1
- data/lib/ruby-lint/definitions/core/primitive_failure.rb +2 -2
- data/lib/ruby-lint/definitions/core/proc.rb +2 -2
- data/lib/ruby-lint/definitions/core/process.rb +29 -29
- data/lib/ruby-lint/definitions/core/queue.rb +2 -2
- data/lib/ruby-lint/definitions/core/rake.rb +117 -117
- data/lib/ruby-lint/definitions/core/rake_file_utils.rb +1 -1
- data/lib/ruby-lint/definitions/core/rakeversion.rb +1 -1
- data/lib/ruby-lint/definitions/core/random.rb +2 -2
- data/lib/ruby-lint/definitions/core/range.rb +4 -4
- data/lib/ruby-lint/definitions/core/range_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/rational.rb +2 -2
- data/lib/ruby-lint/definitions/core/rb_config.rb +3 -3
- data/lib/ruby-lint/definitions/core/regexp.rb +28 -28
- data/lib/ruby-lint/definitions/core/regexp_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/ruby_copyright.rb +1 -1
- data/lib/ruby-lint/definitions/core/ruby_description.rb +1 -1
- data/lib/ruby-lint/definitions/core/ruby_engine.rb +1 -1
- data/lib/ruby-lint/definitions/core/ruby_patchlevel.rb +1 -1
- data/lib/ruby-lint/definitions/core/ruby_platform.rb +1 -1
- data/lib/ruby-lint/definitions/core/ruby_release_date.rb +1 -1
- data/lib/ruby-lint/definitions/core/ruby_version.rb +1 -1
- data/lib/ruby-lint/definitions/core/runtime_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/scan_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/script_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/security_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/shellwords.rb +1 -1
- data/lib/ruby-lint/definitions/core/signal.rb +3 -3
- data/lib/ruby-lint/definitions/core/signal_exception.rb +2 -2
- data/lib/ruby-lint/definitions/core/singleton.rb +2 -2
- data/lib/ruby-lint/definitions/core/sized_queue.rb +2 -2
- data/lib/ruby-lint/definitions/core/standard_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/stderr.rb +3 -2
- data/lib/ruby-lint/definitions/core/stdin.rb +3 -2
- data/lib/ruby-lint/definitions/core/stdout.rb +3 -2
- data/lib/ruby-lint/definitions/core/stop_iteration.rb +2 -2
- data/lib/ruby-lint/definitions/core/string.rb +21 -21
- data/lib/ruby-lint/definitions/core/string_io.rb +7 -7
- data/lib/ruby-lint/definitions/core/string_scanner.rb +4 -4
- data/lib/ruby-lint/definitions/core/struct.rb +20 -20
- data/lib/ruby-lint/definitions/core/syck.rb +4 -4
- data/lib/ruby-lint/definitions/core/symbol.rb +2 -2
- data/lib/ruby-lint/definitions/core/syntax_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/system_call_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/system_exit.rb +2 -2
- data/lib/ruby-lint/definitions/core/system_stack_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/thread.rb +6 -6
- data/lib/ruby-lint/definitions/core/thread_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/thread_group.rb +2 -2
- data/lib/ruby-lint/definitions/core/time.rb +3 -3
- data/lib/ruby-lint/definitions/core/toplevel_binding.rb +1 -1
- data/lib/ruby-lint/definitions/core/true.rb +1 -1
- data/lib/ruby-lint/definitions/core/true_class.rb +2 -2
- data/lib/ruby-lint/definitions/core/type_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/unbound_method.rb +2 -2
- data/lib/ruby-lint/definitions/core/unmarshalable.rb +1 -1
- data/lib/ruby-lint/definitions/core/unsupported_library_error.rb +2 -2
- data/lib/ruby-lint/definitions/core/weak_ref.rb +4 -4
- data/lib/ruby-lint/definitions/core/yaml.rb +2361 -0
- data/lib/ruby-lint/definitions/core/zero_division_error.rb +2 -2
- data/lib/ruby-lint/definitions/global_variables.rb +9 -0
- data/lib/ruby-lint/definitions/rails/abstract_controller.rb +174 -28
- data/lib/ruby-lint/definitions/rails/action_controller.rb +4959 -550
- data/lib/ruby-lint/definitions/rails/action_dispatch.rb +2489 -292
- data/lib/ruby-lint/definitions/rails/action_mailer.rb +1285 -42
- data/lib/ruby-lint/definitions/rails/action_pack.rb +14 -6
- data/lib/ruby-lint/definitions/rails/action_view.rb +6941 -445
- data/lib/ruby-lint/definitions/rails/active_model.rb +1212 -69
- data/lib/ruby-lint/definitions/rails/active_record.rb +10344 -1450
- data/lib/ruby-lint/definitions/rails/active_support.rb +4631 -573
- data/lib/ruby-lint/definitions/rails/arel.rb +3211 -319
- data/lib/ruby-lint/definitions/rails/rails.rb +2922 -84
- data/lib/ruby-lint/definitions/rails/sprockets.rb +3048 -277
- data/lib/ruby-lint/docstring/mapping.rb +55 -0
- data/lib/ruby-lint/docstring/param_tag.rb +29 -0
- data/lib/ruby-lint/docstring/parser.rb +133 -0
- data/lib/ruby-lint/docstring/return_tag.rb +24 -0
- data/lib/ruby-lint/file_loader.rb +96 -0
- data/lib/ruby-lint/file_scanner.rb +91 -0
- data/lib/ruby-lint/global_scope.rb +56 -0
- data/lib/ruby-lint/helper/constant_paths.rb +1 -1
- data/lib/ruby-lint/inspector.rb +11 -33
- data/lib/ruby-lint/iterator.rb +31 -4
- data/lib/ruby-lint/method_call/alias.rb +46 -0
- data/lib/ruby-lint/method_call/assign_member.rb +55 -0
- data/lib/ruby-lint/method_call/attribute.rb +102 -0
- data/lib/ruby-lint/method_call/base.rb +37 -0
- data/lib/ruby-lint/method_call/define_method.rb +17 -0
- data/lib/ruby-lint/method_call/include.rb +39 -0
- data/lib/ruby-lint/parser.rb +9 -4
- data/lib/ruby-lint/presenter/text.rb +2 -1
- data/lib/ruby-lint/report.rb +19 -42
- data/lib/ruby-lint/report/entry.rb +20 -17
- data/lib/ruby-lint/runner.rb +92 -11
- data/lib/ruby-lint/template/definition.erb +2 -2
- data/lib/ruby-lint/variable_predicates.rb +7 -10
- data/lib/ruby-lint/version.rb +1 -1
- data/lib/ruby-lint/virtual_machine.rb +265 -188
- data/ruby-lint.gemspec +4 -4
- data/ruby-lint.yml +7 -0
- data/spec/fixtures/associating.rb +7 -0
- data/spec/fixtures/file_scanner/lib/example/recursive/source.rb +6 -0
- data/spec/fixtures/file_scanner/lib/example/recursive/target.rb +8 -0
- data/spec/fixtures/file_scanner/lib/example/user.rb +6 -0
- data/spec/fixtures/file_scanner/lib/test-dashes/foo.rb +4 -0
- data/spec/fixtures/file_scanner/rails/app/models/example/user.rb +6 -0
- data/spec/fixtures/file_scanner/rails/app/models/user.rb +4 -0
- data/spec/fixtures/uses_external.rb +1 -0
- data/spec/fixtures/uses_external_invalid.rb +3 -0
- data/spec/fixtures/uses_external_namespace.rb +1 -0
- data/spec/ruby-lint/analysis/{argument_amount.rb → argument_amount_spec.rb} +33 -7
- data/spec/ruby-lint/analysis/base_spec.rb +12 -0
- data/spec/ruby-lint/analysis/{pedantics.rb → pedantics_spec.rb} +24 -4
- data/spec/ruby-lint/analysis/{shadowing_variables.rb → shadowing_variables_spec.rb} +6 -6
- data/spec/ruby-lint/analysis/undefined_methods_spec.rb +320 -0
- data/spec/ruby-lint/analysis/{undefined_variables.rb → undefined_variables_spec.rb} +33 -10
- data/spec/ruby-lint/analysis/{unused_variables.rb → unused_variables_spec.rb} +36 -9
- data/spec/ruby-lint/ast/{node.rb → node_spec.rb} +12 -6
- data/spec/ruby-lint/cli/{analyze.rb → analyze_spec.rb} +16 -5
- data/spec/ruby-lint/cli/{ast.rb → ast_spec.rb} +3 -3
- data/spec/ruby-lint/configuration_spec.rb +106 -0
- data/spec/ruby-lint/definition/constant_proxy_spec.rb +54 -0
- data/spec/ruby-lint/definition/{dsl.rb → dsl_spec.rb} +15 -15
- data/spec/ruby-lint/definition/{ruby_method.rb → ruby_method_spec.rb} +31 -17
- data/spec/ruby-lint/definition/{ruby_object.rb → ruby_object_spec.rb} +28 -23
- data/spec/ruby-lint/definition_builder/{primitive.rb → primitive_spec.rb} +9 -9
- data/spec/ruby-lint/definition_builder/{ruby_class.rb → ruby_class_spec.rb} +13 -13
- data/spec/ruby-lint/definition_builder/{ruby_method.rb → ruby_method_spec.rb} +9 -9
- data/spec/ruby-lint/definition_builder/{ruby_module.rb → ruby_module_spec.rb} +12 -10
- data/spec/ruby-lint/docstring/mapping.rb +27 -0
- data/spec/ruby-lint/docstring/parser_spec.rb +88 -0
- data/spec/ruby-lint/extensions/{string.rb → string_spec.rb} +3 -3
- data/spec/ruby-lint/file_loader_spec.rb +69 -0
- data/spec/ruby-lint/file_scanner_spec.rb +51 -0
- data/spec/ruby-lint/inspector_spec.rb +44 -0
- data/spec/ruby-lint/{iterator.rb → iterator_spec.rb} +39 -4
- data/spec/ruby-lint/{nested_stack.rb → nested_stack_spec.rb} +4 -4
- data/spec/ruby-lint/parser_spec.rb +31 -0
- data/spec/ruby-lint/presenter/json_spec.rb +58 -0
- data/spec/ruby-lint/presenter/text_spec.rb +49 -0
- data/spec/ruby-lint/report/entry_spec.rb +58 -0
- data/spec/ruby-lint/report_spec.rb +39 -0
- data/spec/ruby-lint/runner_spec.rb +52 -0
- data/spec/ruby-lint/virtual_machine/alias_spec.rb +55 -0
- data/spec/ruby-lint/virtual_machine/assignments/{arrays.rb → arrays_spec.rb} +7 -7
- data/spec/ruby-lint/virtual_machine/assignments/{hashes.rb → hashes_spec.rb} +6 -6
- data/spec/ruby-lint/virtual_machine/assignments/{optional.rb → optional_spec.rb} +6 -6
- data/spec/ruby-lint/virtual_machine/assignments/{return_values.rb → return_values_spec.rb} +11 -11
- data/spec/ruby-lint/virtual_machine/assignments/{variables.rb → variables_spec.rb} +38 -7
- data/spec/ruby-lint/virtual_machine/associate_nodes_spec.rb +59 -0
- data/spec/ruby-lint/virtual_machine/{autoloading.rb → autoloading_spec.rb} +6 -6
- data/spec/ruby-lint/virtual_machine/{blocks.rb → blocks_spec.rb} +30 -4
- data/spec/ruby-lint/virtual_machine/classes/{class_methods.rb → class_methods_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/classes/{extending.rb → extending_spec.rb} +20 -15
- data/spec/ruby-lint/virtual_machine/classes/{redefining.rb → redefining_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/classes/{sclass.rb → sclass_spec.rb} +7 -7
- data/spec/ruby-lint/virtual_machine/classes/{scoping.rb → scoping_spec.rb} +5 -5
- data/spec/ruby-lint/virtual_machine/complex/{rails.rb → rails_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/complex/{rcap.rb → rcap_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/complex/{slop.rb → slop_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/constants_spec.rb +31 -0
- data/spec/ruby-lint/virtual_machine/{for.rb → for_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/{freeze.rb → freeze_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/global_variables_spec.rb +12 -0
- data/spec/ruby-lint/virtual_machine/inherit_kernel_spec.rb +15 -0
- data/spec/ruby-lint/virtual_machine/{interpolation.rb → interpolation_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/methods/attr_spec.rb +116 -0
- data/spec/ruby-lint/virtual_machine/methods/define_method_spec.rb +41 -0
- data/spec/ruby-lint/virtual_machine/methods/{defining.rb → defining_spec.rb} +4 -4
- data/spec/ruby-lint/virtual_machine/methods/docstrings_spec.rb +69 -0
- data/spec/ruby-lint/virtual_machine/methods/{exporting.rb → exporting_spec.rb} +3 -3
- data/spec/ruby-lint/virtual_machine/methods/{parameters.rb → parameters_spec.rb} +17 -5
- data/spec/ruby-lint/virtual_machine/methods/{patching.rb → patching_spec.rb} +4 -4
- data/spec/ruby-lint/virtual_machine/methods/{scoping.rb → scoping_spec.rb} +5 -5
- data/spec/ruby-lint/virtual_machine/methods/{visibility.rb → visibility_spec.rb} +6 -6
- data/spec/ruby-lint/virtual_machine/{modules.rb → modules_spec.rb} +39 -9
- data/spec/ruby-lint/virtual_machine/reference_amount_spec.rb +61 -0
- data/spec/ruby-lint/virtual_machine/{unused.rb → unused_spec.rb} +4 -4
- data/spec/{helper.rb → spec_helper.rb} +6 -4
- data/spec/support/building.rb +10 -6
- data/spec/support/coveralls.rb +1 -1
- data/spec/support/parsing.rb +10 -1
- data/spec/support/simplecov.rb +1 -1
- data/spec/support/versions.rb +9 -0
- data/task/test.rake +2 -4
- data/task/travis.rake +1 -0
- metadata +144 -143
- metadata.gz.asc +14 -14
- data/.rubocop.yml +0 -59
- data/doc/contributing.md +0 -16
- data/lib/ruby-lint/analysis/confusing_variables.rb +0 -26
- data/lib/ruby-lint/definitions/core/main.rb +0 -25
- data/lib/ruby-lint/definitions/core/psych.rb +0 -2231
- data/lib/ruby-lint/definitions/core/rubinius.rb +0 -16637
- data/lib/ruby-lint/definitions/core/ruby_lint.rb +0 -93
- data/spec/ruby-lint/analysis/confusing_variables.rb +0 -46
- data/spec/ruby-lint/analysis/undefined_methods.rb +0 -174
- data/spec/ruby-lint/configuration.rb +0 -54
- data/spec/ruby-lint/definition/constant_proxy.rb +0 -31
- data/spec/ruby-lint/parser.rb +0 -14
- data/spec/ruby-lint/presenter/json.rb +0 -31
- data/spec/ruby-lint/presenter/text.rb +0 -22
- data/spec/ruby-lint/report.rb +0 -50
- data/spec/ruby-lint/report/entry.rb +0 -28
- data/spec/ruby-lint/runner.rb +0 -32
- data/spec/ruby-lint/virtual_machine/associate_nodes.rb +0 -17
- data/spec/ruby-lint/virtual_machine/reference_amount.rb +0 -33
- data/spec/support/bacon.rb +0 -33
- data/task/cop.rake +0 -11
data/lib/ruby-lint/parser.rb
CHANGED
|
@@ -12,6 +12,8 @@ module RubyLint
|
|
|
12
12
|
def initialize
|
|
13
13
|
builder = AST::Builder.new
|
|
14
14
|
@internal_parser = ::Parser::CurrentRuby.new(builder)
|
|
15
|
+
|
|
16
|
+
internal_parser.diagnostics.all_errors_are_fatal = false
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
##
|
|
@@ -24,21 +26,24 @@ module RubyLint
|
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
##
|
|
27
|
-
# Parses a block of Ruby code and
|
|
29
|
+
# Parses a block of Ruby code and returns the AST and a mapping of each AST
|
|
30
|
+
# node and their comments (if there are any). This mapping is returned as a
|
|
31
|
+
# Hash.
|
|
28
32
|
#
|
|
29
33
|
# @param [String] code
|
|
30
34
|
# @param [String] file
|
|
31
35
|
# @param [Numeric] line
|
|
32
|
-
# @return [
|
|
36
|
+
# @return [Array]
|
|
33
37
|
#
|
|
34
38
|
def parse(code, file = '(ruby-lint)', line = 1)
|
|
35
39
|
buffer = ::Parser::Source::Buffer.new(file, line)
|
|
36
40
|
buffer.source = code
|
|
37
|
-
ast
|
|
41
|
+
ast, comments = internal_parser.parse_with_comments(buffer)
|
|
42
|
+
associator = ::Parser::Source::Comment::Associator.new(comments, ast)
|
|
38
43
|
|
|
39
44
|
internal_parser.reset
|
|
40
45
|
|
|
41
|
-
return AST::Node.new(:root, [ast])
|
|
46
|
+
return AST::Node.new(:root, [ast]), associator.associate
|
|
42
47
|
end
|
|
43
48
|
end # Parser
|
|
44
49
|
end # RubyLint
|
|
@@ -10,7 +10,8 @@ module RubyLint
|
|
|
10
10
|
#
|
|
11
11
|
# @return [String]
|
|
12
12
|
#
|
|
13
|
-
FORMAT = '%{
|
|
13
|
+
FORMAT = '%{filename}: %{level}: line %{line}, column %{column}: ' \
|
|
14
|
+
'%{message}'
|
|
14
15
|
|
|
15
16
|
##
|
|
16
17
|
# @param [String] format The format to use for each entry.
|
data/lib/ruby-lint/report.rb
CHANGED
|
@@ -15,28 +15,22 @@ module RubyLint
|
|
|
15
15
|
# * info
|
|
16
16
|
#
|
|
17
17
|
# Unless other levels are specified when creating an instance these levels
|
|
18
|
-
# are used for each new instance.
|
|
19
|
-
#
|
|
20
|
-
# Adding available levels can be done as following:
|
|
21
|
-
#
|
|
22
|
-
# RubyLint::Report.add_level(:pedantic)
|
|
23
|
-
#
|
|
24
|
-
# Retrieving a list of available levels in turn is done as following:
|
|
25
|
-
#
|
|
26
|
-
# RubyLint::Report.levels # => [:error, :warning, :info, :pedantic]
|
|
27
|
-
#
|
|
28
|
-
# Each level is a Symbol and will be cased to one automatically.
|
|
18
|
+
# are used for each new instance. Extra levels can be specified in the
|
|
19
|
+
# constructor of this class.
|
|
29
20
|
#
|
|
30
21
|
# ## Adding Entries
|
|
31
22
|
#
|
|
32
|
-
# Adding entries can be done by either calling {RubyLint::Report#add}
|
|
33
|
-
# method for the corresponding reporting level:
|
|
23
|
+
# Adding entries can be done by either calling {RubyLint::Report#add}:
|
|
34
24
|
#
|
|
35
25
|
# report = RubyLint::Report.new
|
|
36
26
|
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
27
|
+
# report.add(
|
|
28
|
+
# :level => :info,
|
|
29
|
+
# :message => 'informational message',
|
|
30
|
+
# :line => 1,
|
|
31
|
+
# :column => 2,
|
|
32
|
+
# :file => 'file.rb'
|
|
33
|
+
# )
|
|
40
34
|
#
|
|
41
35
|
# When using {RubyLint::Report#add} any invalid/disabled reporting levels
|
|
42
36
|
# will be silently ignored. This makes it easier for code to add entries of a
|
|
@@ -44,6 +38,7 @@ module RubyLint
|
|
|
44
38
|
#
|
|
45
39
|
# @!attribute [r] entries
|
|
46
40
|
# @return [Array] The entries of the report.
|
|
41
|
+
#
|
|
47
42
|
# @!attribute [r] levels
|
|
48
43
|
# @return [Array] The enabled levels of the report.
|
|
49
44
|
#
|
|
@@ -68,34 +63,16 @@ module RubyLint
|
|
|
68
63
|
##
|
|
69
64
|
# Adds a new entry to the report.
|
|
70
65
|
#
|
|
71
|
-
# @param [
|
|
72
|
-
# @
|
|
73
|
-
#
|
|
74
|
-
# @
|
|
75
|
-
# @param [String] file
|
|
66
|
+
# @param [Hash] attributes
|
|
67
|
+
# @option attributes [Symbol] :level The level of the message.
|
|
68
|
+
#
|
|
69
|
+
# @see RubyLint::Report::Entry#initialize
|
|
76
70
|
#
|
|
77
|
-
def add(
|
|
78
|
-
level = level.to_sym
|
|
71
|
+
def add(attributes)
|
|
72
|
+
level = attributes[:level].to_sym
|
|
79
73
|
|
|
80
74
|
if valid_level?(level)
|
|
81
|
-
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
##
|
|
86
|
-
# Makes it easier to add entries to a report by calling methods such as
|
|
87
|
-
# `#info` instead of `add(:info, ...)`.
|
|
88
|
-
#
|
|
89
|
-
# @param [Symbol] name
|
|
90
|
-
# @param [Array] args
|
|
91
|
-
# @param [Proc] block
|
|
92
|
-
# @raise [NoMethodError] Raised when an invalid method was called.
|
|
93
|
-
#
|
|
94
|
-
def method_missing(name, *args, &block)
|
|
95
|
-
if valid_level?(name)
|
|
96
|
-
return add(name, *args, &block)
|
|
97
|
-
else
|
|
98
|
-
raise NoMethodError, 'undefined method "%s" for %s' % [name, inspect]
|
|
75
|
+
entries << Entry.new(attributes)
|
|
99
76
|
end
|
|
100
77
|
end
|
|
101
78
|
|
|
@@ -106,7 +83,7 @@ module RubyLint
|
|
|
106
83
|
# @return [TrueClass|FalseClass]
|
|
107
84
|
#
|
|
108
85
|
def valid_level?(level)
|
|
109
|
-
return
|
|
86
|
+
return levels.include?(level)
|
|
110
87
|
end
|
|
111
88
|
end # Report
|
|
112
89
|
end # RubyLint
|
|
@@ -6,31 +6,32 @@ module RubyLint
|
|
|
6
6
|
#
|
|
7
7
|
# @!attribute [r] level
|
|
8
8
|
# @return [Symbol]
|
|
9
|
+
#
|
|
9
10
|
# @!attribute [r] message
|
|
10
11
|
# @return [String]
|
|
12
|
+
#
|
|
11
13
|
# @!attribute [r] line
|
|
12
14
|
# @return [Numeric]
|
|
15
|
+
#
|
|
13
16
|
# @!attribute [r] column
|
|
14
17
|
# @return [Numeric]
|
|
18
|
+
#
|
|
15
19
|
# @!attribute [r] file
|
|
16
20
|
# @return [String]
|
|
17
21
|
#
|
|
22
|
+
# @!attribute [r] node
|
|
23
|
+
# @return [RubyLint::AST::Node]
|
|
24
|
+
#
|
|
18
25
|
class Entry
|
|
19
|
-
attr_reader :level, :message, :line, :column, :file
|
|
26
|
+
attr_reader :level, :message, :line, :column, :file, :node
|
|
20
27
|
|
|
21
28
|
##
|
|
22
|
-
# @param [
|
|
23
|
-
# @param [String] message
|
|
24
|
-
# @param [Numeric] line
|
|
25
|
-
# @param [Numeric] column
|
|
26
|
-
# @param [String] file
|
|
29
|
+
# @param [Hash] attributes
|
|
27
30
|
#
|
|
28
|
-
def initialize(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@column = column
|
|
33
|
-
@file = file
|
|
31
|
+
def initialize(attributes = {})
|
|
32
|
+
attributes.each do |key, value|
|
|
33
|
+
instance_variable_set("@#{key}", value)
|
|
34
|
+
end
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
##
|
|
@@ -47,11 +48,13 @@ module RubyLint
|
|
|
47
48
|
#
|
|
48
49
|
def attributes
|
|
49
50
|
return {
|
|
50
|
-
:level
|
|
51
|
-
:message
|
|
52
|
-
:line
|
|
53
|
-
:column
|
|
54
|
-
:file
|
|
51
|
+
:level => level,
|
|
52
|
+
:message => message,
|
|
53
|
+
:line => line,
|
|
54
|
+
:column => column,
|
|
55
|
+
:file => file,
|
|
56
|
+
:filename => filename,
|
|
57
|
+
:node => node
|
|
55
58
|
}
|
|
56
59
|
end
|
|
57
60
|
|
data/lib/ruby-lint/runner.rb
CHANGED
|
@@ -14,7 +14,7 @@ module RubyLint
|
|
|
14
14
|
# @param [RubyLint::Configuration] configuration
|
|
15
15
|
#
|
|
16
16
|
def initialize(configuration)
|
|
17
|
-
@configuration
|
|
17
|
+
@configuration = configuration
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
##
|
|
@@ -39,13 +39,7 @@ module RubyLint
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
files.each do |file|
|
|
42
|
-
|
|
43
|
-
ast = parser.parse(code, file)
|
|
44
|
-
vm = RubyLint::VirtualMachine.new
|
|
45
|
-
|
|
46
|
-
vm.run(ast)
|
|
47
|
-
|
|
48
|
-
run_analysis(ast, vm, report)
|
|
42
|
+
analyze_file(file, parser, report)
|
|
49
43
|
end
|
|
50
44
|
|
|
51
45
|
return presenter.present(report)
|
|
@@ -53,15 +47,102 @@ module RubyLint
|
|
|
53
47
|
|
|
54
48
|
private
|
|
55
49
|
|
|
50
|
+
##
|
|
51
|
+
# @param [String] file
|
|
52
|
+
# @param [RubyLint::Parser] parser
|
|
53
|
+
# @param [RubyLint::Report] report
|
|
54
|
+
#
|
|
55
|
+
def analyze_file(file, parser, report)
|
|
56
|
+
ast, comments = parse_file(parser, file)
|
|
57
|
+
|
|
58
|
+
extra_ast, extra_comments = process_external_files(ast)
|
|
59
|
+
|
|
60
|
+
extra_ast.push(ast)
|
|
61
|
+
|
|
62
|
+
comments.merge!(extra_comments)
|
|
63
|
+
|
|
64
|
+
autoload_constants(extra_ast)
|
|
65
|
+
|
|
66
|
+
vm = run_vm(extra_ast, comments)
|
|
67
|
+
|
|
68
|
+
run_analysis(ast, vm, report)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
# Parses the given file and returns an Array containing all the associated
|
|
73
|
+
# AST nodes and comments.
|
|
74
|
+
#
|
|
75
|
+
# @param [RubyLint::Parser] parser
|
|
76
|
+
# @param [String] file
|
|
77
|
+
# @return [Array]
|
|
78
|
+
#
|
|
79
|
+
def parse_file(parser, file)
|
|
80
|
+
return parser.parse(File.read(file), file)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Automatically loads definitions using {RubyLint::ConstantLoader}.
|
|
85
|
+
#
|
|
86
|
+
# @param [Array] nodes
|
|
87
|
+
#
|
|
88
|
+
def autoload_constants(nodes)
|
|
89
|
+
nodes.each { |node| GlobalScope.constant_loader.iterate(node) }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
# Processes external Ruby files using {RubyLint::FileLoader}. The return
|
|
94
|
+
# value is a collection of AST nodes and a Hash containing all the
|
|
95
|
+
# associated comments.
|
|
96
|
+
#
|
|
97
|
+
# @param [RubyLint::AST::Node] root_ast
|
|
98
|
+
# @return [Array]
|
|
99
|
+
#
|
|
100
|
+
def process_external_files(root_ast)
|
|
101
|
+
loader = FileLoader.new(
|
|
102
|
+
:directories => configuration.directories,
|
|
103
|
+
:ignore_paths => configuration.ignore_paths,
|
|
104
|
+
:debug => configuration.debug
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
nodes = []
|
|
108
|
+
comments = {}
|
|
109
|
+
|
|
110
|
+
loader.iterate(root_ast)
|
|
111
|
+
|
|
112
|
+
loader.nodes.each do |(ast, cmts)|
|
|
113
|
+
nodes << ast
|
|
114
|
+
|
|
115
|
+
comments.merge!(cmts)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
return nodes, comments
|
|
119
|
+
end
|
|
120
|
+
|
|
56
121
|
##
|
|
57
122
|
# @param [Parser::Diagnostic] diagnostic
|
|
58
123
|
# @param [RubyLint::Report] report
|
|
59
124
|
#
|
|
60
125
|
def report_diagnostic(diagnostic, report)
|
|
61
|
-
|
|
62
|
-
|
|
126
|
+
report.add(
|
|
127
|
+
:level => :error,
|
|
128
|
+
:message => diagnostic.message,
|
|
129
|
+
:line => diagnostic.location.line,
|
|
130
|
+
:column => diagnostic.location.column,
|
|
131
|
+
:file => diagnostic.location.source_buffer.name
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# @param [Array] nodes
|
|
137
|
+
# @param [Hash] comments
|
|
138
|
+
# @return [RubyLint::VirtualMachine]
|
|
139
|
+
#
|
|
140
|
+
def run_vm(nodes, comments)
|
|
141
|
+
vm = RubyLint::VirtualMachine.new(:comments => comments)
|
|
142
|
+
|
|
143
|
+
vm.run(nodes)
|
|
63
144
|
|
|
64
|
-
|
|
145
|
+
return vm
|
|
65
146
|
end
|
|
66
147
|
|
|
67
148
|
##
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
# Platform: <%= RUBY_ENGINE %> <%= Rubinius::VERSION rescue RUBY_VERSION %>
|
|
6
6
|
|
|
7
7
|
<% @constants.each do |constant| %>
|
|
8
|
-
RubyLint::
|
|
8
|
+
RubyLint::GlobalScope.definitions.define_constant('<%= constant.name %>') do |klass|
|
|
9
9
|
<%- if constant.superclass -%>
|
|
10
|
-
klass.inherits(RubyLint::
|
|
10
|
+
klass.inherits(RubyLint::GlobalScope.constant_proxy('<%= constant.superclass %>'))
|
|
11
11
|
<%- end -%>
|
|
12
12
|
|
|
13
13
|
<%- constant.methods.each do |type, collection| -%>
|
|
@@ -4,20 +4,14 @@ module RubyLint
|
|
|
4
4
|
# types.
|
|
5
5
|
#
|
|
6
6
|
module VariablePredicates
|
|
7
|
-
##
|
|
8
|
-
# Array containing various Ruby types that are considered to be scalar
|
|
9
|
-
# values.
|
|
10
|
-
#
|
|
11
|
-
# @return [Array]
|
|
12
|
-
#
|
|
13
|
-
SCALAR_TYPES = [:int, :float, :str, :sym]
|
|
14
|
-
|
|
15
7
|
##
|
|
16
8
|
# Array containing various predicate methods to create.
|
|
17
9
|
#
|
|
18
10
|
# @return [Array]
|
|
19
11
|
#
|
|
20
|
-
PREDICATE_METHODS = [
|
|
12
|
+
PREDICATE_METHODS = [
|
|
13
|
+
:array, :class, :const, :hash, :module, :self, :block, :gvar
|
|
14
|
+
]
|
|
21
15
|
|
|
22
16
|
##
|
|
23
17
|
# Hash containing various Node types and the associated Ruby classes.
|
|
@@ -34,7 +28,10 @@ module RubyLint
|
|
|
34
28
|
:hash => 'Hash',
|
|
35
29
|
:irange => 'Range',
|
|
36
30
|
:erange => 'Range',
|
|
37
|
-
:lambda => 'Proc'
|
|
31
|
+
:lambda => 'Proc',
|
|
32
|
+
:true => 'TrueClass',
|
|
33
|
+
:false => 'FalseClass',
|
|
34
|
+
:nil => 'NilClass'
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
PREDICATE_METHODS.each do |type|
|
data/lib/ruby-lint/version.rb
CHANGED
|
@@ -42,38 +42,44 @@ module RubyLint
|
|
|
42
42
|
# {RubyLint::VirtualMachine#associations} with the keys set to the nodes and
|
|
43
43
|
# the values to the corresponding definitions.
|
|
44
44
|
#
|
|
45
|
+
# ## Options
|
|
46
|
+
#
|
|
47
|
+
# The following extra options can be set in the constructor:
|
|
48
|
+
#
|
|
49
|
+
# * `:comments`: a Hash containing the comments for various AST nodes.
|
|
50
|
+
#
|
|
45
51
|
# @!attribute [r] associations
|
|
46
52
|
# @return [Hash]
|
|
53
|
+
#
|
|
54
|
+
# @!attribute [r] comments
|
|
55
|
+
# @return [Hash]
|
|
56
|
+
#
|
|
47
57
|
# @!attribute [r] definitions
|
|
48
58
|
# @return [RubyLint::Definition::RubyObject]
|
|
59
|
+
#
|
|
60
|
+
# @!attribute [r] extra_definitions
|
|
61
|
+
# @return [Array]
|
|
62
|
+
#
|
|
49
63
|
# @!attribute [r] value_stack
|
|
50
64
|
# @return [RubyLint::NestedStack]
|
|
65
|
+
#
|
|
51
66
|
# @!attribute [r] variable_stack
|
|
52
67
|
# @return [RubyLint::NestedStack]
|
|
53
68
|
#
|
|
69
|
+
# @!attribute [r] docstring_tags
|
|
70
|
+
# @return [RubyLint::Docstring::Mapping]
|
|
71
|
+
#
|
|
54
72
|
class VirtualMachine < Iterator
|
|
55
73
|
include Helper::ConstantPaths
|
|
56
74
|
|
|
57
|
-
attr_reader :associations,
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
attr_reader :associations,
|
|
76
|
+
:comments,
|
|
77
|
+
:definitions,
|
|
78
|
+
:docstring_tags,
|
|
79
|
+
:value_stack,
|
|
80
|
+
:variable_stack
|
|
60
81
|
|
|
61
|
-
|
|
62
|
-
# Hash containing the definition types to copy when including/extending a
|
|
63
|
-
# module.
|
|
64
|
-
#
|
|
65
|
-
# @return [Hash]
|
|
66
|
-
#
|
|
67
|
-
INCLUDE_CALLS = {
|
|
68
|
-
'include' => {
|
|
69
|
-
:const => :const,
|
|
70
|
-
:instance_method => :instance_method
|
|
71
|
-
},
|
|
72
|
-
'extend' => {
|
|
73
|
-
:const => :const,
|
|
74
|
-
:instance_method => :method
|
|
75
|
-
}
|
|
76
|
-
}
|
|
82
|
+
private :value_stack, :variable_stack, :docstring_tags
|
|
77
83
|
|
|
78
84
|
##
|
|
79
85
|
# Hash containing variable assignment types and the corresponding variable
|
|
@@ -93,24 +99,32 @@ module RubyLint
|
|
|
93
99
|
#
|
|
94
100
|
# @return [Array]
|
|
95
101
|
#
|
|
96
|
-
PRIMITIVES = [:int, :float, :str, :sym]
|
|
102
|
+
PRIMITIVES = [:int, :float, :str, :sym, :true, :false, :nil]
|
|
97
103
|
|
|
98
104
|
##
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
# considered to be invalid syntax and thus its mapped to
|
|
102
|
-
# `on_send_assign_member`.
|
|
105
|
+
# Returns a Hash containing the method call evaluators to use for `(send)`
|
|
106
|
+
# nodes.
|
|
103
107
|
#
|
|
104
108
|
# @return [Hash]
|
|
105
109
|
#
|
|
106
|
-
SEND_MAPPING = {
|
|
110
|
+
SEND_MAPPING = {
|
|
111
|
+
'[]=' => MethodCall::AssignMember,
|
|
112
|
+
'include' => MethodCall::Include,
|
|
113
|
+
'extend' => MethodCall::Include,
|
|
114
|
+
'alias_method' => MethodCall::Alias,
|
|
115
|
+
'attr' => MethodCall::Attribute,
|
|
116
|
+
'attr_reader' => MethodCall::Attribute,
|
|
117
|
+
'attr_writer' => MethodCall::Attribute,
|
|
118
|
+
'attr_accessor' => MethodCall::Attribute,
|
|
119
|
+
'define_method' => MethodCall::DefineMethod
|
|
120
|
+
}
|
|
107
121
|
|
|
108
122
|
##
|
|
109
123
|
# Array containing the various argument types of method definitions.
|
|
110
124
|
#
|
|
111
125
|
# @return [Array]
|
|
112
126
|
#
|
|
113
|
-
ARGUMENT_TYPES = [:arg, :optarg, :restarg, :blockarg]
|
|
127
|
+
ARGUMENT_TYPES = [:arg, :optarg, :restarg, :blockarg, :kwoptarg]
|
|
114
128
|
|
|
115
129
|
##
|
|
116
130
|
# The types of variables to export outside of a method definition.
|
|
@@ -119,13 +133,6 @@ module RubyLint
|
|
|
119
133
|
#
|
|
120
134
|
EXPORT_VARIABLES = [:ivar, :cvar, :const]
|
|
121
135
|
|
|
122
|
-
##
|
|
123
|
-
# Array containing the directories to use for looking up definition files.
|
|
124
|
-
#
|
|
125
|
-
# @return [Array]
|
|
126
|
-
#
|
|
127
|
-
LOAD_PATH = [File.expand_path('../definitions/core', __FILE__)]
|
|
128
|
-
|
|
129
136
|
##
|
|
130
137
|
# The available method visibilities.
|
|
131
138
|
#
|
|
@@ -133,78 +140,34 @@ module RubyLint
|
|
|
133
140
|
#
|
|
134
141
|
VISIBILITIES = [:public, :protected, :private].freeze
|
|
135
142
|
|
|
136
|
-
##
|
|
137
|
-
# @return [RubyLint::Definition::RubyObject]
|
|
138
|
-
#
|
|
139
|
-
def self.global_scope
|
|
140
|
-
return @global_scope ||= Definition::RubyObject.new(
|
|
141
|
-
:name => 'global',
|
|
142
|
-
:type => :global
|
|
143
|
-
)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
##
|
|
147
|
-
# Looks up the given constant in the global scope. If it does not exist
|
|
148
|
-
# this method will try to load it from one of the existing definitions.
|
|
149
|
-
#
|
|
150
|
-
# @param [String] name
|
|
151
|
-
# @return [RubyLint::Definition::RubyObject]
|
|
152
|
-
#
|
|
153
|
-
def self.global_constant(name)
|
|
154
|
-
found = global_scope.lookup_constant_path(name)
|
|
155
|
-
|
|
156
|
-
if !found and !constant_loader.loaded?(name)
|
|
157
|
-
constant_loader.load_constant(name)
|
|
158
|
-
|
|
159
|
-
found = global_scope.lookup_constant_path(name)
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
return found
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
##
|
|
166
|
-
# Creates a new proxy for a global constant.
|
|
167
|
-
#
|
|
168
|
-
# @param [String] name The name of the constant, can include an entire
|
|
169
|
-
# constant path in the form of `Foo::Bar`.
|
|
170
|
-
# @return [RubyLint::Definition::ConstantProxy]
|
|
171
|
-
#
|
|
172
|
-
def self.constant_proxy(name)
|
|
173
|
-
return Definition::ConstantProxy.new(global_scope, name)
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
##
|
|
177
|
-
# @return [RubyLint::ConstantLoader]
|
|
178
|
-
#
|
|
179
|
-
def self.constant_loader
|
|
180
|
-
return @constant_loader ||= ConstantLoader.new
|
|
181
|
-
end
|
|
182
|
-
|
|
183
143
|
##
|
|
184
144
|
# Called after a new instance of the virtual machine has been created.
|
|
185
145
|
#
|
|
186
146
|
def after_initialize
|
|
187
|
-
@
|
|
188
|
-
|
|
189
|
-
@
|
|
190
|
-
@
|
|
191
|
-
@
|
|
192
|
-
@
|
|
193
|
-
@
|
|
194
|
-
@
|
|
147
|
+
@comments ||= {}
|
|
148
|
+
|
|
149
|
+
@associations = {}
|
|
150
|
+
@definitions = initial_definitions
|
|
151
|
+
@scopes = [@definitions]
|
|
152
|
+
@value_stack = NestedStack.new
|
|
153
|
+
@variable_stack = NestedStack.new
|
|
154
|
+
@ignored_nodes = []
|
|
155
|
+
@visibility = :public
|
|
195
156
|
|
|
157
|
+
reset_docstring_tags
|
|
196
158
|
reset_method_type
|
|
197
159
|
end
|
|
198
160
|
|
|
199
161
|
##
|
|
200
|
-
# Processes the given AST
|
|
162
|
+
# Processes the given AST or a collection of AST nodes.
|
|
201
163
|
#
|
|
202
164
|
# @see #iterate
|
|
165
|
+
# @param [Array|RubyLint::AST::Node] ast
|
|
203
166
|
#
|
|
204
167
|
def run(ast)
|
|
205
|
-
|
|
168
|
+
ast = [ast] unless ast.is_a?(Array)
|
|
206
169
|
|
|
207
|
-
iterate(
|
|
170
|
+
ast.each { |node| iterate(node) }
|
|
208
171
|
|
|
209
172
|
freeze
|
|
210
173
|
end
|
|
@@ -213,11 +176,11 @@ module RubyLint
|
|
|
213
176
|
# Freezes the VM along with all the instance variables.
|
|
214
177
|
#
|
|
215
178
|
def freeze
|
|
216
|
-
|
|
179
|
+
@associations.freeze
|
|
180
|
+
@definitions.freeze
|
|
181
|
+
@scopes.freeze
|
|
217
182
|
|
|
218
|
-
|
|
219
|
-
instance_variable_get(var).freeze
|
|
220
|
-
end
|
|
183
|
+
super
|
|
221
184
|
end
|
|
222
185
|
|
|
223
186
|
##
|
|
@@ -309,7 +272,7 @@ module RubyLint
|
|
|
309
272
|
def after_masgn(node)
|
|
310
273
|
variables = variable_stack.pop
|
|
311
274
|
values = value_stack.pop.first
|
|
312
|
-
values = values ? values.value : []
|
|
275
|
+
values = values && values.value ? values.value : []
|
|
313
276
|
|
|
314
277
|
variables.each_with_index do |variable, index|
|
|
315
278
|
variable.value = values[index].value if values[index]
|
|
@@ -374,12 +337,27 @@ module RubyLint
|
|
|
374
337
|
end
|
|
375
338
|
end
|
|
376
339
|
|
|
340
|
+
##
|
|
341
|
+
# Called whenever a magic regexp global variable is referenced (e.g. `$1`).
|
|
342
|
+
#
|
|
343
|
+
# @param [RubyLint::AST::Node] node
|
|
344
|
+
#
|
|
345
|
+
def on_nth_ref(node)
|
|
346
|
+
var = definitions.lookup(:gvar, "$#{node.children[0]}")
|
|
347
|
+
|
|
348
|
+
push_value(var.value)
|
|
349
|
+
end
|
|
350
|
+
|
|
377
351
|
##
|
|
378
352
|
# @param [RubyLint::AST::Node] node
|
|
379
353
|
#
|
|
380
354
|
def on_const(node)
|
|
381
355
|
increment_reference_amount(node)
|
|
382
356
|
push_variable_value(node)
|
|
357
|
+
|
|
358
|
+
# The root node is also used in such a way that it processes child (=
|
|
359
|
+
# receiver) constants.
|
|
360
|
+
skip_child_nodes!(node)
|
|
383
361
|
end
|
|
384
362
|
|
|
385
363
|
##
|
|
@@ -488,7 +466,7 @@ module RubyLint
|
|
|
488
466
|
parent = evaluate_node(parent_node)
|
|
489
467
|
|
|
490
468
|
if !parent or !parent.const?
|
|
491
|
-
|
|
469
|
+
parent = current_scope.lookup(:const, 'Object')
|
|
492
470
|
end
|
|
493
471
|
end
|
|
494
472
|
|
|
@@ -576,6 +554,15 @@ module RubyLint
|
|
|
576
554
|
|
|
577
555
|
associate_node(node, definition)
|
|
578
556
|
|
|
557
|
+
buffer_docstring_tags(node)
|
|
558
|
+
|
|
559
|
+
if docstring_tags and docstring_tags.return_tag
|
|
560
|
+
assign_return_value_from_tag(
|
|
561
|
+
docstring_tags.return_tag,
|
|
562
|
+
definition
|
|
563
|
+
)
|
|
564
|
+
end
|
|
565
|
+
|
|
579
566
|
push_scope(definition)
|
|
580
567
|
end
|
|
581
568
|
|
|
@@ -588,29 +575,13 @@ module RubyLint
|
|
|
588
575
|
previous = pop_scope
|
|
589
576
|
current = current_scope
|
|
590
577
|
|
|
578
|
+
reset_docstring_tags
|
|
579
|
+
|
|
591
580
|
EXPORT_VARIABLES.each do |type|
|
|
592
581
|
current.copy(previous, type)
|
|
593
582
|
end
|
|
594
583
|
end
|
|
595
584
|
|
|
596
|
-
##
|
|
597
|
-
# @param [RubyLint::AST::Node] node
|
|
598
|
-
#
|
|
599
|
-
def on_args(node)
|
|
600
|
-
variable_stack.add_stack
|
|
601
|
-
end
|
|
602
|
-
|
|
603
|
-
##
|
|
604
|
-
# @param [RubyLint::AST::Node] node
|
|
605
|
-
#
|
|
606
|
-
def after_args(node)
|
|
607
|
-
variables = variable_stack.pop
|
|
608
|
-
|
|
609
|
-
variables.each do |variable|
|
|
610
|
-
current_scope.add_definition(variable)
|
|
611
|
-
end
|
|
612
|
-
end
|
|
613
|
-
|
|
614
585
|
# Creates callbacks for various argument types such as :arg and :optarg.
|
|
615
586
|
ARGUMENT_TYPES.each do |type|
|
|
616
587
|
define_method("on_#{type}") do |node|
|
|
@@ -620,16 +591,19 @@ module RubyLint
|
|
|
620
591
|
define_method("after_#{type}") do |node|
|
|
621
592
|
value = value_stack.pop.first
|
|
622
593
|
name = node.children[0].to_s
|
|
623
|
-
|
|
624
|
-
:type =>
|
|
594
|
+
var = Definition::RubyObject.new(
|
|
595
|
+
:type => :lvar,
|
|
625
596
|
:name => name,
|
|
626
597
|
:value => value,
|
|
627
598
|
:instance_type => :instance
|
|
628
599
|
)
|
|
629
600
|
|
|
630
|
-
|
|
601
|
+
if docstring_tags and docstring_tags.param_tags[name]
|
|
602
|
+
update_parents_from_tag(docstring_tags.param_tags[name], var)
|
|
603
|
+
end
|
|
631
604
|
|
|
632
|
-
|
|
605
|
+
current_scope.add(type, name, var)
|
|
606
|
+
current_scope.add_definition(var)
|
|
633
607
|
end
|
|
634
608
|
end
|
|
635
609
|
|
|
@@ -659,65 +633,64 @@ module RubyLint
|
|
|
659
633
|
receiver, name, _ = *node
|
|
660
634
|
|
|
661
635
|
name = name.to_s
|
|
662
|
-
|
|
663
|
-
|
|
636
|
+
args_length = node.children[2..-1].length
|
|
637
|
+
values = value_stack.pop
|
|
638
|
+
arguments = values.pop(args_length)
|
|
639
|
+
block = nil
|
|
640
|
+
|
|
641
|
+
receiver_definition = values.first
|
|
642
|
+
|
|
643
|
+
if arguments.length != args_length
|
|
644
|
+
raise <<-EOF
|
|
645
|
+
Not enough argument definitions for #{node.inspect_oneline}.
|
|
646
|
+
Location: #{node.file} on line #{node.line}, column #{node.column}
|
|
647
|
+
Expected: #{args_length}
|
|
648
|
+
Received: #{arguments.length}
|
|
649
|
+
EOF
|
|
650
|
+
end
|
|
664
651
|
|
|
665
|
-
|
|
652
|
+
# If the receiver doesn't exist there's no point in associating a context
|
|
653
|
+
# with it.
|
|
654
|
+
if receiver and !receiver_definition
|
|
655
|
+
push_unknown_value
|
|
666
656
|
|
|
667
|
-
|
|
657
|
+
return
|
|
658
|
+
end
|
|
668
659
|
|
|
669
|
-
if receiver
|
|
670
|
-
context =
|
|
660
|
+
if receiver and receiver_definition
|
|
661
|
+
context = receiver_definition
|
|
671
662
|
else
|
|
672
663
|
context = current_scope
|
|
673
664
|
|
|
674
665
|
# `parser` wraps (block) nodes around (send) calls which is a bit
|
|
675
666
|
# inconvenient
|
|
676
|
-
|
|
667
|
+
if context.block?
|
|
668
|
+
block = context
|
|
669
|
+
context = previous_scope
|
|
670
|
+
end
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
if SEND_MAPPING[name]
|
|
674
|
+
evaluator = SEND_MAPPING[name].new(node, self)
|
|
675
|
+
|
|
676
|
+
evaluator.evaluate(arguments, context, block)
|
|
677
677
|
end
|
|
678
678
|
|
|
679
679
|
# Associate the receiver node with the context so that it becomes
|
|
680
680
|
# easier to retrieve later on.
|
|
681
|
-
if receiver
|
|
681
|
+
if receiver and context
|
|
682
682
|
associate_node(receiver, context)
|
|
683
683
|
end
|
|
684
684
|
|
|
685
685
|
if context and context.method_defined?(name)
|
|
686
686
|
retval = context.call_method(name)
|
|
687
687
|
|
|
688
|
-
push_value(retval)
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
##
|
|
693
|
-
# @param [RubyLint::AST::Node] node
|
|
694
|
-
#
|
|
695
|
-
def on_send_include(node)
|
|
696
|
-
value_stack.add_stack
|
|
697
|
-
end
|
|
698
|
-
|
|
699
|
-
##
|
|
700
|
-
# Processes a `include` method call.
|
|
701
|
-
#
|
|
702
|
-
# @param [RubyLint::AST::Node] node
|
|
703
|
-
#
|
|
704
|
-
def after_send_include(node)
|
|
705
|
-
copy_types = INCLUDE_CALLS[node.children[1].to_s]
|
|
706
|
-
scope = current_scope
|
|
707
|
-
arguments = value_stack.pop
|
|
708
|
-
|
|
709
|
-
arguments.each do |source|
|
|
710
|
-
copy_types.each do |from, to|
|
|
711
|
-
source.list(from).each do |definition|
|
|
712
|
-
scope.add(to, definition.name, definition)
|
|
713
|
-
end
|
|
714
|
-
end
|
|
688
|
+
retval ? push_value(retval) : push_unknown_value
|
|
689
|
+
else
|
|
690
|
+
push_unknown_value
|
|
715
691
|
end
|
|
716
692
|
end
|
|
717
693
|
|
|
718
|
-
alias_method :on_send_extend, :on_send_include
|
|
719
|
-
alias_method :after_send_extend, :after_send_include
|
|
720
|
-
|
|
721
694
|
VISIBILITIES.each do |vis|
|
|
722
695
|
define_method("on_send_#{vis}") do |node|
|
|
723
696
|
@visibility = vis
|
|
@@ -727,34 +700,26 @@ module RubyLint
|
|
|
727
700
|
##
|
|
728
701
|
# @param [RubyLint::AST::Node] node
|
|
729
702
|
#
|
|
730
|
-
def
|
|
703
|
+
def on_alias(node)
|
|
731
704
|
value_stack.add_stack
|
|
732
705
|
end
|
|
733
706
|
|
|
734
707
|
##
|
|
735
|
-
# Processes
|
|
708
|
+
# Processes calls to `alias`. Two types of data can be aliased:
|
|
736
709
|
#
|
|
737
|
-
#
|
|
710
|
+
# 1. Methods (using the syntax `alias ALIAS SOURCE`)
|
|
711
|
+
# 2. Global variables
|
|
738
712
|
#
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
end
|
|
748
|
-
|
|
749
|
-
indexes.each do |index|
|
|
750
|
-
member = Definition::RubyObject.new(
|
|
751
|
-
:name => index.value.to_s,
|
|
752
|
-
:type => :member,
|
|
753
|
-
:value => index_values.shift
|
|
754
|
-
)
|
|
713
|
+
# This method dispatches the alias process to two possible methods:
|
|
714
|
+
#
|
|
715
|
+
# * on_alias_sym: aliasing methods (using symbols)
|
|
716
|
+
# * on_alias_gvar: aliasing global variables
|
|
717
|
+
#
|
|
718
|
+
def after_alias(node)
|
|
719
|
+
arguments = value_stack.pop
|
|
720
|
+
evaluator = MethodCall::Alias.new(node, self)
|
|
755
721
|
|
|
756
|
-
|
|
757
|
-
end
|
|
722
|
+
evaluator.evaluate(arguments, current_scope)
|
|
758
723
|
end
|
|
759
724
|
|
|
760
725
|
private
|
|
@@ -768,12 +733,10 @@ module RubyLint
|
|
|
768
733
|
definitions = Definition::RubyObject.new(
|
|
769
734
|
:name => 'root',
|
|
770
735
|
:type => :root,
|
|
771
|
-
:parents => [
|
|
736
|
+
:parents => [GlobalScope.definitions],
|
|
772
737
|
:instance_type => :instance
|
|
773
738
|
)
|
|
774
739
|
|
|
775
|
-
definitions.merge(RubyLint::VirtualMachine.global_scope)
|
|
776
|
-
|
|
777
740
|
definitions.add(:keyword, 'self', definitions)
|
|
778
741
|
|
|
779
742
|
return definitions
|
|
@@ -783,20 +746,22 @@ module RubyLint
|
|
|
783
746
|
# Defines a new module/class based on the supplied node.
|
|
784
747
|
#
|
|
785
748
|
# @param [RubyLint::Node] node
|
|
786
|
-
# @param [
|
|
749
|
+
# @param [RubyLint::DefinitionBuilder::Base] definition_builder
|
|
787
750
|
# @param [Hash] options
|
|
788
751
|
#
|
|
789
752
|
def define_module(node, definition_builder, options = {})
|
|
790
753
|
builder = definition_builder.new(node, current_scope, options)
|
|
791
754
|
definition = builder.build
|
|
792
755
|
scope = builder.scope
|
|
793
|
-
existing = scope.lookup(definition.type, definition.name)
|
|
756
|
+
existing = scope.lookup(definition.type, definition.name, false)
|
|
794
757
|
|
|
795
758
|
if existing
|
|
796
759
|
definition = existing
|
|
797
760
|
|
|
798
761
|
inherit_definition(definition, current_scope)
|
|
799
762
|
else
|
|
763
|
+
definition.add_definition(definition)
|
|
764
|
+
|
|
800
765
|
scope.add_definition(definition)
|
|
801
766
|
end
|
|
802
767
|
|
|
@@ -881,6 +846,13 @@ module RubyLint
|
|
|
881
846
|
value_stack.push(definition) if definition && !value_stack.empty?
|
|
882
847
|
end
|
|
883
848
|
|
|
849
|
+
##
|
|
850
|
+
# Pushes an unknown value object onto the value stack.
|
|
851
|
+
#
|
|
852
|
+
def push_unknown_value
|
|
853
|
+
push_value(Definition::RubyObject.create_unknown)
|
|
854
|
+
end
|
|
855
|
+
|
|
884
856
|
##
|
|
885
857
|
# Adds a new variable and value stack.
|
|
886
858
|
#
|
|
@@ -897,11 +869,14 @@ module RubyLint
|
|
|
897
869
|
# @param [RubyLint::Definition::RubyObject] value
|
|
898
870
|
#
|
|
899
871
|
def assign_variable(type, name, value)
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
:
|
|
904
|
-
:
|
|
872
|
+
existing = current_scope.lookup(type, name)
|
|
873
|
+
ref_amount = existing ? existing.reference_amount + 1 : 0
|
|
874
|
+
variable = Definition::RubyObject.new(
|
|
875
|
+
:type => type,
|
|
876
|
+
:name => name,
|
|
877
|
+
:value => value,
|
|
878
|
+
:instance_type => :instance,
|
|
879
|
+
:reference_amount => ref_amount
|
|
905
880
|
)
|
|
906
881
|
|
|
907
882
|
buffer_assignment_value(variable.value)
|
|
@@ -975,6 +950,8 @@ module RubyLint
|
|
|
975
950
|
# will be overwritten.
|
|
976
951
|
#
|
|
977
952
|
def conditional_assignment(variable, value, bool = true)
|
|
953
|
+
variable.reference_amount += 1
|
|
954
|
+
|
|
978
955
|
if current_scope.has_definition?(variable.type, variable.name) == bool
|
|
979
956
|
variable.value = value
|
|
980
957
|
|
|
@@ -997,6 +974,8 @@ module RubyLint
|
|
|
997
974
|
definition = current_scope.lookup(node.type, node.name)
|
|
998
975
|
end
|
|
999
976
|
|
|
977
|
+
definition = Definition::RubyObject.create_unknown unless definition
|
|
978
|
+
|
|
1000
979
|
return definition
|
|
1001
980
|
end
|
|
1002
981
|
|
|
@@ -1040,5 +1019,103 @@ module RubyLint
|
|
|
1040
1019
|
definition.parents << inherit
|
|
1041
1020
|
end
|
|
1042
1021
|
end
|
|
1022
|
+
|
|
1023
|
+
##
|
|
1024
|
+
# Extracts all the docstring tags from the documentation of the given
|
|
1025
|
+
# node, retrieves the corresponding types and stores them for later use.
|
|
1026
|
+
#
|
|
1027
|
+
# @param [RubyLint::AST::Node] node
|
|
1028
|
+
#
|
|
1029
|
+
def buffer_docstring_tags(node)
|
|
1030
|
+
return unless comments[node]
|
|
1031
|
+
|
|
1032
|
+
parser = Docstring::Parser.new
|
|
1033
|
+
tags = parser.parse(comments[node].map(&:text))
|
|
1034
|
+
|
|
1035
|
+
@docstring_tags = Docstring::Mapping.new(tags)
|
|
1036
|
+
end
|
|
1037
|
+
|
|
1038
|
+
##
|
|
1039
|
+
# Resets the docstring tags collection back to its initial value.
|
|
1040
|
+
#
|
|
1041
|
+
def reset_docstring_tags
|
|
1042
|
+
@docstring_tags = nil
|
|
1043
|
+
end
|
|
1044
|
+
|
|
1045
|
+
##
|
|
1046
|
+
# Updates the parents of a definition according to the types of a `@param`
|
|
1047
|
+
# tag.
|
|
1048
|
+
#
|
|
1049
|
+
# @param [RubyLint::Docstring::ParamTag] tag
|
|
1050
|
+
# @param [RubyLint::Definition::RubyObject] definition
|
|
1051
|
+
#
|
|
1052
|
+
def update_parents_from_tag(tag, definition)
|
|
1053
|
+
extra_parents = definitions_for_types(tag.types)
|
|
1054
|
+
|
|
1055
|
+
definition.parents.concat(extra_parents)
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
##
|
|
1059
|
+
# Creates an "unknown" definition with the given method in it.
|
|
1060
|
+
#
|
|
1061
|
+
# @param [String] name The name of the method to add.
|
|
1062
|
+
# @return [RubyLint::Definition::RubyObject]
|
|
1063
|
+
#
|
|
1064
|
+
def create_unknown_with_method(name)
|
|
1065
|
+
definition = Definition::RubyObject.create_unknown
|
|
1066
|
+
|
|
1067
|
+
definition.send("define_#{@method_type}", name)
|
|
1068
|
+
|
|
1069
|
+
return definition
|
|
1070
|
+
end
|
|
1071
|
+
|
|
1072
|
+
##
|
|
1073
|
+
# Returns a collection of definitions for a set of YARD types.
|
|
1074
|
+
#
|
|
1075
|
+
# @param [Array] types
|
|
1076
|
+
# @return [Array]
|
|
1077
|
+
#
|
|
1078
|
+
def definitions_for_types(types)
|
|
1079
|
+
definitions = []
|
|
1080
|
+
|
|
1081
|
+
# There are basically two type signatures: either the name(s) of a
|
|
1082
|
+
# constant or a method in the form of `#method_name`.
|
|
1083
|
+
types.each do |type|
|
|
1084
|
+
if type[0] == '#'
|
|
1085
|
+
found = create_unknown_with_method(type[1..-1])
|
|
1086
|
+
else
|
|
1087
|
+
found = lookup_type_definition(type)
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
definitions << found if found
|
|
1091
|
+
end
|
|
1092
|
+
|
|
1093
|
+
return definitions
|
|
1094
|
+
end
|
|
1095
|
+
|
|
1096
|
+
##
|
|
1097
|
+
# Tries to look up the given type/constant in the current scope and falls
|
|
1098
|
+
# back to the global scope if it couldn't be found in the former.
|
|
1099
|
+
#
|
|
1100
|
+
# @param [String] name
|
|
1101
|
+
# @return [RubyLint::Definition::RubyObject]
|
|
1102
|
+
#
|
|
1103
|
+
def lookup_type_definition(name)
|
|
1104
|
+
return current_scope.lookup(:const, name) ||
|
|
1105
|
+
GlobalScope.global_constant(name)
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
##
|
|
1109
|
+
# @param [RubyLint::Docstring::ReturnTag] tag
|
|
1110
|
+
# @param [RubyLint::Definition::RubyMethod] definition
|
|
1111
|
+
#
|
|
1112
|
+
def assign_return_value_from_tag(tag, definition)
|
|
1113
|
+
definitions = definitions_for_types(tag.types)
|
|
1114
|
+
|
|
1115
|
+
# THINK: currently ruby-lint assumes methods always return a single type
|
|
1116
|
+
# but YARD allows you to specify multiple ones. For now we'll take the
|
|
1117
|
+
# first one but there should be a nicer way to do this.
|
|
1118
|
+
definition.returns(definitions[0]) if definitions[0]
|
|
1119
|
+
end
|
|
1043
1120
|
end # VirtualMachine
|
|
1044
1121
|
end # RubyLint
|