rupkl 0.1.0 → 0.3.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/rupkl/node/amend_expression.rb +48 -0
  4. data/lib/rupkl/node/any.rb +110 -0
  5. data/lib/rupkl/node/base.rb +75 -0
  6. data/lib/rupkl/node/boolean.rb +30 -5
  7. data/lib/rupkl/node/collection.rb +176 -0
  8. data/lib/rupkl/node/context.rb +27 -0
  9. data/lib/rupkl/node/data_size.rb +254 -0
  10. data/lib/rupkl/node/declared_type.rb +32 -0
  11. data/lib/rupkl/node/duration.rb +266 -0
  12. data/lib/rupkl/node/dynamic.rb +33 -60
  13. data/lib/rupkl/node/identifier.rb +19 -5
  14. data/lib/rupkl/node/if_expression.rb +45 -0
  15. data/lib/rupkl/node/intseq.rb +84 -0
  16. data/lib/rupkl/node/listing.rb +68 -0
  17. data/lib/rupkl/node/map.rb +120 -0
  18. data/lib/rupkl/node/mapping.rb +54 -0
  19. data/lib/rupkl/node/member_finder.rb +49 -0
  20. data/lib/rupkl/node/member_reference.rb +46 -21
  21. data/lib/rupkl/node/method_call.rb +63 -0
  22. data/lib/rupkl/node/method_definition.rb +199 -0
  23. data/lib/rupkl/node/node_common.rb +76 -0
  24. data/lib/rupkl/node/null.rb +24 -0
  25. data/lib/rupkl/node/number.rb +228 -10
  26. data/lib/rupkl/node/object.rb +626 -74
  27. data/lib/rupkl/node/operation.rb +175 -115
  28. data/lib/rupkl/node/pair.rb +58 -0
  29. data/lib/rupkl/node/pkl_module.rb +16 -28
  30. data/lib/rupkl/node/reference_resolver.rb +79 -0
  31. data/lib/rupkl/node/regex.rb +196 -0
  32. data/lib/rupkl/node/string.rb +415 -23
  33. data/lib/rupkl/node/struct_common.rb +150 -53
  34. data/lib/rupkl/node/this.rb +17 -0
  35. data/lib/rupkl/node/type_common.rb +34 -0
  36. data/lib/rupkl/node/value_common.rb +18 -13
  37. data/lib/rupkl/parser/expression.rb +197 -43
  38. data/lib/rupkl/parser/identifier.rb +2 -2
  39. data/lib/rupkl/parser/literal.rb +18 -12
  40. data/lib/rupkl/parser/method.rb +41 -0
  41. data/lib/rupkl/parser/misc.rb +24 -0
  42. data/lib/rupkl/parser/object.rb +141 -26
  43. data/lib/rupkl/parser/pkl_class.rb +37 -10
  44. data/lib/rupkl/parser/pkl_module.rb +5 -3
  45. data/lib/rupkl/parser/type.rb +28 -0
  46. data/lib/rupkl/parser.rb +8 -0
  47. data/lib/rupkl/pkl_object.rb +11 -7
  48. data/lib/rupkl/version.rb +1 -1
  49. data/lib/rupkl.rb +35 -6
  50. metadata +45 -7
  51. data/lib/rupkl/node/pkl_class.rb +0 -30
