Class: Audition::Static::Checks::RactorIsolation
- Inherits:
-
Base
- Object
- Prism::Visitor
- Base
- Audition::Static::Checks::RactorIsolation
show all
- Defined in:
- lib/audition/static/checks/ractor_isolation.rb
Overview
Ractor.new verifies block isolation at creation time: a
block that touches locals from the enclosing scope raises
ArgumentError before the Ractor ever runs. Prism records the
resolution depth of every local reference, so captures are
detectable exactly: a reference whose depth reaches past the
Ractor block's own scope is an outer capture.
Ractor.shareable_proc applies a weaker rule to any block at
conversion time: a captured local may not hold an
unshareable object and may not be assigned more than once.
Rails converts the blocks handed to its callback macros the
same way once unshareable_proc_action is set, so a callback
whose capture is provably unshareable is reported too; a
capture of unknown value stays silent, and the boot gate is
its detector.
Defined Under Namespace
Classes: CaptureScanner
Constant Summary
collapse
- CAPTURE_FIX =
"Capture a shareable value: freeze the local (a " \
"frozen literal or .freeze), inline it, or hoist a " \
"shareable leaf such as a Symbol into a fresh local " \
"assigned once before the block."
- CALLBACK_MACROS =
Methods that keep their block for later, as a callback or
boot hook; Rails runs each through try_shareable_proc.
%i[
validate validates_each set_callback on_load initializer
to_prepare rescue_from scope default_scope
].freeze
- CALLBACK_PREFIXES =
%w[
before_ after_ around_ prepend_before_ prepend_after_
prepend_around_ append_before_ append_after_
append_around_
].freeze
- CONVERTERS =
%i[shareable_proc shareable_lambda].freeze
- UNSHAREABLE_KINDS =
Classifications a captured value must have for the
conversion to fail for certain.
%i[
mutable_string mutable_container mutable_call
sync_primitive default_proc proc
].freeze
Constants inherited
from Base
Base::EMPTY_CATALOG, Base::WRAPPER
Instance Attribute Summary
Attributes inherited from Base
#file, #findings
Instance Method Summary
collapse
Methods inherited from Base
call, check_name, explain, explanations, handlers, on
Constructor Details
Returns a new instance of RactorIsolation.
83
84
85
86
87
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 83
def initialize(file)
super
@frames = []
@pending = []
end
|
Instance Method Details
#visit_block_node(node) ⇒ Object
104
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 104
def visit_block_node(node) = framed { super }
|
#visit_call_node(node) ⇒ Object
133
134
135
136
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 133
def visit_call_node(node)
examine(node)
super
end
|
#visit_class_node(node) ⇒ Object
96
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 96
def visit_class_node(node) = framed { super }
|
#visit_def_node(node) ⇒ Object
102
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 102
def visit_def_node(node) = framed { super }
|
#visit_lambda_node(node) ⇒ Object
106
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 106
def visit_lambda_node(node) = framed { super }
|
#visit_local_variable_and_write_node(node) ⇒ Object
123
124
125
126
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 123
def visit_local_variable_and_write_node(node)
assign(node.name, node.depth, nil)
super
end
|
#visit_local_variable_operator_write_node(node) ⇒ Object
118
119
120
121
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 118
def visit_local_variable_operator_write_node(node)
assign(node.name, node.depth, nil)
super
end
|
#visit_local_variable_or_write_node(node) ⇒ Object
113
114
115
116
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 113
def visit_local_variable_or_write_node(node)
assign(node.name, node.depth, nil)
super
end
|
#visit_local_variable_target_node(node) ⇒ Object
128
129
130
131
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 128
def visit_local_variable_target_node(node)
assign(node.name, node.depth, nil)
super
end
|
#visit_local_variable_write_node(node) ⇒ Object
108
109
110
111
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 108
def visit_local_variable_write_node(node)
assign(node.name, node.depth, node.value)
super
end
|
#visit_module_node(node) ⇒ Object
98
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 98
def visit_module_node(node) = framed { super }
|
#visit_program_node(node) ⇒ Object
Captures are judged once the whole file is read: a local
reassigned after the block is refused just the same.
91
92
93
94
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 91
def visit_program_node(node)
framed { super }
@pending.each { |entry| judge(entry) }
end
|
#visit_singleton_class_node(node) ⇒ Object
100
|
# File 'lib/audition/static/checks/ractor_isolation.rb', line 100
def visit_singleton_class_node(node) = framed { super }
|