Skip to content

Commit 87c31ae

Browse files
committed
Handling inline visibility modifiers
1 parent ba11ee9 commit 87c31ae

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

lib/empirical/attr_processor.rb

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,26 @@
99
# syntax could work...
1010
class Empirical::AttrProcessor < Empirical::BaseProcessor
1111
ATTR_METHODS = Set[:attr_accessor, :attr_reader, :attr_writer].freeze
12+
VISIBILITY_METHODS = Set[:private, :protected, :public].freeze
1213

1314
def visit_call_node(node)
14-
if ATTR_METHODS.include?(node.name)
15+
# Check if this is a visibility modifier wrapping an attr call, we need it for oua generated methods
16+
if VISIBILITY_METHODS.include?(node.name) && node.arguments
17+
arg = node.arguments.arguments.first
18+
if arg.is_a?(Prism::CallNode) && ATTR_METHODS.include?(arg.name)
19+
visit_attr_call_node(arg, visibility: node.name)
20+
end
21+
# TODO: We don't call super because we have effectively handled the modifier ourselves
22+
# ... though the original methods visibility is now not set correct?
23+
return
24+
elsif ATTR_METHODS.include?(node.name)
1525
visit_attr_call_node(node)
1626
end
1727

1828
super
1929
end
2030

21-
def visit_attr_call_node(node)
31+
def visit_attr_call_node(node, visibility: nil)
2232
# TODO: improve errors, as per `fun`
2333
raise SyntaxError unless node.arguments
2434
raise SyntaxError if node.receiver
@@ -62,9 +72,9 @@ def visit_attr_call_node(node)
6272
# TODO: here we check on read for attr_readre and on write for writer/accessor, makes sense?
6373
case node.name
6474
when :attr_reader
65-
post_end_buffer << typed_getter(attr_name, attr_type_ident)
75+
post_end_buffer << typed_getter(attr_name, attr_type_ident, visibility)
6676
when :attr_writer, :attr_accessor
67-
post_end_buffer << typed_setter(attr_name, attr_type_ident)
77+
post_end_buffer << typed_setter(attr_name, attr_type_ident, visibility)
6878
end
6979
end
7080

@@ -94,12 +104,16 @@ def extract_typed_attrs_from_hash(elements)
94104
end
95105

96106
# TODO: readability!
97-
def typed_getter(attr_name, type_ident)
98-
"alias_method(:__original_#{attr_name}, :#{attr_name});def #{attr_name};__value = __original_#{attr_name};raise(::Empirical::TypeError.attr_type_error(name: '#{attr_name}', value: __value, expected: ::Empirical::TypeStore::#{type_ident}, attr_type: 'reader', context: self)) unless ::Empirical::TypeStore::#{type_ident} === __value;__value;end"
107+
def typed_getter(attr_name, type_ident, visibility = nil)
108+
code = "alias_method(:__original_#{attr_name}, :#{attr_name});def #{attr_name};__value = __original_#{attr_name};raise(::Empirical::TypeError.attr_type_error(name: '#{attr_name}', value: __value, expected: ::Empirical::TypeStore::#{type_ident}, attr_type: 'reader', context: self)) unless ::Empirical::TypeStore::#{type_ident} === __value;__value;end"
109+
code += ";#{visibility} :#{attr_name}" if visibility
110+
code
99111
end
100112

101-
def typed_setter(attr_name, type_ident)
102-
"alias_method(:__original_#{attr_name}=, :#{attr_name}=);def #{attr_name}=(value);raise(::Empirical::TypeError.attr_type_error(name: '#{attr_name}', value: value, expected: ::Empirical::TypeStore::#{type_ident}, attr_type: 'writer', context: self)) unless ::Empirical::TypeStore::#{type_ident} === value;send(:__original_#{attr_name}=, value);end"
113+
def typed_setter(attr_name, type_ident, visibility = nil)
114+
code = "alias_method(:__original_#{attr_name}=, :#{attr_name}=);def #{attr_name}=(value);raise(::Empirical::TypeError.attr_type_error(name: '#{attr_name}', value: value, expected: ::Empirical::TypeStore::#{type_ident}, attr_type: 'writer', context: self)) unless ::Empirical::TypeStore::#{type_ident} === value;send(:__original_#{attr_name}=, value);end"
115+
code += ";#{visibility} :#{attr_name}=" if visibility
116+
code
103117
end
104118

105119
# TODO: duplication

0 commit comments

Comments
 (0)