hocon 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +4 -2
  3. data/lib/hocon.rb +2 -0
  4. data/lib/hocon/config.rb +1010 -0
  5. data/lib/hocon/config_error.rb +32 -2
  6. data/lib/hocon/config_factory.rb +46 -0
  7. data/lib/hocon/config_include_context.rb +49 -0
  8. data/lib/hocon/config_includer_file.rb +27 -0
  9. data/lib/hocon/config_list.rb +49 -0
  10. data/lib/hocon/config_mergeable.rb +74 -0
  11. data/lib/hocon/config_object.rb +144 -1
  12. data/lib/hocon/config_parse_options.rb +33 -9
  13. data/lib/hocon/config_parseable.rb +51 -0
  14. data/lib/hocon/config_render_options.rb +4 -2
  15. data/lib/hocon/config_resolve_options.rb +31 -0
  16. data/lib/hocon/config_syntax.rb +5 -2
  17. data/lib/hocon/config_util.rb +73 -0
  18. data/lib/hocon/config_value.rb +122 -0
  19. data/lib/hocon/config_value_factory.rb +66 -2
  20. data/lib/hocon/config_value_type.rb +5 -2
  21. data/lib/hocon/impl.rb +2 -0
  22. data/lib/hocon/impl/abstract_config_node.rb +29 -0
  23. data/lib/hocon/impl/abstract_config_node_value.rb +11 -0
  24. data/lib/hocon/impl/abstract_config_object.rb +148 -42
  25. data/lib/hocon/impl/abstract_config_value.rb +251 -11
  26. data/lib/hocon/impl/array_iterator.rb +19 -0
  27. data/lib/hocon/impl/config_boolean.rb +7 -1
  28. data/lib/hocon/impl/config_concatenation.rb +177 -28
  29. data/lib/hocon/impl/config_delayed_merge.rb +329 -0
  30. data/lib/hocon/impl/config_delayed_merge_object.rb +274 -0
  31. data/lib/hocon/impl/config_document_parser.rb +647 -0
  32. data/lib/hocon/impl/config_double.rb +44 -0
  33. data/lib/hocon/impl/config_impl.rb +143 -19
  34. data/lib/hocon/impl/config_impl_util.rb +18 -0
  35. data/lib/hocon/impl/config_include_kind.rb +10 -0
  36. data/lib/hocon/impl/config_int.rb +13 -1
  37. data/lib/hocon/impl/config_node_array.rb +11 -0
  38. data/lib/hocon/impl/config_node_comment.rb +19 -0
  39. data/lib/hocon/impl/config_node_complex_value.rb +54 -0
  40. data/lib/hocon/impl/config_node_concatenation.rb +11 -0
  41. data/lib/hocon/impl/config_node_field.rb +81 -0
  42. data/lib/hocon/impl/config_node_include.rb +33 -0
  43. data/lib/hocon/impl/config_node_object.rb +276 -0
  44. data/lib/hocon/impl/config_node_path.rb +48 -0
  45. data/lib/hocon/impl/config_node_root.rb +60 -0
  46. data/lib/hocon/impl/config_node_simple_value.rb +42 -0
  47. data/lib/hocon/impl/config_node_single_token.rb +17 -0
  48. data/lib/hocon/impl/config_null.rb +15 -7
  49. data/lib/hocon/impl/config_number.rb +43 -4
  50. data/lib/hocon/impl/config_parser.rb +403 -0
  51. data/lib/hocon/impl/config_reference.rb +142 -0
  52. data/lib/hocon/impl/config_string.rb +55 -7
  53. data/lib/hocon/impl/container.rb +29 -0
  54. data/lib/hocon/impl/default_transformer.rb +24 -15
  55. data/lib/hocon/impl/from_map_mode.rb +3 -1
  56. data/lib/hocon/impl/full_includer.rb +2 -0
  57. data/lib/hocon/impl/memo_key.rb +42 -0
  58. data/lib/hocon/impl/mergeable_value.rb +8 -0
  59. data/lib/hocon/impl/origin_type.rb +8 -2
  60. data/lib/hocon/impl/parseable.rb +455 -91
  61. data/lib/hocon/impl/path.rb +181 -59
  62. data/lib/hocon/impl/path_builder.rb +24 -3
  63. data/lib/hocon/impl/path_parser.rb +280 -0
  64. data/lib/hocon/impl/replaceable_merge_stack.rb +22 -0
  65. data/lib/hocon/impl/resolve_context.rb +254 -0
  66. data/lib/hocon/impl/resolve_memos.rb +21 -0
  67. data/lib/hocon/impl/resolve_result.rb +39 -0
  68. data/lib/hocon/impl/resolve_source.rb +354 -0
  69. data/lib/hocon/impl/resolve_status.rb +3 -1
  70. data/lib/hocon/impl/simple_config.rb +264 -10
  71. data/lib/hocon/impl/simple_config_document.rb +48 -0
  72. data/lib/hocon/impl/simple_config_list.rb +282 -8
  73. data/lib/hocon/impl/simple_config_object.rb +424 -88
  74. data/lib/hocon/impl/simple_config_origin.rb +263 -71
  75. data/lib/hocon/impl/simple_include_context.rb +31 -1
  76. data/lib/hocon/impl/simple_includer.rb +196 -1
  77. data/lib/hocon/impl/substitution_expression.rb +38 -0
  78. data/lib/hocon/impl/token.rb +17 -4
  79. data/lib/hocon/impl/token_type.rb +6 -2
  80. data/lib/hocon/impl/tokenizer.rb +339 -109
  81. data/lib/hocon/impl/tokens.rb +330 -79
  82. data/lib/hocon/impl/unmergeable.rb +14 -1
  83. data/lib/hocon/impl/unsupported_operation_error.rb +6 -0
  84. data/lib/hocon/impl/url.rb +37 -0
  85. data/lib/hocon/parser.rb +7 -0
  86. data/lib/hocon/parser/config_document.rb +92 -0
  87. data/lib/hocon/parser/config_document_factory.rb +36 -0
  88. data/lib/hocon/parser/config_node.rb +30 -0
  89. metadata +67 -43
  90. data/lib/hocon/impl/config_float.rb +0 -13
  91. data/lib/hocon/impl/parser.rb +0 -977
  92. data/lib/hocon/impl/properties_parser.rb +0 -83
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'hocon/impl'
2
4
 
