rupkl 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/rupkl/node/amend_expression.rb +48 -0
- data/lib/rupkl/node/any.rb +99 -0
- data/lib/rupkl/node/base.rb +45 -0
- data/lib/rupkl/node/boolean.rb +12 -4
- data/lib/rupkl/node/context.rb +27 -0
- data/lib/rupkl/node/declared_type.rb +32 -0
- data/lib/rupkl/node/dynamic.rb +28 -59
- data/lib/rupkl/node/identifier.rb +16 -6
- data/lib/rupkl/node/listing.rb +61 -0
- data/lib/rupkl/node/mapping.rb +47 -0
- data/lib/rupkl/node/member_finder.rb +55 -0
- data/lib/rupkl/node/member_reference.rb +44 -21
- data/lib/rupkl/node/method_call.rb +64 -0
- data/lib/rupkl/node/method_definition.rb +143 -0
- data/lib/rupkl/node/node_common.rb +76 -0
- data/lib/rupkl/node/null.rb +27 -0
- data/lib/rupkl/node/number.rb +136 -6
- data/lib/rupkl/node/object.rb +369 -73
- data/lib/rupkl/node/operation.rb +97 -60
- data/lib/rupkl/node/pkl_module.rb +16 -28
- data/lib/rupkl/node/reference_resolver.rb +79 -0
- data/lib/rupkl/node/string.rb +388 -18
- data/lib/rupkl/node/struct_common.rb +119 -57
- data/lib/rupkl/node/this.rb +17 -0
- data/lib/rupkl/node/type_common.rb +34 -0
- data/lib/rupkl/node/value_common.rb +18 -9
- data/lib/rupkl/parser/expression.rb +158 -41
- data/lib/rupkl/parser/identifier.rb +2 -2
- data/lib/rupkl/parser/literal.rb +18 -12
- data/lib/rupkl/parser/method.rb +41 -0
- data/lib/rupkl/parser/misc.rb +4 -0
- data/lib/rupkl/parser/object.rb +57 -25
- data/lib/rupkl/parser/pkl_class.rb +28 -8
- data/lib/rupkl/parser/pkl_module.rb +5 -3
- data/lib/rupkl/parser/type.rb +28 -0
- data/lib/rupkl/parser.rb +8 -0
- data/lib/rupkl/pkl_object.rb +26 -6
- data/lib/rupkl/version.rb +1 -1
- data/lib/rupkl.rb +25 -4
- metadata +33 -3
- data/lib/rupkl/node/pkl_class.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7731a56bb62b392639860c5e0f82c2175e8bca4ecd439e8ccffd05d9b223b0f
|
4
|
+
data.tar.gz: 18487cb107c5a47212d185d782f4866d5fc5c0734b893986e4388c003728687d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9d8c2d0d8d9f4976ba804810285344b8f5a6cd308ce1eeff23eb3503feb365c2415d1876c8c879fdf38ca016b01dc849aaeb2e01ae502b9c0e0a44a1a2123ce
|
7
|
+
data.tar.gz: 2bc34ee5b570519a913299dbe5415fe9a7e3dd406b5912f729127ce152c18fd6821f769f9c6df6e677c0c114de935f401584e67e5ae385133aef318810f57ce0
|
data/README.md
CHANGED
@@ -116,7 +116,7 @@ Pkl code snippets used for RSpec examples are originaly from:
|
|
116
116
|
## Copyright & License
|
117
117
|
|
118
118
|
Copyright © 2024 Taichi Ishitani.
|
119
|
-
RuPkl is licensed under the terms of the [MIT License](https://opensource.org/licenses/MIT), see [LICENSE](LICENSE) for further details.
|
119
|
+
RuPkl is licensed under the terms of the [MIT License](https://opensource.org/licenses/MIT), see [LICENSE.txt](LICENSE.txt) for further details.
|
120
120
|
|
121
121
|
## Code of Conduct
|
122
122
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class AmendExpression
|
6
|
+
include NodeCommon
|
7
|
+
|
8
|
+
def initialize(parent, target, bodies, position)
|
9
|
+
super(parent, target, *bodies, position)
|
10
|
+
@target = target
|
11
|
+
@bodies = bodies
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :target
|
15
|
+
attr_reader :bodies
|
16
|
+
|
17
|
+
def evaluate(context = nil)
|
18
|
+
resolve_structure(context).evaluate(context)
|
19
|
+
end
|
20
|
+
|
21
|
+
def resolve_structure(context = nil)
|
22
|
+
t =
|
23
|
+
target
|
24
|
+
.resolve_reference(context)
|
25
|
+
.resolve_structure(context)
|
26
|
+
t.respond_to?(:body) ||
|
27
|
+
begin
|
28
|
+
message = "cannot amend the target type #{t.class.basename}"
|
29
|
+
raise EvaluationError.new(message, position)
|
30
|
+
end
|
31
|
+
do_amend(t.copy(parent))
|
32
|
+
end
|
33
|
+
|
34
|
+
def copy(parent = nil)
|
35
|
+
self.class.new(parent, target.copy, bodies.each(&:copy), position)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def do_amend(target)
|
41
|
+
bodies
|
42
|
+
.map { _1.copy(target).resolve_structure }
|
43
|
+
.then { target.merge!(*_1) }
|
44
|
+
target
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class Any
|
6
|
+
include NodeCommon
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def abstract?
|
10
|
+
@abstract || false
|
11
|
+
end
|
12
|
+
|
13
|
+
def instantiable?
|
14
|
+
!@uninstantiable
|
15
|
+
end
|
16
|
+
|
17
|
+
def class_name
|
18
|
+
@class_name || basename.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
def builtin_property(name)
|
22
|
+
@builtin_properties&.[](name.id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def buildin_method(name)
|
26
|
+
@builtin_methods&.[](name.id)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def abstract_class
|
32
|
+
@abstract = true
|
33
|
+
end
|
34
|
+
|
35
|
+
def uninstantiable_class
|
36
|
+
@uninstantiable = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def klass_name(name)
|
40
|
+
@class_name = name
|
41
|
+
end
|
42
|
+
|
43
|
+
def define_builtin_property(name, &body)
|
44
|
+
(@builtin_properties ||= {})[name] = body
|
45
|
+
end
|
46
|
+
|
47
|
+
def define_builtin_method(name, ...)
|
48
|
+
(@builtin_methods ||= {})[name] = BuiltinMethodDefinition.new(name, ...)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
abstract_class
|
53
|
+
uninstantiable_class
|
54
|
+
|
55
|
+
def property(name)
|
56
|
+
builtin_property(name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def pkl_method(name)
|
60
|
+
buildin_method(name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def null?
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def builtin_property(name)
|
70
|
+
self.class.ancestors.each do |klass|
|
71
|
+
next unless klass.respond_to?(:builtin_property)
|
72
|
+
|
73
|
+
body = klass.builtin_property(name)
|
74
|
+
return instance_exec(&body) if body
|
75
|
+
end
|
76
|
+
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
80
|
+
def buildin_method(name)
|
81
|
+
self.class.ancestors.each do |klass|
|
82
|
+
next unless klass.respond_to?(:buildin_method)
|
83
|
+
|
84
|
+
method = klass.buildin_method(name)
|
85
|
+
return method if method
|
86
|
+
end
|
87
|
+
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def check_positive_number(number)
|
92
|
+
return unless number.value.negative?
|
93
|
+
|
94
|
+
m = "expected a positive number, but got '#{number.value}'"
|
95
|
+
raise EvaluationError.new(m, position)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class Base < PklModule
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super(nil, nil, nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :pkl_classes
|
13
|
+
|
14
|
+
class << self
|
15
|
+
private
|
16
|
+
|
17
|
+
def add_builtin_class(klass)
|
18
|
+
instance.instance_eval do
|
19
|
+
name = klass.class_name
|
20
|
+
(@pkl_classes ||= {})[name] = klass
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
add_builtin_class Any
|
26
|
+
add_builtin_class Boolean
|
27
|
+
add_builtin_class Number
|
28
|
+
add_builtin_class Int
|
29
|
+
add_builtin_class Float
|
30
|
+
add_builtin_class String
|
31
|
+
add_builtin_class Dynamic
|
32
|
+
add_builtin_class Mapping
|
33
|
+
add_builtin_class Listing
|
34
|
+
add_builtin_class PklModule
|
35
|
+
|
36
|
+
define_builtin_property(:NaN) do
|
37
|
+
Float.new(parent, ::Float::NAN, position)
|
38
|
+
end
|
39
|
+
|
40
|
+
define_builtin_property(:Infinity) do
|
41
|
+
Float.new(parent, ::Float::INFINITY, position)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/rupkl/node/boolean.rb
CHANGED
@@ -2,12 +2,10 @@
|
|
2
2
|
|
3
3
|
module RuPkl
|
4
4
|
module Node
|
5
|
-
class Boolean
|
5
|
+
class Boolean < Any
|
6
6
|
include ValueCommon
|
7
7
|
|
8
|
-
|
9
|
-
self
|
10
|
-
end
|
8
|
+
uninstantiable_class
|
11
9
|
|
12
10
|
def undefined_operator?(operator)
|
13
11
|
[:!, :==, :'!=', :'&&', :'||'].none?(operator)
|
@@ -16,6 +14,16 @@ module RuPkl
|
|
16
14
|
def short_circuit?(operator)
|
17
15
|
[operator, value] in [:'&&', false] | [:'||', true]
|
18
16
|
end
|
17
|
+
|
18
|
+
define_builtin_method(:xor, other: Boolean) do |other|
|
19
|
+
result = value ^ other.value
|
20
|
+
Boolean.new(nil, result, position)
|
21
|
+
end
|
22
|
+
|
23
|
+
define_builtin_method(:implies, other: Boolean) do |other|
|
24
|
+
result = !value || other.value
|
25
|
+
Boolean.new(nil, result, position)
|
26
|
+
end
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class Context
|
6
|
+
def initialize(scopes, objects)
|
7
|
+
@scopes = scopes
|
8
|
+
@objects = objects
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :scopes
|
12
|
+
attr_reader :objects
|
13
|
+
|
14
|
+
def push_scope(scope)
|
15
|
+
Context.new([*scopes, scope], objects)
|
16
|
+
end
|
17
|
+
|
18
|
+
def push_object(object)
|
19
|
+
Context.new(scopes, [*objects, object])
|
20
|
+
end
|
21
|
+
|
22
|
+
def pop
|
23
|
+
Context.new(scopes&.slice(..-2), objects&.slice(..-2))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
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
|
data/lib/rupkl/node/dynamic.rb
CHANGED
@@ -2,36 +2,19 @@
|
|
2
2
|
|
3
3
|
module RuPkl
|
4
4
|
module Node
|
5
|
-
class Dynamic
|
5
|
+
class Dynamic < Any
|
6
6
|
include StructCommon
|
7
7
|
|
8
|
-
def
|
9
|
-
@
|
10
|
-
add_members(members, scopes)
|
8
|
+
def properties
|
9
|
+
@body&.properties(visibility: :object)
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
|
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)
|
12
|
+
def entries
|
13
|
+
@body&.entries
|
24
14
|
end
|
25
15
|
|
26
|
-
def
|
27
|
-
|
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
|
16
|
+
def elements
|
17
|
+
@body&.elements
|
35
18
|
end
|
36
19
|
|
37
20
|
def ==(other)
|
@@ -41,58 +24,44 @@ module RuPkl
|
|
41
24
|
match_members?(elements, other.elements, true)
|
42
25
|
end
|
43
26
|
|
44
|
-
def undefined_operator?(operator)
|
45
|
-
[:[], :==, :'!='].none?(operator)
|
46
|
-
end
|
47
|
-
|
48
27
|
def find_by_key(key)
|
49
28
|
find_entry(key) || find_element(key)
|
50
29
|
end
|
51
30
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
31
|
+
define_builtin_method(:length) do
|
32
|
+
result = elements&.size || 0
|
33
|
+
Int.new(nil, result, position)
|
34
|
+
end
|
56
35
|
|
57
|
-
|
58
|
-
|
59
|
-
|
36
|
+
define_builtin_method(:hasProperty, name: String) do |name|
|
37
|
+
result = find_property(name.value.to_sym) && true || false
|
38
|
+
Boolean.new(nil, result, position)
|
60
39
|
end
|
61
40
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
else add_element(m)
|
41
|
+
define_builtin_method(:getProperty, name: String) do |name|
|
42
|
+
find_property(name.value.to_sym) ||
|
43
|
+
begin
|
44
|
+
m = "cannot find property '#{name.value}'"
|
45
|
+
raise EvaluationError.new(m, position)
|
68
46
|
end
|
69
|
-
end
|
70
47
|
end
|
71
48
|
|
72
|
-
|
73
|
-
|
49
|
+
define_builtin_method(:getPropertyOrNull, name: String) do |name|
|
50
|
+
find_property(name.value.to_sym) || Null.new(nil, position)
|
74
51
|
end
|
75
52
|
|
76
|
-
|
77
|
-
add_hash_member((@entries ||= []), member, :key)
|
78
|
-
end
|
53
|
+
private
|
79
54
|
|
80
|
-
def
|
81
|
-
|
55
|
+
def properties_not_allowed?
|
56
|
+
false
|
82
57
|
end
|
83
58
|
|
84
|
-
def
|
85
|
-
|
86
|
-
&.find { _1.key == key }
|
87
|
-
&.then(&:value)
|
59
|
+
def entries_not_allowed?
|
60
|
+
false
|
88
61
|
end
|
89
62
|
|
90
|
-
def
|
91
|
-
|
92
|
-
return nil unless index.value.is_a?(::Integer)
|
93
|
-
|
94
|
-
elements
|
95
|
-
.find.with_index { |_, i| i == index.value }
|
63
|
+
def elements_not_allowed?
|
64
|
+
false
|
96
65
|
end
|
97
66
|
end
|
98
67
|
end
|
@@ -3,17 +3,27 @@
|
|
3
3
|
module RuPkl
|
4
4
|
module Node
|
5
5
|
class Identifier
|
6
|
-
|
6
|
+
include NodeCommon
|
7
|
+
|
8
|
+
def initialize(parent, id, position)
|
9
|
+
super(parent, position)
|
7
10
|
@id = id
|
8
|
-
@position = position
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
attr_reader :id
|
14
|
+
|
15
|
+
def copy(parent = nil)
|
16
|
+
self.class.new(parent, id, position)
|
13
17
|
end
|
14
18
|
|
15
|
-
|
16
|
-
|
19
|
+
def ==(other)
|
20
|
+
id ==
|
21
|
+
if other.respond_to?(:id)
|
22
|
+
other.id
|
23
|
+
else
|
24
|
+
other
|
25
|
+
end
|
26
|
+
end
|
17
27
|
end
|
18
28
|
end
|
19
29
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class Listing < Any
|
6
|
+
include StructCommon
|
7
|
+
|
8
|
+
def elements
|
9
|
+
@body&.elements
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
other.instance_of?(self.class) &&
|
14
|
+
match_members?(elements, other.elements, true)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_by_key(key)
|
18
|
+
find_element(key)
|
19
|
+
end
|
20
|
+
|
21
|
+
define_builtin_property(:isEmpty) do
|
22
|
+
result = elements.nil? || elements.empty?
|
23
|
+
Boolean.new(self, result, position)
|
24
|
+
end
|
25
|
+
|
26
|
+
define_builtin_property(:length) do
|
27
|
+
result = elements&.size || 0
|
28
|
+
Int.new(self, result, position)
|
29
|
+
end
|
30
|
+
|
31
|
+
define_builtin_property(:isDistinct) do
|
32
|
+
result =
|
33
|
+
elements.nil? ||
|
34
|
+
elements.all? { |lhs| elements.one? { |rhs| rhs == lhs } }
|
35
|
+
Boolean.new(self, result || elements.nil?, position)
|
36
|
+
end
|
37
|
+
|
38
|
+
define_builtin_property(:distinct) do
|
39
|
+
result =
|
40
|
+
elements
|
41
|
+
&.each_with_object([]) { |e, l| l << e unless l.include?(e) }
|
42
|
+
body = ObjectBody.new(nil, result, position)
|
43
|
+
Listing.new(self, body, position)
|
44
|
+
end
|
45
|
+
|
46
|
+
define_builtin_method(:join, separator: String) do |separator|
|
47
|
+
result =
|
48
|
+
elements
|
49
|
+
&.map { _1.value.to_string }
|
50
|
+
&.join(separator.value)
|
51
|
+
String.new(nil, result || '', nil, position)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def elements_not_allowed?
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
class Mapping < Any
|
6
|
+
include StructCommon
|
7
|
+
|
8
|
+
def entries
|
9
|
+
@body&.entries
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
other.instance_of?(self.class) &&
|
14
|
+
match_members?(entries, other.entries, false)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_by_key(key)
|
18
|
+
find_entry(key)
|
19
|
+
end
|
20
|
+
|
21
|
+
define_builtin_property(:isEmpty) do
|
22
|
+
result = entries.nil? || entries.empty?
|
23
|
+
Boolean.new(self, result, position)
|
24
|
+
end
|
25
|
+
|
26
|
+
define_builtin_property(:length) do
|
27
|
+
result = entries&.size || 0
|
28
|
+
Int.new(self, result, position)
|
29
|
+
end
|
30
|
+
|
31
|
+
define_builtin_method(:containsKey, key: Any) do |key|
|
32
|
+
result = find_entry(key) && true || false
|
33
|
+
Boolean.new(nil, result, position)
|
34
|
+
end
|
35
|
+
|
36
|
+
define_builtin_method(:getOrNull, key: Any) do |key|
|
37
|
+
find_entry(key) || Null.new(nil, position)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def entries_not_allowed?
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuPkl
|
4
|
+
module Node
|
5
|
+
module MemberFinder
|
6
|
+
def property(name)
|
7
|
+
value = find_property(name)
|
8
|
+
return value if value
|
9
|
+
|
10
|
+
super if self.class <= Any
|
11
|
+
end
|
12
|
+
|
13
|
+
def pkl_method(name)
|
14
|
+
method = find_pkl_method(name)
|
15
|
+
return method if method
|
16
|
+
|
17
|
+
super if self.class <= Any
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def find_property(name)
|
23
|
+
return unless respond_to?(:properties)
|
24
|
+
|
25
|
+
properties
|
26
|
+
&.find { _1.name == name }
|
27
|
+
&.value
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_entry(key)
|
31
|
+
return unless respond_to?(:entries)
|
32
|
+
|
33
|
+
entries
|
34
|
+
&.find { _1.key == key }
|
35
|
+
&.value
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_element(index)
|
39
|
+
return unless respond_to?(:elements)
|
40
|
+
return unless elements
|
41
|
+
return unless index.value.is_a?(::Integer)
|
42
|
+
|
43
|
+
elements
|
44
|
+
.find.with_index { |_, i| i == index.value }
|
45
|
+
&.value
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_pkl_method(name)
|
49
|
+
return unless respond_to?(:pkl_methods)
|
50
|
+
|
51
|
+
pkl_methods&.find { _1.name == name }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|