@@ -0,0 +1,254 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuPkl
4
+ module Node
5
+ class DataSize < Any
6
+ include Operatable
7
+
8
+ uninstantiable_class
9
+
10
+ def initialize(parent, value, unit, position)
11
+ super(parent, value, position)
12
+ @unit = unit
13
+ end
14
+
15
+ attr_reader :unit
16
+
17
+ def value
18
+ @children[0]
19
+ end
20
+
21
+ def evaluate(_context = nil)
22
+ self
23
+ end
24
+
25
+ def to_ruby(context = nil)
26
+ value.to_ruby(context) * unit_factor(unit)
27
+ end
28
+
29
+ def to_pkl_string(context = nil)
30
+ to_string(context)
31
+ end
32
+
33
+ def to_string(context = nil)
34
+ "#{value.to_pkl_string(context)}.#{unit}"
35
+ end
36
+
37
+ def u_op_minus(position)
38
+ DataSize.new(nil, value.u_op_minus(position), unit, position)
39
+ end
40
+
41
+ def ==(other)
42
+ other.is_a?(DataSize) &&
43
+ calc_byte_size(self).value == calc_byte_size(other).value
44
+ end
45
+
46
+ [:b_op_lt, :b_op_gt, :b_op_le, :b_op_ge].each do |method_name|
47
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
48
+ # def b_op_lt(r_operand, position)
49
+ # l = calc_byte_size(self)
50
+ # r = calc_byte_size(r_operand)
51
+ # l.b_op_lt(r, position)
52
+ # end
53
+ def #{method_name}(r_operand, position)
54
+ l = calc_byte_size(self)
55
+ r = calc_byte_size(r_operand)
56
+ l.#{method_name}(r, position)
57
+ end
58
+ M
59
+ end
60
+
61
+ [:b_op_add, :b_op_sub].each do |method_name|
62
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
63
+ # def b_op_add(r_operand, position)
64
+ # l, r, u = align_unit(self, r_operand)
65
+ # result = l.b_op_add(r, position)
66
+ # DataSize.new(nil, result, u, position)
67
+ # end
68
+ def #{method_name}(r_operand, position)
69
+ l, r, u = align_unit(self, r_operand)
70
+ result = l.#{method_name}(r, position)
71
+ DataSize.new(nil, result, u, position)
72
+ end
73
+ M
74
+ end
75
+
76
+ [:b_op_mul, :b_op_rem, :b_op_exp].each do |method_name|
77
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
78
+ # def b_op_mul(r_operand, position)
79
+ # result = value.b_op_mul(r_operand, position)
80
+ # DataSize.new(nil, result, unit, position)
81
+ # end
82
+ def #{method_name}(r_operand, position)
83
+ result = value.#{method_name}(r_operand, position)
84
+ DataSize.new(nil, result, unit, position)
85
+ end
86
+ M
87
+ end
88
+
89
+ [:b_op_div, :b_op_truncating_div].each do |method_name|
90
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
91
+ # def b_op_div(r_operand, position)
92
+ # if r_operand.is_a?(DataSize)
93
+ # l = calc_byte_size(self)
94
+ # r = calc_byte_size(r_operand)
95
+ # l.b_op_div(r, position)
96
+ # else
97
+ # result = value.b_op_div(r_operand, position)
98
+ # DataSize.new(nil, result, unit, position)
99
+ # end
100
+ # end
101
+ def #{method_name}(r_operand, position)
102
+ if r_operand.is_a?(DataSize)
103
+ l = calc_byte_size(self)
104
+ r = calc_byte_size(r_operand)
105
+ l.#{method_name}(r, position)
106
+ else
107
+ result = value.#{method_name}(r_operand, position)
108
+ DataSize.new(nil, result, unit, position)
109
+ end
110
+ end
111
+ M
112
+ end
113
+
114
+ define_builtin_property(:value) do
115
+ value
116
+ end
117
+
118
+ define_builtin_property(:unit) do
119
+ String.new(self, unit.to_s, nil, position)
120
+ end
121
+
122
+ define_builtin_property(:isPositive) do
123
+ result = value.value.zero? || value.value.positive?
124
+ Boolean.new(self, result, position)
125
+ end
126
+
127
+ define_builtin_property(:isBinaryUnit) do
128
+ result = [:b, :kib, :mib, :gib, :tib, :pib].include?(unit)
129
+ Boolean.new(self, result, position)
130
+ end
131
+
132
+ define_builtin_property(:isDecimalUnit) do
133
+ result = [:b, :kb, :mb, :gb, :tb, :pb].include?(unit)
134
+ Boolean.new(self, result, position)
135
+ end
136
+
137
+ define_builtin_method(
138
+ :isBetween, first: DataSize, last: DataSize
139
+ ) do |args, parent, position|
140
+ r = calc_byte_size(self)
141
+ f = calc_byte_size(args[:first])
142
+ l = calc_byte_size(args[:last])
143
+ r.execute_builtin_method(:isBetween, { first: f, last: l }, parent, position)
144
+ end
145
+
146
+ define_builtin_method(:toUnit, unit: String) do |args, parent, position|
147
+ unit = unit_symbol(args[:unit], position)
148
+ value = convert_unit(self, unit, position)
149
+ DataSize.new(parent, value, unit, position)
150
+ end
151
+
152
+ define_builtin_method(:toBinaryUnit) do |_args, parent, position|
153
+ if (unit = to_binary_unit)
154
+ value = convert_unit(self, unit, position)
155
+ DataSize.new(parent, value, unit, position)
156
+ else
157
+ self
158
+ end
159
+ end
160
+
161
+ define_builtin_method(:toDecimalUnit) do |_args, parent, position|
162
+ if (unit = to_decimal_unit)
163
+ value = convert_unit(self, unit, position)
164
+ DataSize.new(parent, value, unit, position)
165
+ else
166
+ self
167
+ end
168
+ end
169
+
170
+ private
171
+
172
+ UNIT_FACTOR = {
173
+ b: 1000**0,
174
+ kb: 1000**1, mb: 1000**2, gb: 1000**3,
175
+ tb: 1000**4, pb: 1000**5,
176
+ kib: 1024**1, mib: 1024**2, gib: 1024**3,
177
+ tib: 1024**4, pib: 1024**5
178
+ }.freeze
179
+
180
+ def unit_factor(unit)
181
+ UNIT_FACTOR[unit]
182
+ end
183
+
184
+ def defined_operator?(operator)
185
+ [:[], :'!@', :'&&', :'||'].none?(operator)
186
+ end
187
+
188
+ def valid_r_operand?(operator, operand)
189
+ case operator
190
+ when :*, :%, :** then operand in Number
191
+ when :/, :'~/' then operand in Number | DataSize
192
+ else super
193
+ end
194
+ end
195
+
196
+ def calc_byte_size(data_size)
197
+ factor = Int.new(nil, unit_factor(data_size.unit), nil)
198
+ data_size.value.b_op_mul(factor, nil)
199
+ end
200
+
201
+ def align_unit(l_operand, r_operand)
202
+ unit =
203
+ if unit_factor(l_operand.unit) >= unit_factor(r_operand.unit)
204
+ l_operand.unit
205
+ else
206
+ r_operand.unit
207
+ end
208
+
209
+ [
210
+ convert_unit(l_operand, unit, position),
211
+ convert_unit(r_operand, unit, position),
212
+ unit
213
+ ]
214
+ end
215
+
216
+ def convert_unit(data_size, unit, position)
217
+ return data_size.value if data_size.unit == unit
218
+
219
+ byte_size = calc_byte_size(data_size)
220
+ factor = Int.new(nil, unit_factor(unit), nil)
221
+ if (byte_size.value % factor.value).zero?
222
+ byte_size.b_op_truncating_div(factor, position)
223
+ else
224
+ byte_size.b_op_div(factor, position)
225
+ end
226
+ end
227
+
228
+ def unit_symbol(string, position)
229
+ symbol = string.value.to_sym
230
+ return symbol if UNIT_FACTOR.key?(symbol)
231
+
232
+ message =
233
+ 'expected value of type ' \
234
+ '"b"|"kb"|"kib"|"mb"|"mib"|"gb"|"gib"|"tb"|"tib"|"pb"|"pib", ' \
235
+ "but got #{string.to_pkl_string(nil)}"
236
+ raise EvaluationError.new(message, position)
237
+ end
238
+
239
+ def to_binary_unit
240
+ {
241
+ kb: :kib, mb: :mib, gb: :gib,
242
+ tb: :tib, pb: :pib
243
+ }[unit]
244
+ end
245
+
246
+ def to_decimal_unit
247
+ {
248
+ kib: :kb, mib: :mb, gib: :gb,
249
+ tib: :tb, pib: :pb
250
+ }[unit]
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuPkl
4
+ module Node
5
+ class DeclaredType
6
+ include TypeCommon
7
+
8
+ def initialize(parent, type, position)
9
+ super(parent, *type, position)
10
+ @type = type
11
+ end
12
+
13
+ attr_reader :type
14
+
15
+ def find_class(context)
16
+ find_type(type, context)
17
+ end
18
+
19
+ def to_s
20
+ type.last.id.to_s
21
+ end
22
+
23
+ private
24
+
25
+ def match_type?(klass, context)
26
+ rhs = klass
27
+ lhs = find_class(context)
28
+ rhs <= lhs
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,266 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuPkl
4
+ module Node
5
+ class Duration < Any
6
+ include Operatable
7
+
8
+ uninstantiable_class
9
+
10
+ def initialize(parent, value, unit, position)
11
+ super(parent, value, position)
12
+ @unit = unit
13
+ end
14
+
15
+ attr_reader :unit
16
+
17
+ def value
18
+ @children[0]
19
+ end
20
+
21
+ def evaluate(_context = nil)
22
+ self
23
+ end
24
+
25
+ def to_ruby(context = nil)
26
+ value.to_ruby(context) * UNIT_FACTOR[unit]
27
+ end
28
+
29
+ def to_pkl_string(context = nil)
30
+ to_string(context)
31
+ end
32
+
33
+ def to_string(context = nil)
34
+ "#{value.to_pkl_string(context)}.#{unit}"
35
+ end
36
+
37
+ def u_op_minus(position)
38
+ Duration.new(nil, value.u_op_minus(position), unit, position)
39
+ end
40
+
41
+ def ==(other)
42
+ other.is_a?(Duration) &&
43
+ begin
44
+ l = calc_second(self)
45
+ r = calc_second(other)
46
+ l.value == r.value
47
+ end
48
+ end
49
+
50
+ [:b_op_lt, :b_op_gt, :b_op_le, :b_op_ge].each do |method_name|
51
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
52
+ # def b_op_lt(r_operand, position)
53
+ # l = calc_second(self)
54
+ # r = calc_second(r_operand)
55
+ # l.b_op_lt(r, position)
56
+ # end
57
+ def #{method_name}(r_operand, position)
58
+ l = calc_second(self)
59
+ r = calc_second(r_operand)
60
+ l.#{method_name}(r, position)
61
+ end
62
+ M
63
+ end
64
+
65
+ [:b_op_add, :b_op_sub].each do |method_name|
66
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
67
+ # def b_op_add(r_operand, position)
68
+ # l, r, u = align_unit(self, r_operand)
69
+ # result = l.b_op_add(r, position)
70
+ # Duration.new(nil, result, u, position)
71
+ # end
72
+ def #{method_name}(r_operand, position)
73
+ l, r, u = align_unit(self, r_operand)
74
+ result = l.#{method_name}(r, position)
75
+ Duration.new(nil, result, u, position)
76
+ end
77
+ M
78
+ end
79
+
80
+ [:b_op_mul, :b_op_rem, :b_op_exp].each do |method_name|
81
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
82
+ # def b_op_mul(r_operand, position)
83
+ # result = value.b_op_mul(r_operand, position)
84
+ # Duration.new(nil, result, unit, position)
85
+ # end
86
+ def #{method_name}(r_operand, position)
87
+ result = value.#{method_name}(r_operand, position)
88
+ Duration.new(nil, result, unit, position)
89
+ end
90
+ M
91
+ end
92
+
93
+ [:b_op_div, :b_op_truncating_div].each do |method_name|
94
+ class_eval(<<~M, __FILE__, __LINE__ + 1)
95
+ # def b_op_div(r_operand, position)
96
+ # if r_operand.is_a?(Duration)
97
+ # l = calc_second(self)
98
+ # r = calc_second(r_operand)
99
+ # l.b_op_div(r, position)
100
+ # else
101
+ # result = value.b_op_div(r_operand, position)
102
+ # Duration.new(nil, result, unit, position)
103
+ # end
104
+ # end
105
+ def #{method_name}(r_operand, position)
106
+ if r_operand.is_a?(Duration)
107
+ l = calc_second(self)
108
+ r = calc_second(r_operand)
109
+ l.#{method_name}(r, position)
110
+ else
111
+ result = value.#{method_name}(r_operand, position)
112
+ Duration.new(nil, result, unit, position)
113
+ end
114
+ end
115
+ M
116
+ end
117
+
118
+ define_builtin_property(:value) do
119
+ value
120
+ end
121
+
122
+ define_builtin_property(:unit) do
123
+ String.new(self, unit.to_s, nil, position)
124
+ end
125
+
126
+ define_builtin_property(:isPositive) do
127
+ result = value.value.zero? || value.value.positive?
128
+ Boolean.new(self, result, position)
129
+ end
130
+
131
+ define_builtin_property(:isoString) do
132
+ unless value.value.finite?
133
+ message = "cannot convert duration '#{to_string(nil)}' to ISO 8601 duration"
134
+ raise EvaluationError.new(message, position)
135
+ end
136
+
137
+ String.new(self, iso8601_string, nil, position)
138
+ end
139
+
140
+ define_builtin_method(
141
+ :isBetween, first: Duration, last: Duration
142
+ ) do |args, parent, position|
143
+ r = calc_second(self)
144
+ f = calc_second(args[:first])
145
+ l = calc_second(args[:last])
146
+ r.execute_builtin_method(:isBetween, { first: f, last: l }, parent, position)
147
+ end
148
+
149
+ define_builtin_method(:toUnit, unit: String) do |args, parent, position|
150
+ unit = unit_symbol(args[:unit], position)
151
+ value = convert_unit(self, unit, position)
152
+ Duration.new(parent, value, unit, position)
153
+ end
154
+
155
+ private
156
+
157
+ UNIT_FACTOR = {
158
+ ns: 10.0**-9, us: 10.0**-6, ms: 10.0**-3,
159
+ s: 1, min: 60, h: 60 * 60, d: 24 * 60 * 60
160
+ }.freeze
161
+
162
+ def unit_factor(unit)
163
+ factor = UNIT_FACTOR[unit]
164
+ if factor >= 1
165
+ Int.new(nil, factor, nil)
166
+ else
167
+ Float.new(nil, factor, nil)
168
+ end
169
+ end
170
+
171
+ def defined_operator?(operator)
172
+ [:[], :'!@', :'&&', :'||'].none?(operator)
173
+ end
174
+
175
+ def valid_r_operand?(operator, operand)
176
+ case operator
177
+ when :*, :%, :** then operand in Number
178
+ when :/, :'~/' then operand in Number | Duration
179
+ else super
180
+ end
181
+ end
182
+
183
+ def calc_second(duration)
184
+ factor = unit_factor(duration.unit)
185
+ duration.value.b_op_mul(factor, nil)
186
+ end
187
+
188
+ def align_unit(l_operand, r_operand)
189
+ unit =
190
+ if UNIT_FACTOR[l_operand.unit] >= UNIT_FACTOR[r_operand.unit]
191
+ l_operand.unit
192
+ else
193
+ r_operand.unit
194
+ end
195
+
196
+ [
197
+ convert_unit(l_operand, unit, position),
198
+ convert_unit(r_operand, unit, position),
199
+ unit
200
+ ]
201
+ end
202
+
203
+ def convert_unit(duration, unit, position)
204
+ return duration.value if duration.unit == unit
205
+
206
+ second = calc_second(duration)
207
+ result = second.b_op_div(unit_factor(unit), position)
208
+ if result.value.to_i == result.value
209
+ Int.new(nil, result.value, position)
210
+ else
211
+ result
212
+ end
213
+ end
214
+
215
+ def iso8601_string
216
+ return 'PT0S' if value.value.zero?
217
+
218
+ parts = value.value.negative? && ['-PT'] || ['PT']
219
+ iso8601_elements.each do |unit, n|
220
+ parts << format_iso8601_element(unit, n)
221
+ end
222
+
223
+ parts.join
224
+ end
225
+
226
+ def iso8601_elements
227
+ result, _ =
228
+ [:h, :min, :s]
229
+ .inject([{}, calc_second(self).value.abs]) do |(elements, sec), unit|
230
+ q, r =
231
+ if unit == :s
232
+ sec
233
+ else
234
+ sec.divmod(UNIT_FACTOR[unit])
235
+ end
236
+ elements[unit] = q if q.positive?
237
+
238
+ [elements, r]
239
+ end
240
+
241
+ result
242
+ end
243
+
244
+ def format_iso8601_element(unit, value)
245
+ s =
246
+ if unit != :s || value.to_i == value
247
+ value
248
+ else
249
+ format('%.12f', value).sub(/0+\Z/, '')
250
+ end
251
+ "#{s}#{unit[0].upcase}"
252
+ end
253
+
254
+ def unit_symbol(string, position)
255
+ symbol = string.value.to_sym
256
+ return symbol if UNIT_FACTOR.key?(symbol)
257
+
258
+ message =
259
+ 'expected value of type ' \
260
+ '"ns"|"us"|"ms"|"s"|"min"|"h"|"d", ' \
261
+ "but got #{string.to_pkl_string(nil)}"
262
+ raise EvaluationError.new(message, position)
263
+ end
264
+ end
265
+ end
266
+ end
@@ -2,36 +2,20 @@
2
2
 