3
5
  class Hocon::Impl::ResolveStatus
@@ -15,4 +17,4 @@ class Hocon::Impl::ResolveStatus
15
17
  def self.from_boolean(resolved)
16
18
  resolved ? RESOLVED : UNRESOLVED
17
19
  end
18
- end
20
+ end
@@ -1,10 +1,16 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'hocon/impl'
2
4
  require 'hocon/config_value_type'
5
+ require 'hocon/config_resolve_options'
3
6
  require 'hocon/impl/path'
4
7
  require 'hocon/impl/default_transformer'
5
8
  require 'hocon/impl/config_impl'
9
+ require 'hocon/impl/resolve_context'
10
+ require 'hocon/config_mergeable'
6
11
 
7
12
  class Hocon::Impl::SimpleConfig
13
+ include Hocon::ConfigMergeable
8
14
 
9
15
  ConfigMissingError = Hocon::ConfigError::ConfigMissingError
10
16
  ConfigNotResolvedError = Hocon::ConfigError::ConfigNotResolvedError
@@ -14,15 +20,35 @@ class Hocon::Impl::SimpleConfig
14
20
  Path = Hocon::Impl::Path
15
21
  DefaultTransformer = Hocon::Impl::DefaultTransformer
16
22
 
23
+ attr_reader :object
24
+
17
25
  def initialize(object)
18
26
  @object = object
19
27
  end
28
+ attr_reader :object
20
29
 
21
30
  def root
22
31
  @object
23
32
  end
24
33
 
