ruby-lint 0.0.5 → 0.9.0
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 +4 -4
- checksums.yaml.gz.asc +14 -14
- data/.gitignore +1 -0
- data/.yardopts +1 -1
- data/Gemfile +3 -3
- data/MANIFEST +16 -3
- data/benchmark/virtual_machine.rb +17 -0
- data/checksum/ruby-lint-0.0.5.gem.sha512 +1 -0
- data/doc/changelog.md +42 -0
- data/doc/configuration.md +133 -13
- data/lib/ruby-lint/analysis/shadowing_variables.rb +8 -14
- data/lib/ruby-lint/analysis/unused_variables.rb +17 -0
- data/lib/ruby-lint/ast/node.rb +18 -3
- data/lib/ruby-lint/cache.rb +121 -0
- data/lib/ruby-lint/cache_entry.rb +44 -0
- data/lib/ruby-lint/cli/analyze.rb +37 -18
- data/lib/ruby-lint/cli/plot.rb +94 -0
- data/lib/ruby-lint/cli.rb +1 -0
- data/lib/ruby-lint/configuration.rb +48 -3
- data/lib/ruby-lint/definition/ruby_method.rb +28 -1
- data/lib/ruby-lint/definition/ruby_object.rb +37 -3
- data/lib/ruby-lint/definition_builder/ruby_method.rb +4 -1
- data/lib/ruby-lint/definition_builder/ruby_module.rb +4 -1
- data/lib/ruby-lint/definition_generator.rb +3 -2
- data/lib/ruby-lint/definitions/core/arg0.rb +3 -1
- data/lib/ruby-lint/definitions/core/argf.rb +3 -1
- data/lib/ruby-lint/definitions/core/argument_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/argv.rb +3 -1
- data/lib/ruby-lint/definitions/core/array.rb +3 -1
- data/lib/ruby-lint/definitions/core/autoload.rb +3 -1
- data/lib/ruby-lint/definitions/core/basic_object.rb +2 -0
- data/lib/ruby-lint/definitions/core/bignum.rb +3 -1
- data/lib/ruby-lint/definitions/core/binding.rb +3 -1
- data/lib/ruby-lint/definitions/core/class.rb +2 -0
- data/lib/ruby-lint/definitions/core/comparable.rb +3 -1
- data/lib/ruby-lint/definitions/core/complex.rb +3 -1
- data/lib/ruby-lint/definitions/core/condition_variable.rb +3 -1
- data/lib/ruby-lint/definitions/core/continuation.rb +3 -1
- data/lib/ruby-lint/definitions/core/data.rb +3 -1
- data/lib/ruby-lint/definitions/core/date.rb +3 -1
- data/lib/ruby-lint/definitions/core/date_time.rb +3 -1
- data/lib/ruby-lint/definitions/core/default_record_separator.rb +3 -1
- data/lib/ruby-lint/definitions/core/digest.rb +3 -1
- data/lib/ruby-lint/definitions/core/dir.rb +3 -1
- data/lib/ruby-lint/definitions/core/encoding.rb +3 -1
- data/lib/ruby-lint/definitions/core/encoding_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/enumerable.rb +3 -1
- data/lib/ruby-lint/definitions/core/enumerator.rb +3 -1
- data/lib/ruby-lint/definitions/core/env.rb +4 -1
- data/lib/ruby-lint/definitions/core/eoferror.rb +3 -1
- data/lib/ruby-lint/definitions/core/erb.rb +2 -0
- data/lib/ruby-lint/definitions/core/errno.rb +3 -1
- data/lib/ruby-lint/definitions/core/etc.rb +3 -1
- data/lib/ruby-lint/definitions/core/exception.rb +3 -1
- data/lib/ruby-lint/definitions/core/false.rb +3 -1
- data/lib/ruby-lint/definitions/core/false_class.rb +3 -1
- data/lib/ruby-lint/definitions/core/fatal_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/fiber.rb +3 -1
- data/lib/ruby-lint/definitions/core/fiber_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/file.rb +3 -1
- data/lib/ruby-lint/definitions/core/file_list.rb +3 -1
- data/lib/ruby-lint/definitions/core/file_test.rb +3 -1
- data/lib/ruby-lint/definitions/core/file_utils.rb +3 -1
- data/lib/ruby-lint/definitions/core/fixnum.rb +3 -1
- data/lib/ruby-lint/definitions/core/float.rb +3 -1
- data/lib/ruby-lint/definitions/core/float_domain_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/gc.rb +3 -1
- data/lib/ruby-lint/definitions/core/gem.rb +3 -1
- data/lib/ruby-lint/definitions/core/hash.rb +3 -1
- data/lib/ruby-lint/definitions/core/immediate_value.rb +3 -1
- data/lib/ruby-lint/definitions/core/index_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/integer.rb +3 -1
- data/lib/ruby-lint/definitions/core/interrupt.rb +3 -1
- data/lib/ruby-lint/definitions/core/io.rb +3 -1
- data/lib/ruby-lint/definitions/core/ioerror.rb +3 -1
- data/lib/ruby-lint/definitions/core/kernel.rb +2 -0
- data/lib/ruby-lint/definitions/core/key_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/load_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/local_jump_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/marshal.rb +3 -1
- data/lib/ruby-lint/definitions/core/match_data.rb +3 -1
- data/lib/ruby-lint/definitions/core/math.rb +3 -1
- data/lib/ruby-lint/definitions/core/memory_segmention_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/method.rb +3 -1
- data/lib/ruby-lint/definitions/core/module.rb +2 -0
- data/lib/ruby-lint/definitions/core/monitor.rb +3 -1
- data/lib/ruby-lint/definitions/core/monitor_mixin.rb +3 -1
- data/lib/ruby-lint/definitions/core/mutex.rb +3 -1
- data/lib/ruby-lint/definitions/core/name_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/nil.rb +3 -1
- data/lib/ruby-lint/definitions/core/nil_class.rb +3 -1
- data/lib/ruby-lint/definitions/core/no_memory_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/no_method_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/not_implemented_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/numeric.rb +3 -1
- data/lib/ruby-lint/definitions/core/object.rb +3 -1
- data/lib/ruby-lint/definitions/core/object_space.rb +3 -1
- data/lib/ruby-lint/definitions/core/open_struct.rb +3 -1
- data/lib/ruby-lint/definitions/core/option_parser.rb +3 -1
- data/lib/ruby-lint/definitions/core/precision.rb +3 -1
- data/lib/ruby-lint/definitions/core/primitive_failure.rb +3 -1
- data/lib/ruby-lint/definitions/core/proc.rb +3 -1
- data/lib/ruby-lint/definitions/core/process.rb +3 -1
- data/lib/ruby-lint/definitions/core/queue.rb +3 -1
- data/lib/ruby-lint/definitions/core/rake.rb +3 -1
- data/lib/ruby-lint/definitions/core/rake_file_utils.rb +3 -1
- data/lib/ruby-lint/definitions/core/rakeversion.rb +3 -1
- data/lib/ruby-lint/definitions/core/random.rb +3 -1
- data/lib/ruby-lint/definitions/core/range.rb +3 -1
- data/lib/ruby-lint/definitions/core/range_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/rational.rb +3 -1
- data/lib/ruby-lint/definitions/core/rb_config.rb +3 -1
- data/lib/ruby-lint/definitions/core/regexp.rb +3 -1
- data/lib/ruby-lint/definitions/core/regexp_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_copyright.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_description.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_engine.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_patchlevel.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_platform.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_release_date.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_version.rb +3 -1
- data/lib/ruby-lint/definitions/core/runtime_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/scan_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/script_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/security_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/shellwords.rb +3 -1
- data/lib/ruby-lint/definitions/core/signal.rb +3 -1
- data/lib/ruby-lint/definitions/core/signal_exception.rb +3 -1
- data/lib/ruby-lint/definitions/core/singleton.rb +3 -1
- data/lib/ruby-lint/definitions/core/sized_queue.rb +3 -1
- data/lib/ruby-lint/definitions/core/standard_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/stderr.rb +2 -0
- data/lib/ruby-lint/definitions/core/stdin.rb +2 -0
- data/lib/ruby-lint/definitions/core/stdout.rb +2 -0
- data/lib/ruby-lint/definitions/core/stop_iteration.rb +3 -1
- data/lib/ruby-lint/definitions/core/string.rb +3 -1
- data/lib/ruby-lint/definitions/core/string_io.rb +3 -1
- data/lib/ruby-lint/definitions/core/string_scanner.rb +3 -1
- data/lib/ruby-lint/definitions/core/struct.rb +3 -1
- data/lib/ruby-lint/definitions/core/syck.rb +3 -1
- data/lib/ruby-lint/definitions/core/symbol.rb +3 -1
- data/lib/ruby-lint/definitions/core/syntax_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/system_call_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/system_exit.rb +3 -1
- data/lib/ruby-lint/definitions/core/system_stack_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/thread.rb +3 -1
- data/lib/ruby-lint/definitions/core/thread_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/thread_group.rb +3 -1
- data/lib/ruby-lint/definitions/core/time.rb +3 -1
- data/lib/ruby-lint/definitions/core/toplevel_binding.rb +3 -1
- data/lib/ruby-lint/definitions/core/true.rb +3 -1
- data/lib/ruby-lint/definitions/core/true_class.rb +3 -1
- data/lib/ruby-lint/definitions/core/type_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/unbound_method.rb +3 -1
- data/lib/ruby-lint/definitions/core/unmarshalable.rb +3 -1
- data/lib/ruby-lint/definitions/core/unsupported_library_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/weak_ref.rb +3 -1
- data/lib/ruby-lint/definitions/core/yaml.rb +1 -0
- data/lib/ruby-lint/definitions/core/zero_division_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/zlib.rb +8840 -0
- data/lib/ruby-lint/definitions/rails/abstract_controller.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_controller.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_dispatch.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_mailer.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_pack.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_view.rb +1 -0
- data/lib/ruby-lint/definitions/rails/active_model.rb +1 -0
- data/lib/ruby-lint/definitions/rails/active_record.rb +1 -0
- data/lib/ruby-lint/definitions/rails/active_support.rb +1 -0
- data/lib/ruby-lint/definitions/rails/arel.rb +1 -0
- data/lib/ruby-lint/definitions/rails/rails.rb +1 -0
- data/lib/ruby-lint/definitions/rails/sprockets.rb +1 -0
- data/lib/ruby-lint/file_scanner.rb +2 -0
- data/lib/ruby-lint/iterator.rb +21 -12
- data/lib/ruby-lint/method_call_info.rb +31 -0
- data/lib/ruby-lint/node_hash.rb +105 -0
- data/lib/ruby-lint/parser.rb +4 -2
- data/lib/ruby-lint/runner.rb +62 -6
- data/lib/ruby-lint/template/definition.erb +2 -0
- data/lib/ruby-lint/version.rb +1 -1
- data/lib/ruby-lint/virtual_machine.rb +75 -43
- data/lib/ruby-lint.rb +20 -2
- data/profiling/virtual_machine.rb +20 -0
- data/ruby-lint.gemspec +2 -1
- data/spec/fixtures/complex/rcap.rb +29 -0
- data/spec/fixtures/complex/slop.rb +21 -0
- data/spec/fixtures/file_scanner/lib/ruby-lint/definition/constant_proxy.rb +6 -0
- data/spec/fixtures/file_scanner/lib/ruby-lint/global_scope.rb +6 -0
- data/spec/ruby-lint/analysis/unused_variables_spec.rb +114 -0
- data/spec/ruby-lint/cache_entry_spec.rb +25 -0
- data/spec/ruby-lint/cache_spec.rb +53 -0
- data/spec/ruby-lint/definition/ruby_method_spec.rb +4 -4
- data/spec/ruby-lint/definition/ruby_object_spec.rb +33 -0
- data/spec/ruby-lint/iterator_spec.rb +15 -0
- data/spec/ruby-lint/node_hash_spec.rb +56 -0
- data/spec/ruby-lint/runner_spec.rb +6 -1
- data/spec/ruby-lint/virtual_machine/assignments/variables_spec.rb +2 -2
- data/spec/ruby-lint/virtual_machine/location_spec.rb +64 -0
- data/spec/ruby-lint/virtual_machine/method_call_tracking_spec.rb +64 -0
- data/spec/spec_helper.rb +7 -0
- data/task/generate.rake +1 -1
- data.tar.gz.asc +14 -14
- metadata +34 -7
- metadata.gz.asc +14 -14
- data/debug/memory_usage.rb +0 -14
- data/debug/profile.rb +0 -18
- data/task/profile.rake +0 -27
|
@@ -11793,3 +11793,4 @@ RubyLint::GlobalScope.definitions.define_constant('ActiveRecord::WrappedDatabase
|
|
|
11793
11793
|
end
|
|
11794
11794
|
end
|
|
11795
11795
|
|
|
11796
|
+
RubyLint::GlobalScope.definitions.lookup(:const, 'ActiveRecord').deep_freeze
|
data/lib/ruby-lint/iterator.rb
CHANGED
|
@@ -50,7 +50,13 @@ module RubyLint
|
|
|
50
50
|
# the specified node (`throw` calls bubble up regardless of `catch` calls,
|
|
51
51
|
# unlike when using `begin/rescue`).
|
|
52
52
|
#
|
|
53
|
+
# @!attribute [r] arity_cache Hash containing the amount of arguments for
|
|
54
|
+
# each method.
|
|
55
|
+
# @return [Hash]
|
|
56
|
+
#
|
|
53
57
|
class Iterator
|
|
58
|
+
attr_reader :arity_cache
|
|
59
|
+
|
|
54
60
|
##
|
|
55
61
|
# @param [Hash] options Hash containing custom options to set for the
|
|
56
62
|
# iterator.
|
|
@@ -61,6 +67,8 @@ module RubyLint
|
|
|
61
67
|
end
|
|
62
68
|
|
|
63
69
|
after_initialize if respond_to?(:after_initialize)
|
|
70
|
+
|
|
71
|
+
@arity_cache = {}
|
|
64
72
|
end
|
|
65
73
|
|
|
66
74
|
##
|
|
@@ -72,8 +80,9 @@ module RubyLint
|
|
|
72
80
|
def iterate(node)
|
|
73
81
|
return unless node.is_a?(AST::Node)
|
|
74
82
|
|
|
75
|
-
before
|
|
76
|
-
|
|
83
|
+
before = :"on_#{node.type}"
|
|
84
|
+
after = :"after_#{node.type}"
|
|
85
|
+
skip_node = catch :skip_child_nodes do
|
|
77
86
|
execute_callback(before, node)
|
|
78
87
|
end
|
|
79
88
|
|
|
@@ -104,17 +113,17 @@ module RubyLint
|
|
|
104
113
|
# @param [Array] args Arguments to pass to the callback method.
|
|
105
114
|
#
|
|
106
115
|
def execute_callback(name, *args)
|
|
107
|
-
|
|
108
|
-
end
|
|
116
|
+
return unless respond_to?(name)
|
|
109
117
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
unless arity_cache.key?(name)
|
|
119
|
+
arity_cache[name] = method(name).arity
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
if arity_cache[name] == 0
|
|
123
|
+
send(name)
|
|
124
|
+
else
|
|
125
|
+
send(name, *args)
|
|
126
|
+
end
|
|
118
127
|
end
|
|
119
128
|
end # Iterator
|
|
120
129
|
end # RubyLint
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module RubyLint
|
|
2
|
+
##
|
|
3
|
+
# The MethodCallInfo class stores basic information about method calls such
|
|
4
|
+
# as the definition of the method and location information of the method
|
|
5
|
+
# call.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] definition
|
|
8
|
+
# @return [RubyLint::Definition::RubyMethod]
|
|
9
|
+
#
|
|
10
|
+
# @!attribute [r] line
|
|
11
|
+
# @return [Numeric] The line of the method call.
|
|
12
|
+
#
|
|
13
|
+
# @!attribute [r] column
|
|
14
|
+
# @return [Numeric] The column of the method call.
|
|
15
|
+
#
|
|
16
|
+
# @!attribute [r] file
|
|
17
|
+
# @return [String] The file of the method call.
|
|
18
|
+
#
|
|
19
|
+
class MethodCallInfo
|
|
20
|
+
attr_reader :definition, :line, :column, :file
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# @param [Hash] options
|
|
24
|
+
#
|
|
25
|
+
def initialize(options = {})
|
|
26
|
+
options.each do |key, value|
|
|
27
|
+
instance_variable_set("@#{key}", value) if respond_to?(key)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end # MethodCallInfo
|
|
31
|
+
end # RubyLint
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
module RubyLint
|
|
2
|
+
##
|
|
3
|
+
# The NodeHash class is used to store information about {RubyLint::AST::Node}
|
|
4
|
+
# instances based on their SHA1 hashes. It's primarily used by
|
|
5
|
+
# {RubyLint::Runner} to store nodes and their associated comments.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] hash
|
|
8
|
+
# @return [Hash]
|
|
9
|
+
#
|
|
10
|
+
class NodeHash
|
|
11
|
+
attr_reader :hash
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Creates a new instance from a regular Hash.
|
|
15
|
+
#
|
|
16
|
+
# @param [Hash] hash
|
|
17
|
+
# @return [RubyLint::NodeHash]
|
|
18
|
+
#
|
|
19
|
+
def self.from_hash(hash)
|
|
20
|
+
converted = {}
|
|
21
|
+
|
|
22
|
+
hash.each do |key, value|
|
|
23
|
+
converted[key.sha1] = value
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
return new(converted)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# @param [Hash] hash
|
|
31
|
+
#
|
|
32
|
+
def initialize(hash = {})
|
|
33
|
+
@hash = hash
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Returns the value associated with the given node.
|
|
38
|
+
#
|
|
39
|
+
# @param [RubyLint::AST::Node] node
|
|
40
|
+
# @return [Mixed]
|
|
41
|
+
#
|
|
42
|
+
def [](node)
|
|
43
|
+
return @hash[node.sha1]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# Checks if there's a value stored for the node.
|
|
48
|
+
#
|
|
49
|
+
# @param [RubyLint::AST::Node] node
|
|
50
|
+
# @return [TrueClass|FalseClass]
|
|
51
|
+
#
|
|
52
|
+
def key?(node)
|
|
53
|
+
return @hash.key?(node.sha1)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Sets a value for the given node.
|
|
58
|
+
#
|
|
59
|
+
# @param [RubyLint::AST::Node] node
|
|
60
|
+
# @param [Mixed] value
|
|
61
|
+
#
|
|
62
|
+
def []=(node, value)
|
|
63
|
+
return @hash[node.sha1] = value
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
##
|
|
67
|
+
# @return [Array]
|
|
68
|
+
#
|
|
69
|
+
def keys
|
|
70
|
+
return @hash.keys
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
##
|
|
74
|
+
# @return [Array]
|
|
75
|
+
#
|
|
76
|
+
def values
|
|
77
|
+
return @hash.values
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# @return [Array]
|
|
82
|
+
#
|
|
83
|
+
def to_a
|
|
84
|
+
return @hash.to_a
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
##
|
|
88
|
+
# Merges the values of another NodeHash into the current one.
|
|
89
|
+
#
|
|
90
|
+
# @param [RubyLint::NodeHash] other
|
|
91
|
+
#
|
|
92
|
+
def merge!(other)
|
|
93
|
+
@hash.merge!(other.hash)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# Merges a regular Hash into the current NodeHash.
|
|
98
|
+
#
|
|
99
|
+
# @param [Hash] hash
|
|
100
|
+
#
|
|
101
|
+
def merge_hash!(hash)
|
|
102
|
+
merge!(self.class.from_hash(hash))
|
|
103
|
+
end
|
|
104
|
+
end # NodeHash
|
|
105
|
+
end # RubyLint
|
data/lib/ruby-lint/parser.rb
CHANGED
|
@@ -39,11 +39,13 @@ module RubyLint
|
|
|
39
39
|
buffer = ::Parser::Source::Buffer.new(file, line)
|
|
40
40
|
buffer.source = code
|
|
41
41
|
ast, comments = internal_parser.parse_with_comments(buffer)
|
|
42
|
-
associator = ::Parser::Source::Comment::Associator.new(
|
|
42
|
+
associator = ::Parser::Source::Comment::Associator.new(ast, comments)
|
|
43
43
|
|
|
44
44
|
internal_parser.reset
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
root = AST::Node.new(:root, [ast], :location => ast.location)
|
|
47
|
+
|
|
48
|
+
return root, associator.associate
|
|
47
49
|
end
|
|
48
50
|
end # Parser
|
|
49
51
|
end # RubyLint
|
data/lib/ruby-lint/runner.rb
CHANGED
|
@@ -7,14 +7,20 @@ module RubyLint
|
|
|
7
7
|
# @!attribute [r] configuration
|
|
8
8
|
# @return [RubyLint::Configuration]
|
|
9
9
|
#
|
|
10
|
+
# @!attribute [r] cache
|
|
11
|
+
# @return [RubyLint::Cache]
|
|
12
|
+
#
|
|
10
13
|
class Runner
|
|
11
|
-
attr_reader :configuration
|
|
14
|
+
attr_reader :configuration, :cache
|
|
12
15
|
|
|
13
16
|
##
|
|
14
17
|
# @param [RubyLint::Configuration] configuration
|
|
15
18
|
#
|
|
16
19
|
def initialize(configuration)
|
|
17
|
-
@configuration
|
|
20
|
+
@configuration = configuration
|
|
21
|
+
@cache = Cache.new(configuration.cache_directory)
|
|
22
|
+
|
|
23
|
+
@cache.create_directory! if configuration.enable_cache
|
|
18
24
|
end
|
|
19
25
|
|
|
20
26
|
##
|
|
@@ -77,7 +83,9 @@ module RubyLint
|
|
|
77
83
|
# @return [Array]
|
|
78
84
|
#
|
|
79
85
|
def parse_file(parser, file)
|
|
80
|
-
|
|
86
|
+
ast, comments = parser.parse(File.read(file), file)
|
|
87
|
+
|
|
88
|
+
return ast, NodeHash.from_hash(comments)
|
|
81
89
|
end
|
|
82
90
|
|
|
83
91
|
##
|
|
@@ -98,6 +106,10 @@ module RubyLint
|
|
|
98
106
|
# @return [Array]
|
|
99
107
|
#
|
|
100
108
|
def process_external_files(root_ast)
|
|
109
|
+
if cached_values = get_cache(root_ast)
|
|
110
|
+
return cached_values
|
|
111
|
+
end
|
|
112
|
+
|
|
101
113
|
loader = FileLoader.new(
|
|
102
114
|
:directories => configuration.directories,
|
|
103
115
|
:ignore_paths => configuration.ignore_paths,
|
|
@@ -105,16 +117,21 @@ module RubyLint
|
|
|
105
117
|
)
|
|
106
118
|
|
|
107
119
|
nodes = []
|
|
108
|
-
|
|
120
|
+
mtimes = {}
|
|
121
|
+
comments = NodeHash.new
|
|
109
122
|
|
|
110
123
|
loader.iterate(root_ast)
|
|
111
124
|
|
|
112
|
-
loader.nodes.each do |(ast,
|
|
125
|
+
loader.nodes.each do |(ast, comment_associations)|
|
|
113
126
|
nodes << ast
|
|
114
127
|
|
|
115
|
-
|
|
128
|
+
mtimes[ast.file] = File.mtime(ast.file) if configuration.enable_cache
|
|
129
|
+
|
|
130
|
+
comments.merge_hash!(comment_associations)
|
|
116
131
|
end
|
|
117
132
|
|
|
133
|
+
set_cache(root_ast, nodes, comments, mtimes)
|
|
134
|
+
|
|
118
135
|
return nodes, comments
|
|
119
136
|
end
|
|
120
137
|
|
|
@@ -158,5 +175,44 @@ module RubyLint
|
|
|
158
175
|
instance.iterate(ast)
|
|
159
176
|
end
|
|
160
177
|
end
|
|
178
|
+
|
|
179
|
+
##
|
|
180
|
+
# Checks if the AST node has a cache file and if so returns the nodes and
|
|
181
|
+
# comments that are cached.
|
|
182
|
+
#
|
|
183
|
+
# @param [RubyLint::AST::Node] node
|
|
184
|
+
# @return [Array]
|
|
185
|
+
#
|
|
186
|
+
def get_cache(node)
|
|
187
|
+
return unless configuration.enable_cache
|
|
188
|
+
|
|
189
|
+
cache_name = node.sha1
|
|
190
|
+
|
|
191
|
+
if cache.exists?(cache_name)
|
|
192
|
+
entry = cache.get(cache_name)
|
|
193
|
+
|
|
194
|
+
if entry.valid?
|
|
195
|
+
return entry.nodes, entry.comments
|
|
196
|
+
else
|
|
197
|
+
cache.delete(cache_name)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
return
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
##
|
|
205
|
+
# Caches the values for the given node.
|
|
206
|
+
#
|
|
207
|
+
# @param [RubyLint::AST::Node] node
|
|
208
|
+
# @param [Array] nodes
|
|
209
|
+
# @param [RubyLint::NodeHash] comments
|
|
210
|
+
# @param [Hash] mtimes
|
|
211
|
+
#
|
|
212
|
+
def set_cache(node, nodes, comments, mtimes)
|
|
213
|
+
return unless configuration.enable_cache
|
|
214
|
+
|
|
215
|
+
cache.set(node.sha1, CacheEntry.new(nodes, comments, mtimes))
|
|
216
|
+
end
|
|
161
217
|
end # Runner
|
|
162
218
|
end # RubyLint
|
data/lib/ruby-lint/version.rb
CHANGED
|
@@ -195,7 +195,7 @@ module RubyLint
|
|
|
195
195
|
#
|
|
196
196
|
# @param [RubyLint::AST::Node] node
|
|
197
197
|
#
|
|
198
|
-
def on_assign
|
|
198
|
+
def on_assign
|
|
199
199
|
reset_assignment_value
|
|
200
200
|
value_stack.add_stack
|
|
201
201
|
end
|
|
@@ -212,10 +212,10 @@ module RubyLint
|
|
|
212
212
|
value = assignment_value
|
|
213
213
|
end
|
|
214
214
|
|
|
215
|
-
assign_variable(type, name, value)
|
|
215
|
+
assign_variable(type, name, value, node)
|
|
216
216
|
end
|
|
217
217
|
|
|
218
|
-
ASSIGNMENT_TYPES.each do |callback,
|
|
218
|
+
ASSIGNMENT_TYPES.each do |callback, _|
|
|
219
219
|
alias_method :"on_#{callback}", :on_assign
|
|
220
220
|
alias_method :"after_#{callback}", :after_assign
|
|
221
221
|
end
|
|
@@ -259,7 +259,7 @@ module RubyLint
|
|
|
259
259
|
##
|
|
260
260
|
# @param [RubyLint::AST::Node] node
|
|
261
261
|
#
|
|
262
|
-
def on_masgn
|
|
262
|
+
def on_masgn
|
|
263
263
|
add_stacks
|
|
264
264
|
end
|
|
265
265
|
|
|
@@ -267,9 +267,7 @@ module RubyLint
|
|
|
267
267
|
# Processes a mass variable assignment using the stacks created by
|
|
268
268
|
# {#on_masgn}.
|
|
269
269
|
#
|
|
270
|
-
|
|
271
|
-
#
|
|
272
|
-
def after_masgn(node)
|
|
270
|
+
def after_masgn
|
|
273
271
|
variables = variable_stack.pop
|
|
274
272
|
values = value_stack.pop.first
|
|
275
273
|
values = values && values.value ? values.value : []
|
|
@@ -284,16 +282,14 @@ module RubyLint
|
|
|
284
282
|
##
|
|
285
283
|
# @param [RubyLint::AST::Node] node
|
|
286
284
|
#
|
|
287
|
-
def on_or_asgn
|
|
285
|
+
def on_or_asgn
|
|
288
286
|
add_stacks
|
|
289
287
|
end
|
|
290
288
|
|
|
291
289
|
##
|
|
292
290
|
# Processes an `or` assignment in the form of `variable ||= value`.
|
|
293
291
|
#
|
|
294
|
-
|
|
295
|
-
#
|
|
296
|
-
def after_or_asgn(node)
|
|
292
|
+
def after_or_asgn
|
|
297
293
|
variable = variable_stack.pop.first
|
|
298
294
|
value = value_stack.pop.first
|
|
299
295
|
|
|
@@ -305,7 +301,7 @@ module RubyLint
|
|
|
305
301
|
##
|
|
306
302
|
# @param [RubyLint::AST::Node] node
|
|
307
303
|
#
|
|
308
|
-
def on_and_asgn
|
|
304
|
+
def on_and_asgn
|
|
309
305
|
add_stacks
|
|
310
306
|
end
|
|
311
307
|
|
|
@@ -314,7 +310,7 @@ module RubyLint
|
|
|
314
310
|
#
|
|
315
311
|
# @param [RubyLint::AST::Node] node
|
|
316
312
|
#
|
|
317
|
-
def after_and_asgn
|
|
313
|
+
def after_and_asgn
|
|
318
314
|
variable = variable_stack.pop.first
|
|
319
315
|
value = value_stack.pop.first
|
|
320
316
|
|
|
@@ -330,7 +326,7 @@ module RubyLint
|
|
|
330
326
|
|
|
331
327
|
# Creates the callback methods for various variable types such as local
|
|
332
328
|
# variables.
|
|
333
|
-
ASSIGNMENT_TYPES.each do |
|
|
329
|
+
ASSIGNMENT_TYPES.each do |_, type|
|
|
334
330
|
define_method("on_#{type}") do |node|
|
|
335
331
|
increment_reference_amount(node)
|
|
336
332
|
push_variable_value(node)
|
|
@@ -361,9 +357,9 @@ module RubyLint
|
|
|
361
357
|
end
|
|
362
358
|
|
|
363
359
|
##
|
|
364
|
-
#
|
|
360
|
+
# Adds a new stack for Array values.
|
|
365
361
|
#
|
|
366
|
-
def on_array
|
|
362
|
+
def on_array
|
|
367
363
|
value_stack.add_stack
|
|
368
364
|
end
|
|
369
365
|
|
|
@@ -383,9 +379,9 @@ module RubyLint
|
|
|
383
379
|
end
|
|
384
380
|
|
|
385
381
|
##
|
|
386
|
-
#
|
|
382
|
+
# Adds a new stack for Hash values.
|
|
387
383
|
#
|
|
388
|
-
def on_hash
|
|
384
|
+
def on_hash
|
|
389
385
|
value_stack.add_stack
|
|
390
386
|
end
|
|
391
387
|
|
|
@@ -405,18 +401,16 @@ module RubyLint
|
|
|
405
401
|
end
|
|
406
402
|
|
|
407
403
|
##
|
|
408
|
-
#
|
|
404
|
+
# Adds a new value stack for key/value pairs.
|
|
409
405
|
#
|
|
410
|
-
def on_pair
|
|
406
|
+
def on_pair
|
|
411
407
|
value_stack.add_stack
|
|
412
408
|
end
|
|
413
409
|
|
|
414
410
|
##
|
|
415
|
-
#
|
|
416
|
-
#
|
|
417
|
-
# @param [RubyLint::AST::Node] node
|
|
411
|
+
# @see #on_pair
|
|
418
412
|
#
|
|
419
|
-
def after_pair
|
|
413
|
+
def after_pair
|
|
420
414
|
key, value = value_stack.pop
|
|
421
415
|
|
|
422
416
|
return unless key
|
|
@@ -431,9 +425,9 @@ module RubyLint
|
|
|
431
425
|
end
|
|
432
426
|
|
|
433
427
|
##
|
|
434
|
-
#
|
|
428
|
+
# Pushes the value of `self` onto the current stack.
|
|
435
429
|
#
|
|
436
|
-
def on_self
|
|
430
|
+
def on_self
|
|
437
431
|
push_value(current_scope.lookup(:keyword, 'self'))
|
|
438
432
|
end
|
|
439
433
|
|
|
@@ -447,9 +441,9 @@ module RubyLint
|
|
|
447
441
|
end
|
|
448
442
|
|
|
449
443
|
##
|
|
450
|
-
#
|
|
444
|
+
# Pops the scope created by the module.
|
|
451
445
|
#
|
|
452
|
-
def after_module
|
|
446
|
+
def after_module
|
|
453
447
|
pop_scope
|
|
454
448
|
end
|
|
455
449
|
|
|
@@ -474,9 +468,9 @@ module RubyLint
|
|
|
474
468
|
end
|
|
475
469
|
|
|
476
470
|
##
|
|
477
|
-
#
|
|
471
|
+
# Pops the scope created by the class.
|
|
478
472
|
#
|
|
479
|
-
def after_class
|
|
473
|
+
def after_class
|
|
480
474
|
pop_scope
|
|
481
475
|
end
|
|
482
476
|
|
|
@@ -495,9 +489,9 @@ module RubyLint
|
|
|
495
489
|
end
|
|
496
490
|
|
|
497
491
|
##
|
|
498
|
-
#
|
|
492
|
+
# Pops the scope created by the block.
|
|
499
493
|
#
|
|
500
|
-
def after_block
|
|
494
|
+
def after_block
|
|
501
495
|
pop_scope
|
|
502
496
|
end
|
|
503
497
|
|
|
@@ -521,9 +515,10 @@ module RubyLint
|
|
|
521
515
|
end
|
|
522
516
|
|
|
523
517
|
##
|
|
524
|
-
#
|
|
518
|
+
# Pops the scope created by the `sclass` block and resets the method
|
|
519
|
+
# definition/send type.
|
|
525
520
|
#
|
|
526
|
-
def after_sclass
|
|
521
|
+
def after_sclass
|
|
527
522
|
reset_method_type
|
|
528
523
|
pop_scope
|
|
529
524
|
end
|
|
@@ -569,9 +564,7 @@ module RubyLint
|
|
|
569
564
|
##
|
|
570
565
|
# Exports various variables to the outer scope of the method definition.
|
|
571
566
|
#
|
|
572
|
-
|
|
573
|
-
#
|
|
574
|
-
def after_def(node)
|
|
567
|
+
def after_def
|
|
575
568
|
previous = pop_scope
|
|
576
569
|
current = current_scope
|
|
577
570
|
|
|
@@ -584,7 +577,7 @@ module RubyLint
|
|
|
584
577
|
|
|
585
578
|
# Creates callbacks for various argument types such as :arg and :optarg.
|
|
586
579
|
ARGUMENT_TYPES.each do |type|
|
|
587
|
-
define_method("on_#{type}") do
|
|
580
|
+
define_method("on_#{type}") do
|
|
588
581
|
value_stack.add_stack
|
|
589
582
|
end
|
|
590
583
|
|
|
@@ -686,21 +679,24 @@ Received: #{arguments.length}
|
|
|
686
679
|
retval = context.call_method(name)
|
|
687
680
|
|
|
688
681
|
retval ? push_value(retval) : push_unknown_value
|
|
682
|
+
|
|
683
|
+
# Track the method call
|
|
684
|
+
track_method_call(context, name, node)
|
|
689
685
|
else
|
|
690
686
|
push_unknown_value
|
|
691
687
|
end
|
|
692
688
|
end
|
|
693
689
|
|
|
694
690
|
VISIBILITIES.each do |vis|
|
|
695
|
-
define_method("on_send_#{vis}") do
|
|
691
|
+
define_method("on_send_#{vis}") do
|
|
696
692
|
@visibility = vis
|
|
697
693
|
end
|
|
698
694
|
end
|
|
699
695
|
|
|
700
696
|
##
|
|
701
|
-
#
|
|
697
|
+
# Adds a new value stack for the values of an alias.
|
|
702
698
|
#
|
|
703
|
-
def on_alias
|
|
699
|
+
def on_alias
|
|
704
700
|
value_stack.add_stack
|
|
705
701
|
end
|
|
706
702
|
|
|
@@ -867,8 +863,9 @@ Received: #{arguments.length}
|
|
|
867
863
|
# @param [Symbol] type The type of variable.
|
|
868
864
|
# @param [String] name The name of the variable
|
|
869
865
|
# @param [RubyLint::Definition::RubyObject] value
|
|
866
|
+
# @param [RubyLint::AST::Node] node
|
|
870
867
|
#
|
|
871
|
-
def assign_variable(type, name, value)
|
|
868
|
+
def assign_variable(type, name, value, node)
|
|
872
869
|
existing = current_scope.lookup(type, name)
|
|
873
870
|
ref_amount = existing ? existing.reference_amount + 1 : 0
|
|
874
871
|
variable = Definition::RubyObject.new(
|
|
@@ -876,7 +873,10 @@ Received: #{arguments.length}
|
|
|
876
873
|
:name => name,
|
|
877
874
|
:value => value,
|
|
878
875
|
:instance_type => :instance,
|
|
879
|
-
:reference_amount => ref_amount
|
|
876
|
+
:reference_amount => ref_amount,
|
|
877
|
+
:line => node.line,
|
|
878
|
+
:column => node.column,
|
|
879
|
+
:file => node.file
|
|
880
880
|
)
|
|
881
881
|
|
|
882
882
|
buffer_assignment_value(variable.value)
|
|
@@ -1117,5 +1117,37 @@ Received: #{arguments.length}
|
|
|
1117
1117
|
# first one but there should be a nicer way to do this.
|
|
1118
1118
|
definition.returns(definitions[0]) if definitions[0]
|
|
1119
1119
|
end
|
|
1120
|
+
|
|
1121
|
+
##
|
|
1122
|
+
# Tracks a method call.
|
|
1123
|
+
#
|
|
1124
|
+
# @param [RubyLint::Definition::RubyMethod] definition
|
|
1125
|
+
# @param [String] name
|
|
1126
|
+
# @param [RubyLint::AST::Node] node
|
|
1127
|
+
#
|
|
1128
|
+
def track_method_call(definition, name, node)
|
|
1129
|
+
method = definition.lookup(definition.method_call_type, name)
|
|
1130
|
+
current = current_scope
|
|
1131
|
+
location = {
|
|
1132
|
+
:line => node.line,
|
|
1133
|
+
:column => node.column,
|
|
1134
|
+
:file => node.file
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
# Add the call to the current scope if we're dealing with a writable
|
|
1138
|
+
# method definition.
|
|
1139
|
+
if current.respond_to?(:calls) and !current.frozen?
|
|
1140
|
+
current.calls.push(
|
|
1141
|
+
MethodCallInfo.new(location.merge(:definition => method))
|
|
1142
|
+
)
|
|
1143
|
+
end
|
|
1144
|
+
|
|
1145
|
+
# Add the caller to the called method, this allows for inverse lookups.
|
|
1146
|
+
unless method.frozen?
|
|
1147
|
+
method.callers.push(
|
|
1148
|
+
MethodCallInfo.new(location.merge(:definition => definition))
|
|
1149
|
+
)
|
|
1150
|
+
end
|
|
1151
|
+
end
|
|
1120
1152
|
end # VirtualMachine
|
|
1121
1153
|
end # RubyLint
|