rigortype 0.4.3 → 0.4.4
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
- data/README.md +1 -1
- data/data/core_overlay/ostruct.rbs +40 -0
- data/docs/handbook/11-sig-gen.md +16 -0
- data/docs/manual/02-cli-reference.md +4 -3
- data/docs/manual/03-configuration.md +16 -5
- data/docs/manual/04-diagnostics.md +44 -2
- data/docs/manual/07-plugins.md +1 -1
- data/docs/manual/10-mcp-server.md +32 -3
- data/docs/manual/18-removing-dead-code.md +11 -1
- data/docs/manual/plugins/rigor-rails-routes.md +2 -2
- data/docs/manual/plugins/rigor-shoulda-matchers.md +4 -1
- data/exe/rigor +12 -17
- data/lib/rigor/analysis/check_rules/rule_ids.rb +57 -0
- data/lib/rigor/analysis/check_rules.rb +46 -36
- data/lib/rigor/analysis/incremental.rb +12 -0
- data/lib/rigor/analysis/incremental_session.rb +121 -21
- data/lib/rigor/analysis/reachability/graph.rb +23 -3
- data/lib/rigor/analysis/reachability/scan.rb +51 -9
- data/lib/rigor/analysis/rule_catalog.rb +6 -1
- data/lib/rigor/analysis/run_cache_key.rb +31 -7
- data/lib/rigor/analysis/run_cache_probe.rb +5 -3
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +48 -12
- data/lib/rigor/analysis/runner/pool_coordinator.rb +110 -15
- data/lib/rigor/analysis/runner/project_pre_passes.rb +29 -4
- data/lib/rigor/analysis/runner.rb +35 -9
- data/lib/rigor/analysis/severity_stamp.rb +34 -1
- data/lib/rigor/analysis/worker_session.rb +57 -1
- data/lib/rigor/cache/descriptor.rb +40 -6
- data/lib/rigor/cache/incremental_snapshot.rb +20 -4
- data/lib/rigor/cli/mcp_command.rb +1 -1
- data/lib/rigor/config_audit.rb +111 -15
- data/lib/rigor/configuration/dependencies.rb +19 -11
- data/lib/rigor/environment/rbs_loader.rb +46 -10
- data/lib/rigor/inference/block_call_timing.rb +5 -0
- data/lib/rigor/inference/captured_locals.rb +26 -3
- data/lib/rigor/inference/definer_resolution.rb +16 -7
- data/lib/rigor/inference/expression_typer.rb +59 -4
- data/lib/rigor/inference/guard_rebinding.rb +7 -2
- data/lib/rigor/inference/last_line/self_evidence.rb +1 -1
- data/lib/rigor/inference/module_function_state.rb +80 -13
- data/lib/rigor/inference/narrowing.rb +184 -68
- data/lib/rigor/inference/reflective_ivar_write.rb +116 -0
- data/lib/rigor/inference/repeated_or_writes.rb +414 -1
- data/lib/rigor/inference/scope_indexer.rb +439 -70
- data/lib/rigor/inference/self_call_ivar_writes.rb +341 -0
- data/lib/rigor/inference/statement_evaluator.rb +84 -29
- data/lib/rigor/lens/anchor.rb +3 -3
- data/lib/rigor/lens/contract_reader.rb +15 -0
- data/lib/rigor/lens/document.rb +2 -2
- data/lib/rigor/lens/file_reader.rb +442 -73
- data/lib/rigor/lens/members.rb +65 -15
- data/lib/rigor/lens/run.rb +44 -2
- data/lib/rigor/lens.rb +2 -1
- data/lib/rigor/mcp/server.rb +61 -20
- data/lib/rigor/plugin/box_probe.rb +154 -7
- data/lib/rigor/project_environment.rb +6 -3
- data/lib/rigor/scope.rb +11 -6
- data/lib/rigor/sig_gen/layout_index.rb +36 -0
- data/lib/rigor/sig_gen/method_candidate.rb +8 -0
- data/lib/rigor/sig_gen/path_mapper.rb +18 -2
- data/lib/rigor/sig_gen/writer.rb +47 -34
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +5 -1
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +5 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/discoverer.rb +28 -6
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +1 -1
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +5 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +155 -12
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +10 -8
- metadata +4 -1
|
@@ -321,6 +321,37 @@ module Rigor
|
|
|
321
321
|
try_project_singleton_inference(receiver, node, arg_types, method_name: :[])
|
|
322
322
|
end
|
|
323
323
|
|
|
324
|
+
# Issue #1889 — the type a block-form `inject` / `reduce` accumulator parameter holds across the block's runs,
|
|
325
|
+
# or nil when the call is not one {#try_block_inject_fold} folds. The RBS tier binds the parameter to the seed
|
|
326
|
+
# alone, so the statement pass and the ADR-56 write-back typed every run's accumulator as `0` for `inject(0)`,
|
|
327
|
+
# and a capture assigned from it (`m = a`) was written back as `0`.
|
|
328
|
+
#
|
|
329
|
+
# The fold records the answer as it types the call ({#record_inject_accumulator}): the constant arm the
|
|
330
|
+
# accumulator values the block receives (`0 | 1` for `[1, 2].inject(0) { |a, e| a + e }`), the nominal
|
|
331
|
+
# arm its seed joined with the converged accumulator. The statement pass types the call from the same scope
|
|
332
|
+
# just before it enters the block, so the recorded answer is read back rather than computed again — each
|
|
333
|
+
# computation types the body, and a nested `inject` multiplied that by its depth.
|
|
334
|
+
def inject_accumulator_type(call_node, receiver, arg_types)
|
|
335
|
+
block = call_node.block
|
|
336
|
+
return nil unless INJECT_METHODS.include?(call_node.name) && block.is_a?(Prism::BlockNode)
|
|
337
|
+
|
|
338
|
+
recorded = self.class.recorded_inject_accumulator(block, scope)
|
|
339
|
+
return recorded if recorded
|
|
340
|
+
|
|
341
|
+
try_block_inject_fold(call_node, receiver, arg_types)
|
|
342
|
+
self.class.recorded_inject_accumulator(block, scope)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
INJECT_ACCUMULATOR_KEY = :__rigor_inject_accumulator__
|
|
346
|
+
private_constant :INJECT_ACCUMULATOR_KEY
|
|
347
|
+
|
|
348
|
+
# The accumulator type {#record_inject_accumulator} stored for `block` when the call was typed from `scope`
|
|
349
|
+
# itself (by identity), else nil.
|
|
350
|
+
def self.recorded_inject_accumulator(block, scope)
|
|
351
|
+
slot = Thread.current[INJECT_ACCUMULATOR_KEY]&.[](block)
|
|
352
|
+
slot && slot[0].equal?(scope) ? slot[1] : nil
|
|
353
|
+
end
|
|
354
|
+
|
|
324
355
|
# ADR-89 WD2 — the current run's return memo bucket as `{ def_node => [MemoEntry, …] }` (only entries
|
|
325
356
|
# that carry a call descriptor, i.e. every stored entry). Read by the incremental session right after a
|
|
326
357
|
# recording run to harvest each analyzed callee's observed call keys → return descriptors. Returns an
|
|
@@ -1047,12 +1078,15 @@ module Rigor
|
|
|
1047
1078
|
#
|
|
1048
1079
|
# The `case ... in` pattern-matching form (`CaseMatchNode`) and the predicate-less form (`case; when
|
|
1049
1080
|
# c1; ...`) bypass the `===` analysis: pattern matching has richer semantics, and a predicate-less
|
|
1050
|
-
# `case` reduces to a `if c1; ...; elsif c2` chain
|
|
1081
|
+
# `case` reduces to a `if c1; ...; elsif c2` chain. Issue #1495 — like {#type_of_conditional}, that
|
|
1082
|
+
# chain delegates to the statement evaluator, which narrows each arm by its conditions' edges, so
|
|
1083
|
+
# `[case; when x.nil? then "n"; else x end]` reads `"n" | String` as the statement form does.
|
|
1051
1084
|
# Issue #1429 — each arm is typed under the subject's clause narrowing (`Narrowing.case_when_scopes`), the
|
|
1052
1085
|
# scope the statement evaluator runs the arm in: `when Symbol then n` on `n: Integer | Symbol` answers
|
|
1053
1086
|
# `Symbol`, and the `else` arm reads the subject every earlier clause has ruled out.
|
|
1054
1087
|
def type_of_case(node)
|
|
1055
|
-
return type_of_case_simple_union(node) if node.is_a?(Prism::CaseMatchNode)
|
|
1088
|
+
return type_of_case_simple_union(node) if node.is_a?(Prism::CaseMatchNode)
|
|
1089
|
+
return scope.evaluate(node, tracer: tracer).first if node.predicate.nil?
|
|
1056
1090
|
|
|
1057
1091
|
subject_type = type_of(node.predicate)
|
|
1058
1092
|
candidates = []
|
|
@@ -3883,6 +3917,12 @@ module Rigor
|
|
|
3883
3917
|
# default — or `Dynamic` when the shape is open or absent; `**kwrest`, `&block`, and destructured
|
|
3884
3918
|
# positionals bind `Dynamic`. Binding `Dynamic` is monotone-safe (wider in → wider out), so the only
|
|
3885
3919
|
# declines left are the shapes where positional CORRESPONDENCE itself is unknowable.
|
|
3920
|
+
#
|
|
3921
|
+
# The scope carries no `source_path:`: the body is re-typed for call sites in any file, so a rule that
|
|
3922
|
+
# asks "did this file write it?" by comparing `scope.source_path` with census paths answers wrongly
|
|
3923
|
+
# through it. Record a per-file write kind in the census instead, as {ScopeIndexer::CONSTANT_MEMO} does
|
|
3924
|
+
# (#1276). Setting `source_path` here was rejected: plugins read it, and the return memo would become
|
|
3925
|
+
# caller-dependent.
|
|
3886
3926
|
def build_user_method_body_scope(def_node, receiver, arg_types, self_fold_safe: false)
|
|
3887
3927
|
params = def_node.parameters
|
|
3888
3928
|
locals = bind_params_from_call_types(params, arg_types)
|
|
@@ -3893,7 +3933,7 @@ module Rigor
|
|
|
3893
3933
|
# allocated a fresh frozen Scope per field, run per user-method-call inference (ADR-44). The
|
|
3894
3934
|
# discovery index is inherited whole by reference (ADR-53 Track A); the hand-copied per-field list
|
|
3895
3935
|
# this replaces had silently dropped `data_member_layouts` and `discovered_method_visibilities`.
|
|
3896
|
-
Scope.new(
|
|
3936
|
+
body_scope = Scope.new(
|
|
3897
3937
|
environment: scope.environment,
|
|
3898
3938
|
locals: locals.freeze,
|
|
3899
3939
|
self_type: receiver,
|
|
@@ -3911,6 +3951,7 @@ module Rigor
|
|
|
3911
3951
|
# Issue #1358 — the callee runs in a frame of its own ({Scope#with_match_frame}).
|
|
3912
3952
|
match_frame: MatchRebinding::Frame.new(def_node.body, def_node.parameters)
|
|
3913
3953
|
)
|
|
3954
|
+
body_scope.with_repeated_or_writes(RepeatedOrWrites.straight_line_sites(def_node.body, body_scope))
|
|
3914
3955
|
end
|
|
3915
3956
|
|
|
3916
3957
|
# Issue #681 / #707 — the ONE place in `lib/` that answers "what `Module.nesting` was recorded for this
|
|
@@ -5436,13 +5477,25 @@ module Rigor
|
|
|
5436
5477
|
return nil if acc.nil?
|
|
5437
5478
|
|
|
5438
5479
|
captured = inject_captured_bindings(block, rest.map { |value| Type::Combinator.constant_of(value) })
|
|
5480
|
+
received = [acc]
|
|
5439
5481
|
rest.each_with_index do |element_value, position|
|
|
5440
5482
|
acc = inject_constant_step(block, acc, element_value, captured, position)
|
|
5441
5483
|
return nil if acc.nil?
|
|
5484
|
+
|
|
5485
|
+
received << acc
|
|
5442
5486
|
end
|
|
5487
|
+
received.pop if received.size > 1
|
|
5488
|
+
record_inject_accumulator(block, Type::Combinator.union(*received))
|
|
5443
5489
|
acc
|
|
5444
5490
|
end
|
|
5445
5491
|
|
|
5492
|
+
# Records `type` as the accumulator `block` receives when typed from this typer's scope
|
|
5493
|
+
# ({.recorded_inject_accumulator}). The keys are weak, so a finished file's nodes do not stay reachable, and
|
|
5494
|
+
# the values strong, so a record outlives a collection while its node does. Prism nodes compare by identity.
|
|
5495
|
+
def record_inject_accumulator(block, type)
|
|
5496
|
+
(Thread.current[INJECT_ACCUMULATOR_KEY] ||= ObjectSpace::WeakKeyMap.new)[block] = [scope, type].freeze
|
|
5497
|
+
end
|
|
5498
|
+
|
|
5446
5499
|
# Issue #1332 — the #587 (b) captured-block binding ({#captured_block_bindings}) both inject arms lay under
|
|
5447
5500
|
# every step, as the Tuple / Range per-element folds and the per-pair `HashShape` fold do. Without it each
|
|
5448
5501
|
# step reads a captured variable at its entry binding, so a body that rebinds or mutates one (`n += 1`,
|
|
@@ -5550,7 +5603,9 @@ module Rigor
|
|
|
5550
5603
|
result.nil? ? {} : { __inject_acc__: result }
|
|
5551
5604
|
end
|
|
5552
5605
|
)
|
|
5553
|
-
converged[:__inject_acc__] || seed_acc
|
|
5606
|
+
result = converged[:__inject_acc__] || seed_acc
|
|
5607
|
+
record_inject_accumulator(block, Type::Combinator.union(seed_acc, result))
|
|
5608
|
+
result
|
|
5554
5609
|
end
|
|
5555
5610
|
|
|
5556
5611
|
def assemble_per_element_result(method_name, per_position, element_types)
|
|
@@ -223,6 +223,12 @@ module Rigor
|
|
|
223
223
|
end || Type::Combinator.untyped
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
+
# Issue #1596 — true when `name` runs code chosen by name or by a String, or a block or String it is given
|
|
227
|
+
# ({CODE_RUNNING_NAMES}, {BLOCK_OR_CODE_NAMES}), whatever its receiver.
|
|
228
|
+
def code_running_name?(name)
|
|
229
|
+
CODE_RUNNING_NAMES.include?(name) || BLOCK_OR_CODE_NAMES.include?(name)
|
|
230
|
+
end
|
|
231
|
+
|
|
226
232
|
# True when `method_name` on a value of `type` may run foreign code ({.foreign_target?}).
|
|
227
233
|
def type_method_foreign?(type, method_name, scope)
|
|
228
234
|
targets = ProjectMethodOwnership.targets(type)
|
|
@@ -326,8 +332,7 @@ module Rigor
|
|
|
326
332
|
private_class_method :scan, :guarded_ivar_write?, :scan_call, :receiver_targets, :foreign_target?,
|
|
327
333
|
:universal_delegate_foreign?, :method_owner, :deferred_block_call?,
|
|
328
334
|
:compound_write_foreign?,
|
|
329
|
-
:compound_receiver_type, :compound_accessors, :compound_read_type, :variable_type
|
|
330
|
-
:type_method_foreign?
|
|
335
|
+
:compound_receiver_type, :compound_accessors, :compound_read_type, :variable_type
|
|
331
336
|
end
|
|
332
337
|
|
|
333
338
|
module GuardRebinding
|
|
@@ -45,7 +45,7 @@ module Rigor
|
|
|
45
45
|
# `X.send(:define_method, :m, blk)`), whose body may be a block the file wrote anywhere, an eval of a
|
|
46
46
|
# String, whose code may do any of these, and a `const_set`, which may make a class a `class` body reopens;
|
|
47
47
|
# - one name: a `def` of it anywhere (`def self.gets` at the top level defines it on `main`, which
|
|
48
|
-
# {BlockCallTiming.project_defines_anywhere?} does not
|
|
48
|
+
# {BlockCallTiming.project_defines_anywhere?} does not count), and a Symbol or String literal naming it,
|
|
49
49
|
# which a macro may define it through (`def_delegators :@io, :gets`, `attr_reader :gets`,
|
|
50
50
|
# `undef_method :gets`), other than `&:gets` and the first argument of a call that only names a method
|
|
51
51
|
# (`respond_to?(:gets)`, `send(:gets)`).
|
|
@@ -11,8 +11,8 @@ module Rigor
|
|
|
11
11
|
# [#1197](https://github.com/rigortype/rigor/issues/1197)). Four readers used to compute it in four
|
|
12
12
|
# places. They disagree with each other and, in places, with Ruby. Each entry point below reproduces
|
|
13
13
|
# one reader's answer exactly: this module gives the readings one place to live, and does not yet make
|
|
14
|
-
# them agree. A change to one reading lands here, beside the other three.
|
|
15
|
-
#
|
|
14
|
+
# them agree. A change to one reading lands here, beside the other three. An example is the reset a bare
|
|
15
|
+
# `public`, `private` or `protected` makes.
|
|
16
16
|
#
|
|
17
17
|
# - The singleton def-node table (`ScopeIndexer#walk_singleton_body`) reads
|
|
18
18
|
# {.each_singleton_sibling} and {.each_singleton_copy}. A bare call covers the later direct
|
|
@@ -78,23 +78,49 @@ module Rigor
|
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
# The defs a named call copies onto the module's singleton, for the singleton def-node table.
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
81
|
+
# The defs a named call copies onto the module's singleton, for the singleton def-node table. Ruby
|
|
82
|
+
# copies the method in effect at the call (#1550), so a later def of the name redefines only the
|
|
83
|
+
# instance method. This reading approximates that from the body's direct `statements`: it yields
|
|
84
|
+
# `name, def_node` for each Symbol or String argument, where `def_node` is the last receiverless def
|
|
85
|
+
# of that name written as a direct statement before the call.
|
|
86
|
+
#
|
|
87
|
+
# A name declines (nothing is yielded) when no def precedes the call, where Ruby raises `NameError` or
|
|
88
|
+
# copies a def another file may load first, and when a statement after that def and before the call
|
|
89
|
+
# may rebind it in a way this reading cannot name: a def nested in control flow or a block, an `alias`,
|
|
90
|
+
# an `undef`, or a receiverless or `self.` `alias_method`, `define_method`, `attr_*`, `remove_method`
|
|
91
|
+
# or `undef_method` call. Such a call or `alias` with a non-literal name anywhere before the call, even
|
|
92
|
+
# before the def, declines every name. A `module_function def x` argument names nothing here.
|
|
93
|
+
#
|
|
94
|
+
# It does not see `send(:define_method, ...)`, a `define_method` on an explicit module receiver, a
|
|
95
|
+
# `prepend`, another file's singleton defs, or that a `rescue` clause's statements may run after an
|
|
96
|
+
# `ensure` call's (#1969).
|
|
87
97
|
def each_singleton_copy(call, statements)
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
call_start = call.location.start_offset
|
|
99
|
+
in_effect = {}
|
|
100
|
+
statements.each do |stmt|
|
|
101
|
+
next unless stmt.location.end_offset <= call_start
|
|
102
|
+
|
|
103
|
+
if stmt.is_a?(Prism::DefNode)
|
|
104
|
+
in_effect[stmt.name] = stmt if stmt.receiver.nil?
|
|
105
|
+
else
|
|
106
|
+
each_rebound_name(stmt) { |name| in_effect[name] = :unknown }
|
|
107
|
+
end
|
|
90
108
|
end
|
|
91
109
|
call.arguments&.arguments&.each do |arg|
|
|
92
110
|
name = symbol_argument_name(arg)
|
|
93
|
-
def_node = name &&
|
|
94
|
-
yield name, def_node if def_node
|
|
111
|
+
def_node = name && !in_effect.key?(ANY_NAME) && in_effect[name]
|
|
112
|
+
yield name, def_node if def_node.is_a?(Prism::DefNode)
|
|
95
113
|
end
|
|
96
114
|
end
|
|
97
115
|
|
|
116
|
+
# The key {.each_singleton_copy} records when a statement may rebind a name it cannot read.
|
|
117
|
+
ANY_NAME = Object.new.freeze
|
|
118
|
+
|
|
119
|
+
# Calls that may define, alias or remove an instance method of the receiverless module.
|
|
120
|
+
REBINDING_CALLS = %i[
|
|
121
|
+
alias_method define_method attr attr_reader attr_writer attr_accessor remove_method undef_method
|
|
122
|
+
].freeze
|
|
123
|
+
|
|
98
124
|
# The deferred-ranges reading, over one class-ish body's subtree. Appends to `offsets` the start of
|
|
99
125
|
# every bare call; each def that starts after one is a module function
|
|
100
126
|
# ({.deferred_module_function?}). Appends to `ranges` one row per named call, in the table's
|
|
@@ -173,6 +199,46 @@ module Rigor
|
|
|
173
199
|
active && kind == :instance
|
|
174
200
|
end
|
|
175
201
|
|
|
202
|
+
# Yields each instance-method name `node` may rebind on the module whose body holds it, or
|
|
203
|
+
# {ANY_NAME} when one is not a literal. It does not enter a nested class, module or `class <<` body,
|
|
204
|
+
# whose methods belong to another module.
|
|
205
|
+
def each_rebound_name(node, &)
|
|
206
|
+
case node
|
|
207
|
+
when Prism::ClassNode, Prism::ModuleNode, Prism::SingletonClassNode then nil
|
|
208
|
+
when Prism::DefNode then yield node.name if node.receiver.nil?
|
|
209
|
+
else
|
|
210
|
+
each_own_rebound_name(node, &)
|
|
211
|
+
node.compact_child_nodes.each { |child| each_rebound_name(child, &) }
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# The names `node` itself may rebind, apart from its children: an `alias`, an `undef` or a
|
|
216
|
+
# {REBINDING_CALLS} call on the module.
|
|
217
|
+
def each_own_rebound_name(node, &)
|
|
218
|
+
case node
|
|
219
|
+
when Prism::AliasMethodNode then yield symbol_argument_name(node.new_name) || ANY_NAME
|
|
220
|
+
when Prism::UndefNode then node.names.each { |name| yield symbol_argument_name(name) || ANY_NAME }
|
|
221
|
+
when Prism::CallNode
|
|
222
|
+
each_rebinding_call_name(node, &) if REBINDING_CALLS.include?(node.name) &&
|
|
223
|
+
(node.receiver.nil? || node.receiver.is_a?(Prism::SelfNode))
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# The names a {REBINDING_CALLS} call may rebind: the first argument of `alias_method` and
|
|
228
|
+
# `define_method`, every argument of the others (and its writer, for the `attr_*` family), or
|
|
229
|
+
# {ANY_NAME} for a non-literal one.
|
|
230
|
+
def each_rebinding_call_name(call)
|
|
231
|
+
arguments = call.arguments&.arguments || []
|
|
232
|
+
arguments = arguments.first(1) if %i[alias_method define_method].include?(call.name)
|
|
233
|
+
arguments.each do |arg|
|
|
234
|
+
name = symbol_argument_name(arg)
|
|
235
|
+
next yield(ANY_NAME) unless name
|
|
236
|
+
|
|
237
|
+
yield name
|
|
238
|
+
yield :"#{name}=" if call.name.start_with?("attr")
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
176
242
|
# The prescan's call arm.
|
|
177
243
|
def prescan_call(node, qualified_prefix, in_singleton_class, offsets, ranges)
|
|
178
244
|
if bare?(node)
|
|
@@ -208,7 +274,8 @@ module Rigor
|
|
|
208
274
|
Source::Literals.symbol_or_string(arg)
|
|
209
275
|
end
|
|
210
276
|
|
|
211
|
-
private_class_method :prescan_call, :prescan_eval_call, :symbol_argument_name
|
|
277
|
+
private_class_method :prescan_call, :prescan_eval_call, :symbol_argument_name, :each_rebound_name,
|
|
278
|
+
:each_own_rebound_name, :each_rebinding_call_name
|
|
212
279
|
end
|
|
213
280
|
end
|
|
214
281
|
end
|