25
- def find_key(me, key, expected, original_path)
34
+ def origin
35
+ @object.origin
36
+ end
37
+
38
+ def resolve(options = Hocon::ConfigResolveOptions.defaults)
39
+ resolve_with(self, options)
40
+ end
41
+
42
+ def resolve_with(source, options)
43
+ resolved = Hocon::Impl::ResolveContext.resolve(@object, source.object, options)
44
+ if resolved.eql?(@object)
45
+ self
46
+ else
47
+ Hocon::Impl::SimpleConfig.new(resolved)
48
+ end
49
+ end
50
+
51
+ def self.find_key(me, key, expected, original_path)
26
52
  v = me.peek_assuming_resolved(key, original_path)
27
53
  if v.nil?
28
54
  raise ConfigMissingError.new(nil, "No configuration setting found for key '#{original_path.render}'", nil)
@@ -35,12 +61,12 @@ class Hocon::Impl::SimpleConfig
35
61
  if v.value_type == ConfigValueType::NULL
36
62
  raise ConfigNullError.new(v.origin,
37
63
  (ConfigNullError.make_message(original_path.render,
38
- (not expected.nil?) ? expected.name : nil)),
64
+ (not expected.nil?) ? ConfigValueType.name(expected) : nil)),
39
65
  nil)
40
66
  elsif (not expected.nil?) && v.value_type != expected
41
67
  raise ConfigWrongTypeError.new(v.origin,
42
- "#{original_path.render} has type #{v.value_type.name} " +
43
- "rather than #{expected.name}",
68
+ "#{original_path.render} has type #{ConfigValueType.name(v.value_type)} " +
69
+ "rather than #{ConfigValueType.name(expected)}",
44
70
  nil)
45
71
  else
46
72
  return v
@@ -51,30 +77,250 @@ class Hocon::Impl::SimpleConfig
51
77
  key = path.first
52
78
  rest = path.remainder
53
79
  if rest.nil?
54
- find_key(me, key, expected, original_path)
80
+ self.class.find_key(me, key, expected, original_path)
55
81
  else