3
3
  module RuPkl
4
4
  module Node
5
- class Dynamic
5
+ class Dynamic < Any
6
+ include Operatable
6
7
  include StructCommon
7
8
 
8
- def initialize(members, scopes, position)
9
- @position = position
10
- add_members(members, scopes)
9
+ def entries
10
+ @body&.entries
11
11
  end
12
12
 
13
- attr_reader :properties
14
- attr_reader :entries
15
- attr_reader :elements
16
- attr_reader :position
17
-
18
- def evaluate(_scopes)
19
- self
20
- end
21
-
22
- def to_ruby(_scopes)
23
- create_pkl_object(nil, properties, entries, elements)
13
+ def elements
14
+ @body&.elements
24
15
  end
25
16
 
26
- def to_pkl_string(_scopes)
27
- to_pkl_string_object(*properties, *entries, *elements)
28
- end
29
-
30
- def merge!(other)
31
- @properties = merge_hash_members(properties, other.properties, :name)
32
- @entries = merge_hash_members(entries, other.entries, :key)
33
- @elements = merge_array_members(elements, other.elements)
34
- self
17
+ def to_ruby(context = nil)
18
+ to_pkl_object(context)
35
19
  end
36
20
 
37
21
  def ==(other)
@@ -41,58 +25,47 @@ module RuPkl
41
25
  match_members?(elements, other.elements, true)
42
26
  end
43
27
 
44
- def undefined_operator?(operator)
45
- [:[], :==, :'!='].none?(operator)
46
- end
47
-
48
28
  def find_by_key(key)
49
- find_entry(key) || find_element(key)
29
+ (find_entry(key) || find_element(key))&.value
50
30
  end
51
31
 
52
- private
53
-
54
- def add_members(members, scopes)
55
- return unless members
32
+ define_builtin_method(:length) do |_, parent, position|
33
+ result = elements&.size || 0
34
+ Int.new(parent, result, position)
35
+ end
56
36
 
57
- push_scope(scopes) do |s|
58
- members.each { |m| add_member(m, s) }
59
- end
37
+ define_builtin_method(:hasProperty, name: String) do |args, parent, position|
38
+ name = args[:name].value.to_sym
39
+ result = find_property(name) && true || false
40
+ Boolean.new(parent, result, position)
60
41
  end
61
42
 
62
- def add_member(member, scopes)
63
- member.evaluate(scopes).then do |m|
64
- case member
65
- when ObjectProperty then add_property(m)
66
- when ObjectEntry then add_entry(m)
67
- else add_element(m)
43
+ define_builtin_method(:getProperty, name: String) do |args, _, position|
44
+ name = args[:name].value.to_sym
45
+ find_property(name)&.value ||
46
+ begin
47
+ m = "cannot find property '#{name}'"
48
+ raise EvaluationError.new(m, position)
68
49
  end
69
- end
70
50
  end
71
51
 
72
- def add_property(member)
73
- add_hash_member((@properties ||= []), member, :name)
52
+ define_builtin_method(:getPropertyOrNull, name: String) do |args, parent, position|
53
+ name = args[:name].value.to_sym
54
+ find_property(name)&.value || Null.new(parent, position)
74
55
  end
75
56
 
76
- def add_entry(member)
77
- add_hash_member((@entries ||= []), member, :key)
78
- end
57
+ private
79
58
 
80
- def add_element(member)
81
- add_array_member((@elements ||= []), member)
59
+ def properties_not_allowed?
60
+ false
82
61
  end
83
62
 
84
- def find_entry(key)
85
- entries
86
- &.find { _1.key == key }
87
- &.then(&:value)
63
+ def entries_not_allowed?
64
+ false
88
65
  end
89
66
 
90
- def find_element(index)
91
- return nil unless elements
92
- return nil unless index.value.is_a?(::Integer)
93
-
94
- elements
95
- .find.with_index { |_, i| i == index.value }
67
+ def elements_not_allowed?
68
+ false
96
69
  end
97
70
  end
98
71
  end