56
- o = find_key(me, key, ConfigValueType::OBJECT,
82
+ o = self.class.find_key(me, key, ConfigValueType::OBJECT,
57
83
  original_path.sub_path(0, original_path.length - rest.length))
58
84
  raise "Error: object o is nil" unless not o.nil?
59
85
  find(o, rest, expected, original_path)
60
86
  end
61
87
  end
62
88
 
89
+ def find3(path_expression, expected, original_path)
90
+ find(@object, path_expression, expected, original_path)
91
+ end
92
+
93
+ def find2(path_expression, expected)
94
+ path = Path.new_path(path_expression)
95
+ find3(path, expected, path)
96
+ end
97
+
98
+ def ==(other)
99
+ if other.is_a? Hocon::Impl::SimpleConfig
100
+ @object == other.object
101
+ else
102
+ false
103
+ end
104
+ end
105
+
106
+ def hash
107
+ 41 * @object.hash
108
+ end
109
+
110
+ def self.find_key_or_null(me, key, expected, original_path)
111
+ v = me.peek_assuming_resolved(key, original_path)
112
+
113
+ if v.nil?
114
+ raise Hocon::ConfigError::ConfigMissingError.new(nil, original_path.render, nil)
115
+ end
116
+
117
+ if not expected.nil?
118
+ v = Hocon::Impl::DefaultTransformer.transform(v, expected)
119
+ end
120
+
121
+ if (not expected.nil?) && (v.value_type != expected && v.value_type != Hocon::ConfigValueType::NULL)
122
+ raise Hocon::ConfigError::ConfigWrongTypeError.with_expected_actual(v.origin,
123
+ original_path.render,
124
+ expected.name,
125
+ Hocon::ConfigValueType.name(v.value_type))
126
+ else
127
+ return v
128
+ end
129
+ end
130
+
131
+ def self.find_or_null(me, path, expected, original_path)
132
+ begin
133
+ key = path.first
134
+ remainder = path.remainder
135
+
136
+ if remainder.nil?
137
+ return self.find_key_or_null(me, key, expected, original_path)
138
+ else
139
+ o = find_key(me,
140
+ key,
141
+ Hocon::ConfigValueType::OBJECT,
142
+ original_path.sub_path(0, original_path.length - remainder.length))
143
+
144
+ if o.nil?
145
+ raise "Missing key: #{key} on path: #{path}"
146
+ end
147
+
148
+ find_or_null(o, remainder, expected, original_path)
149
+ end
150
+ rescue Hocon::ConfigError::ConfigNotResolvedError
151
+ raise Hocon::Impl::ConfigImpl::improved_not_resolved(path, e)
152
+ end
153
+ end
154
+
155
+ def is_null?(path_expression)
156
+ path = Path.new_path(path_expression)
157
+ v = self.class.find_or_null(@object, path, nil, path)
158
+ v.value_type == Hocon::ConfigValueType::NULL
159
+ end
160
+
63
161
  def get_value(path)
64
162
  parsed_path = Path.new_path(path)
65
163
  find(@object, parsed_path, nil, parsed_path)
66
164
  end
67
165
 
68
- def has_path(path_expression)
166
+ def get_boolean(path)
167
+ v = find2(path, ConfigValueType::BOOLEAN)
168
+ v.unwrapped
169
+ end
170
+
171
+ def get_config_number(path_expression)
69
172
  path = Path.new_path(path_expression)
173
+ v = find(@object, path, ConfigValueType::NUMBER, path)
174
+ v.unwrapped
175
+ end
176
+
177
+ def get_int(path)
178
+ get_config_number(path)
179
+ end
180
+
181
+ def get_string(path)
182
+ v = find2(path, ConfigValueType::STRING)
183
+ v.unwrapped
184
+ end
185
+
186
+ def get_list(path)
187
+ find2(path, ConfigValueType::LIST)
188
+ end
189
+
190
+ def get_object(path)
191
+ find2(path, ConfigValueType::OBJECT)
192
+ end
193
+
194
+ def get_config(path)
195
+ get_object(path).to_config
196
+ end
197
+
198
+ def get_any_ref(path)
199
+ v = find2(path, nil)
200
+ v.unwrapped
201
+ end
202
+
203
+ def get_bytes(path)
204
+ size = null
205
+ begin
206
+ size = get_long(path)
207
+ rescue ConfigWrongTypeError => e
208
+ v = find2(path, ConfigValueType::STRING)
209
+ size = self.class.parse_bytes(v.unwrapped, v.origin, path)
210
+ end
211
+ size
212
+ end
213
+
214
+ def get_homogeneous_unwrapped_list(path, expected)
215
+ l = []
216
+ list = get_list(path)
217
+ list.each do |cv|
218
+ if !expected.nil?
219
+ v = DefaultTransformer.transform(cv, expected)
220
+ end
221
+ if v.value_type != expected
222
+ raise ConfigWrongTypeError.with_expected_actual(origin, path,
223
+ "list of #{expected.name}",
224
+ "list of #{v.value_type.name}")
225
+ end
226
+ l << v.unwrapped
227
+ end
228
+ l
229
+ end
230
+
231
+ def get_boolean_list(path)
232
+ get_homogeneous_unwrapped_list(path, ConfigValueType::BOOLEAN)
233
+ end
234
+
235
+ def get_number_list(path)
236
+ get_homogeneous_unwrapped_list(path, ConfigValueType::NUMBER)
237
+ end
238
+
239
+ def get_int_list(path)
240
+ l = []
241
+ numbers = get_homogeneous_wrapped_list(path, ConfigValueType::NUMBER)
242
+ numbers.each do |v|
243
+ l << v.int_value_range_checked(path)
244
+ end
245
+ l
246
+ end
247
+
248
+ def get_double_list(path)
249
+ l = []
250
+ numbers = get_number_list(path)
251
+ numbers.each do |n|
252
+ l << n.double_value
253
+ end
254
+ l
255
+ end
256
+
257
+ def get_string_list(path)
258
+ get_homogeneous_unwrapped_list(path, ConfigValueType::STRING)
259
+ end
260
+
261
+ def get_object_list(path)
262
+ get_homogeneous_wrapped_list(path, ConfigValueType::OBJECT)
263
+ end
264
+
265
+ def get_homogeneous_wrapped_list(path, expected)
266
+ l = []
267
+ list = get_list(path)
268
+ list.each do |cv|
269
+ if !expected.nil?
270
+ v = DefaultTransformer.transform(cv, expected)
271
+ end
272
+ if v.value_type != expected
273
+ raise ConfigWrongTypeError.with_expected_actual(origin, path,
274
+ "list of #{expected.name}",
275
+ "list of #{v.value_type.name}")
276
+ end
277
+ l << v
278
+ end
279
+ l
280
+ end
281
+
282
+ def has_path_peek(path_expression)
283
+ path = Path.new_path(path_expression)
284
+
70
285
  begin
71
286
  peeked = @object.peek_path(path)
72
- rescue ConfigNotResolvedError => e
73
- raise Hocon::Impl::ConfigImpl.improve_not_resolved(path, e)
287
+ rescue Hocon::ConfigError::ConfigNotResolvedError
288
+ raise Hocon::Impl::ConfigImpl.improved_not_resolved(path, e)
74
289
  end
290
+
291
+ peeked
292
+ end
293
+
294
+ def has_path?(path_expression)
295
+ peeked = has_path_peek(path_expression)
296
+
75
297
  (not peeked.nil?) && peeked.value_type != ConfigValueType::NULL
76
298
  end
77
299
 
300
+ def has_path_or_null?(path)
301
+ peeked = has_path_peek(path)
302
+
303
+ not peeked.nil?
304
+ end
305
+
306
+ def empty?
307
+ @object.empty?
308
+ end
309
+
310
+ def at_key(key)
311
+ root.at_key(key)
312
+ end
313
+
314
+ # In java this is an overloaded version of atKey
315
+ def at_key_with_origin(origin, key)
316
+ root.at_key_with_origin(origin, key)
317
+ end
318
+
319
+ def with_only_path(path_expression)
320
+ path = Path.new_path(path_expression)
321
+ self.class.new(root.with_only_path(path))
322
+ end
323
+
78
324
  def without_path(path_expression)
79
325
  path = Path.new_path(path_expression)
80
326
  self.class.new(root.without_path(path))
@@ -84,4 +330,12 @@ class Hocon::Impl::SimpleConfig
84
330
  path = Path.new_path(path_expression)
85
331
  self.class.new(root.with_value(path, v))
86
332
  end
87
- end
333
+
334
+ def to_fallback_value
335
+ @object
336
+ end
337
+
338
+ def with_fallback(other)
339
+ @object.with_fallback(other).to_config
340
+ end
341
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ require 'hocon/impl'
4
+ require 'hocon/parser/config_document'
5
+ require 'hocon/impl/config_document_parser'
6
+
7
+ class Hocon::Impl::SimpleConfigDocument
8
+ include Hocon::Parser::ConfigDocument
9
+
10
+ def initialize(parsed_node, parse_options)
11
+ @config_node_tree = parsed_node
12
+ @parse_options = parse_options
13
+ end
14
+
15
+ def set_value(path, new_value)
16
+ origin = Hocon::Impl::SimpleConfigOrigin.new_simple("single value parsing")
17
+ reader = StringIO.new(new_value)
18
+ tokens = Hocon::Impl::Tokenizer.tokenize(origin, reader, @parse_options.syntax)
19
+ parsed_value = Hocon::Impl::ConfigDocumentParser.parse_value(tokens, origin, @parse_options)
20
+ reader.close
21
+
22
+ self.class.new(@config_node_tree.set_value(path, parsed_value, @parse_options.syntax), @parse_options)
23
+ end
24
+
25
+ def set_config_value(path, new_value)
26
+ set_value(path, new_value.render)
27
+ end
28
+
29
+ def remove_value(path)
30
+ self.class.new(@config_node_tree.set_value(path, nil, @parse_options.syntax), @parse_options)
31
+ end
32
+
33
+ def has_value?(path)
34
+ @config_node_tree.has_value(path)
35
+ end
36
+
37
+ def render
38
+ @config_node_tree.render
39
+ end
40
+
41
+ def ==(other)
42
+ other.class.ancestors.include?(Hocon::Parser::ConfigDocument) && render == other.render
43
+ end
44
+
45
+ def hash
46
+ render.hash
47
+ end
48
+ end
@@ -1,10 +1,25 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'hocon/impl'
2
4
  require 'hocon/impl/resolve_status'
3
5
  require 'hocon/config_value_type'
6
+ require 'hocon/config_error'
4
7
  require 'hocon/impl/abstract_config_object'
8
+ require 'forwardable'
9
+ require 'hocon/impl/unsupported_operation_error'
10
+ require 'hocon/impl/resolve_result'
11
+ require 'hocon/impl/container'
12
+ require 'hocon/config_list'
13
+
14
+ class Hocon::Impl::SimpleConfigList
15
+ include Hocon::Impl::Container
16
+ include Hocon::ConfigList
17
+ include Hocon::Impl::AbstractConfigValue
18
+ extend Forwardable
5
19
 
6
- class Hocon::Impl::SimpleConfigList < Hocon::Impl::AbstractConfigValue
7
20
  ResolveStatus = Hocon::Impl::ResolveStatus
21
+ ResolveResult = Hocon::Impl::ResolveResult
22
+ ConfigBugOrBrokenError = Hocon::ConfigError::ConfigBugOrBrokenError
8
23
 
9
24
  def initialize(origin, value, status = ResolveStatus.from_values(value))
10
25
  super(origin)
@@ -13,10 +28,14 @@ class Hocon::Impl::SimpleConfigList < Hocon::Impl::AbstractConfigValue
13
28
 
14
29
  # kind of an expensive debug check (makes this constructor pointless)
15
30
  if status != ResolveStatus.from_values(value)
16
- raise ConfigBugError, "SimpleConfigList created with wrong resolve status: #{self}"
31
+ raise ConfigBugOrBrokenError, "SimpleConfigList created with wrong resolve status: #{self}"
17
32
  end
18
33
  end
19
34
 
35
+ attr_reader :value
36
+
37
+ def_delegators :@value, :[], :include?, :empty?, :size, :index, :rindex, :each, :map
38
+
20
39
  def value_type
21
40
  Hocon::ConfigValueType::LIST
22
41
  end
@@ -25,6 +44,143 @@ class Hocon::Impl::SimpleConfigList < Hocon::Impl::AbstractConfigValue
25
44
  @value.map { |v| v.unwrapped }
26
45
  end
27
46
 
47
+ def resolve_status
48
+ ResolveStatus.from_boolean(@resolved)
49
+ end
50
+
51
+ def replace_child(child, replacement)
52
+ new_list = replace_child_in_list(@value, child, replacement)
53
+ if new_list.nil?
54
+ nil
55
+ else
56
+ # we use the constructor flavor that will recompute the resolve status
57
+ SimpleConfigList.new(origin, new_list)
58
+ end
59
+ end
60
+
61
+ def has_descendant?(descendant)
62
+ Hocon::Impl::AbstractConfigValue.has_descendant_in_list?(@value, descendant)
63
+ end
64
+
65
+ def modify(modifier, new_resolve_status)
66
+ begin
67
+ modify_may_throw(modifier, new_resolve_status)
68
+ rescue Hocon::ConfigError => e
69
+ raise e
70
+ end
71
+ end
72
+
73
+ def modify_may_throw(modifier, new_resolve_status)
74
+ # lazy-create for optimization
75
+ changed = nil
76
+ i = 0
77
+ @value.each { |v|
78
+ modified = modifier.modify_child_may_throw(nil, v)
79
+
80
+ # lazy-create the new list if required
81
+ if changed == nil && !modified.equal?(v)
82
+ changed = []
83
+ j = 0
84
+ while j < i
85
+ changed << @value[j]
86
+ j += 1
87
+ end
88
+ end
89
+
90
+ # once the new list is created, all elements
91
+ # have to go in it.if modifyChild returned
92
+ # null, we drop that element.
93
+ if changed != nil && modified != nil
94
+ changed << modified
95
+ end
96
+
97
+ i += 1
98
+ }
99
+
100
+ if changed != nil
101
+ if new_resolve_status != nil
102
+ self.class.new(origin, changed, new_resolve_status)
103
+ else
104
+ self.class.new(origin, changed)
105
+ end
106
+ else
107
+ self
108
+ end
109
+ end
110
+
111
+ class ResolveModifier
112
+ attr_reader :context, :source
113
+ def initialize(context, source)
114
+ @context = context
115
+ @source = source
116
+ end
117
+
118
+ def modify_child_may_throw(key, v)
119
+ result = @context.resolve(v, source)
120
+ @context = result.context
121
+ result.value
122
+ end
123
+ end
124
+
125
+ def resolve_substitutions(context, source)
126
+ if @resolved
127
+ return Hocon::Impl::ResolveResult.make(context, self)
128
+ end
129
+
130
+ if context.is_restricted_to_child
131
+ # if a list restricts to a child path, then it has no child paths,
132
+ # so nothing to do.
133
+ Hocon::Impl::ResolveResult.make(context, self)
134
+ else
135
+ begin
136
+ modifier = ResolveModifier.new(context, source.push_parent(self))
137
+ value = modify_may_throw(modifier, context.options.allow_unresolved ? nil : ResolveStatus::RESOLVED)
138
+ Hocon::Impl::ResolveResult.make(modifier.context, value)
139
+ rescue NotPossibleToResolve => e
140
+ raise e
141
+ rescue RuntimeError => e
142
+ raise e
143
+ rescue Exception => e
144
+ raise ConfigBugOrBrokenError.new("unexpected exception", e)
145
+ end
146
+ end
147
+ end
148
+
149
+ def relativized(prefix)
150
+ modifier = Class.new do
151
+ include Hocon::Impl::AbstractConfigValue::NoExceptionsModifier
152
+
153
+ # prefix isn't in scope inside of a def, but it is in scope inside of Class.new
154
+ # so manually define a method that has access to prefix
155
+ # I feel dirty
156
+ define_method(:modify_child) do |key, v|
157
+ v.relativized(prefix)
158
+ end
159
+ end
160
+
161
+ modify(modifier.new, resolve_status)
162
+ end
163
+
164
+ def can_equal(other)
165
+ other.is_a?(self.class)
166
+ end
167
+
168
+ def ==(other)
169
+ # note that "origin" is deliberately NOT part of equality
170
+ if other.is_a?(self.class)
171
+ # optimization to avoid unwrapped() for two ConfigList
172
+ can_equal(other) &&
173
+ (value.equal?(other.value) || (value == other.value))
174
+ else
175
+ false
176
+ end
177
+ end
178
+
179
+ def hash
180
+ # note that "origin" is deliberately NOT part of equality
181
+ value.hash
182
+ end
183
+
28
184
  def render_value_to_sb(sb, indent_size, at_root, options)
29
185
  if @value.empty?
30
186
  sb << "[]"
@@ -35,10 +191,13 @@ class Hocon::Impl::SimpleConfigList < Hocon::Impl::AbstractConfigValue
35
191
  end
36
192
  @value.each do |v|
37
193
  if options.origin_comments?
38
- indent(sb, indent_size + 1, options)
39
- sb << "# "
40
- sb << v.origin.description
41
- sb << "\n"
194
+ lines = v.origin.description.split("\n")
195
+ lines.each do |l|
196
+ Hocon::Impl::AbstractConfigValue.indent(sb, indent_size + 1, options)
197
+ sb << "# "
198
+ sb << l
199
+ sb << "\n"
200
+ end
42
201
  end
43
202
  if options.comments?
44
203
  v.origin.comments.each do |comment|
@@ -47,7 +206,7 @@ class Hocon::Impl::SimpleConfigList < Hocon::Impl::AbstractConfigValue
47
206
  sb << "\n"
48
207
  end
49
208
  end
50
- indent(sb, indent_size + 1, options)
209
+ Hocon::Impl::AbstractConfigValue.indent(sb, indent_size + 1, options)
51
210
 
52
211
  v.render_value_to_sb(sb, indent_size + 1, at_root, options)
53
212
  sb << ","
@@ -63,13 +222,128 @@ class Hocon::Impl::SimpleConfigList < Hocon::Impl::AbstractConfigValue
63
222
  if options.formatted?
64
223
  sb.pos = sb.pos - 1 # also chop comma
65
224
  sb << "\n"
66
- indent(sb, indent_size, options)
225
+ Hocon::Impl::AbstractConfigValue.indent(sb, indent_size, options)
67
226
  end
68
227
  sb << "]"
69
228
  end
70
229
  end
71
230
 
231
+ def contains?(o)
232
+ value.include?(o)
233
+ end
234
+
235
+ def include_all?(value_list)
236
+ value_list.all? { |v| @value.include?(v)}
237
+ end
238
+
239
+ def contains_all?(c)
240
+ include_all?(c)
241
+ end
242
+
243
+ def get(index)
244
+ value[index]
245
+ end
246
+
247
+ def index_of(o)
248
+ value.index(o)
249
+ end
250
+
251
+ def is_empty
252
+ empty?
253
+ end
254
+
255
+ # Skipping upstream definition of "iterator", because that's not really a thing
256
+ # in Ruby.
257
+
258
+ def last_index_of(o)
259
+ value.rindex(o)
260
+ end
261
+
262
+ # skipping upstream definitions of "wrapListIterator", "listIterator", and
263
+ # "listIterator(int)", because those don't really apply in Ruby.
264
+
265
+ def sub_list(from_index, to_index)
266
+ value[from_index..to_index]
267
+ end
268
+
269
+ def to_array
270
+ value
271
+ end
272
+
273
+ def we_are_immutable(method)
274
+ Hocon::Impl::UnsupportedOperationError.new("ConfigList is immutable, you can't call List. '#{method}'")
275
+ end
276
+
277
+ def add(e)
278
+ raise we_are_immutable("add")
279
+ end
280
+
281
+ def add_at(index, element)
282
+ raise we_are_immutable("add_at")
283
+ end
284
+
285
+ def add_all(c)
286
+ raise we_are_immutable("add_all")
287
+ end
288
+
289
+ def add_all_at(index, c)
290
+ raise we_are_immutable("add_all_at")
291
+ end
292
+
293
+ def clear
294
+ raise we_are_immutable("clear")
295
+ end
296
+
297
+ def remove(o)
298
+ raise we_are_immutable("remove")
299
+ end
300
+
301
+ def remove_at(i)
302
+ raise we_are_immutable("remove_at")
303
+ end
304
+
305
+ def delete(o)
306
+ raise we_are_immutable("delete")
307
+ end
308
+
309
+ def remove_all(c)
310
+ raise we_are_immutable("remove_all")
311
+ end
312
+
313
+ def retain_all(c)
314
+ raise we_are_immutable("retain_all")
315
+ end
316
+
317
+ def set(index, element)
318
+ raise we_are_immutable("set")
319
+ end
320
+
321
+ def []=(index, element)
322
+ raise we_are_immutable("[]=")
323
+ end
324
+
325
+ def push(e)
326
+ raise we_are_immutable("push")
327
+ end
328
+
329
+ def <<(e)
330
+ raise we_are_immutable("<<")
331
+ end
332
+
72
333
  def new_copy(origin)
73
334
  Hocon::Impl::SimpleConfigList.new(origin, @value)
74
335
  end
336
+
337
+ def concatenate(other)
338
+ combined_origin = Hocon::Impl::SimpleConfigOrigin.merge_two_origins(origin, other.origin)
339
+ combined = value + other.value
340
+ Hocon::Impl::SimpleConfigList.new(combined_origin, combined)
341
+ end
342
+
343
+ # Skipping upstream "writeReplace" until we see that we need it for something
344
+
345
+ def with_origin(origin)
346
+ super(origin)
347
+ end
348
+
75
349
  end