dsl_compose 2.15.3 → 2.15.4
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/CHANGELOG.md +7 -0
- data/lib/dsl_compose/composer.rb +3 -1
- data/lib/dsl_compose/dsl/arguments/argument.rb +1 -1
- data/lib/dsl_compose/dsl/dsl_method.rb +1 -1
- data/lib/dsl_compose/dsl.rb +0 -2
- data/lib/dsl_compose/interpreter/execution/arguments.rb +31 -29
- data/lib/dsl_compose/interpreter/execution/method_calls/method_call.rb +6 -4
- data/lib/dsl_compose/interpreter/execution/method_calls.rb +5 -3
- data/lib/dsl_compose/interpreter/execution.rb +13 -9
- data/lib/dsl_compose/interpreter/interpreter_error.rb +18 -0
- data/lib/dsl_compose/interpreter.rb +9 -9
- data/lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser/for_method_parser.rb +10 -0
- data/lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser.rb +8 -0
- data/lib/dsl_compose/version.rb +1 -1
- data/lib/dsl_compose.rb +1 -0
- data/sig/dsl_compose/interpreter/execution/arguments.rbs +8 -7
- data/sig/dsl_compose/interpreter/execution/method_calls/method_call.rbs +5 -4
- data/sig/dsl_compose/interpreter/execution/method_calls.rbs +1 -1
- data/sig/dsl_compose/interpreter/execution.rbs +8 -3
- data/sig/dsl_compose/interpreter/interpreter_error.rbs +11 -0
- data/sig/dsl_compose/interpreter.rbs +1 -4
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c630022da7a35c7bb15fcb5847b3036dc21e45b0afd950edb4fa6bb205147f4
|
4
|
+
data.tar.gz: ed8a49a2b1ec77a4a741a1eeaddd4fb52019ad307cf96c2d8f531f1df4d24a7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96aa671032ce71ce1d7639ab8fbf25d7e3f17d58f3b822a1601b6af99808502083d284b4f6cbea7541dc271a8d1dcf0e005f98d066852d86a9b88d3e194125cb
|
7
|
+
data.tar.gz: 5d17dfa43b30dae88aebdff5bc192d083fa3cf668e896a9fb71c314304b9b8320a4dfb6444b1055b8fde0d0da45d0285d38982ae7cbcf006d93f1c634d86ca38
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.15.4](https://github.com/craigulliott/dsl_compose/compare/v2.15.3...v2.15.4) (2023-10-04)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* passing context along with where DSL's were defined, and then including this context in error messages ([5238a3d](https://github.com/craigulliott/dsl_compose/commit/5238a3daa8c1a32e77783d56c7c429b6335995bd))
|
9
|
+
|
3
10
|
## [2.15.3](https://github.com/craigulliott/dsl_compose/compare/v2.15.2...v2.15.3) (2023-10-03)
|
4
11
|
|
5
12
|
|
data/lib/dsl_compose/composer.rb
CHANGED
@@ -48,9 +48,11 @@ module DSLCompose
|
|
48
48
|
|
49
49
|
# add a singleton method with the name of this new DSL onto our class, this is how our new DSL will be accessed
|
50
50
|
define_singleton_method name do |*args, &block|
|
51
|
+
called_from = caller(1..1).first
|
52
|
+
|
51
53
|
# when it is called, we process this new dynamic DSL with the interpreter
|
52
54
|
# `self` here is the class in which the dsl is being used, not the class in which the DSL was defined
|
53
|
-
interpreter.execute_dsl self, dsl, *args, &block
|
55
|
+
interpreter.execute_dsl self, dsl, called_from, *args, &block
|
54
56
|
end
|
55
57
|
|
56
58
|
end
|
@@ -127,7 +127,7 @@ module DSLCompose
|
|
127
127
|
Interpreter.new(self).instance_eval(&block)
|
128
128
|
end
|
129
129
|
rescue => e
|
130
|
-
raise e, "Error defining argument #{name}
|
130
|
+
raise e, "Error while defining argument #{name}\n#{e.message}", e.backtrace
|
131
131
|
end
|
132
132
|
|
133
133
|
# Set the description for this Argument to the provided value.
|
@@ -60,7 +60,7 @@ module DSLCompose
|
|
60
60
|
Interpreter.new(self).instance_eval(&block)
|
61
61
|
end
|
62
62
|
rescue => e
|
63
|
-
raise e, "Error defining method #{name}
|
63
|
+
raise e, "Error while defining method #{name}\n#{e.message}", e.backtrace
|
64
64
|
end
|
65
65
|
|
66
66
|
# Set the description for this DSLMethod to the provided value.
|
data/lib/dsl_compose/dsl.rb
CHANGED
@@ -83,8 +83,6 @@ module DSLCompose
|
|
83
83
|
else
|
84
84
|
raise NoBlockProvidedError, "No block was provided for this DSL"
|
85
85
|
end
|
86
|
-
rescue => e
|
87
|
-
raise e, "Error defining DSL #{@name} on #{@klass}: #{e.message}", e.backtrace
|
88
86
|
end
|
89
87
|
|
90
88
|
# Set the description for this DSL to the provided value.
|
@@ -4,25 +4,27 @@ module DSLCompose
|
|
4
4
|
class Interpreter
|
5
5
|
class Execution
|
6
6
|
class Arguments
|
7
|
-
class MissingRequiredArgumentsError <
|
7
|
+
class MissingRequiredArgumentsError < InterpreterError
|
8
8
|
end
|
9
9
|
|
10
|
-
class TooManyArgumentsError <
|
10
|
+
class TooManyArgumentsError < InterpreterError
|
11
11
|
end
|
12
12
|
|
13
|
-
class OptionalArgumentsShouldBeHashError <
|
13
|
+
class OptionalArgumentsShouldBeHashError < InterpreterError
|
14
14
|
end
|
15
15
|
|
16
|
-
class InvalidArgumentTypeError <
|
16
|
+
class InvalidArgumentTypeError < InterpreterError
|
17
17
|
end
|
18
18
|
|
19
|
-
class ArrayNotValidError <
|
19
|
+
class ArrayNotValidError < InterpreterError
|
20
20
|
end
|
21
21
|
|
22
22
|
attr_reader :arguments
|
23
|
+
attr_reader :called_from
|
23
24
|
|
24
|
-
def initialize arguments, *args
|
25
|
+
def initialize arguments, called_from, *args
|
25
26
|
@arguments = {}
|
27
|
+
@called_from = called_from
|
26
28
|
|
27
29
|
required_argument_count = arguments.required_arguments.count
|
28
30
|
required_non_kwarg_argument_count = arguments.required_arguments.count { |a| !a.kwarg }
|
@@ -40,7 +42,7 @@ module DSLCompose
|
|
40
42
|
required_kwargs = arguments.required_arguments.filter { |a| a.kwarg }
|
41
43
|
|
42
44
|
if required_kwargs.any? && !all_kwargs.is_a?(Hash)
|
43
|
-
raise MissingRequiredArgumentsError
|
45
|
+
raise MissingRequiredArgumentsError.new("This has required keyword arguments, but no keyword arguments were provided", called_from)
|
44
46
|
end
|
45
47
|
|
46
48
|
required_kwargs.each do |required_kwarg|
|
@@ -51,7 +53,7 @@ module DSLCompose
|
|
51
53
|
# left with only the optional args
|
52
54
|
all_kwargs.delete required_kwarg.name
|
53
55
|
else
|
54
|
-
raise MissingRequiredArgumentsError
|
56
|
+
raise MissingRequiredArgumentsError.new("The required kwarg `#{required_kwarg.name}` was not provided", called_from)
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
@@ -61,12 +63,12 @@ module DSLCompose
|
|
61
63
|
|
62
64
|
# assert that a value is provided for every required argument
|
63
65
|
unless required_argument_count == required_args.count
|
64
|
-
raise MissingRequiredArgumentsError
|
66
|
+
raise MissingRequiredArgumentsError.new("This requires #{required_non_kwarg_argument_count} arguments, but only #{required_args.count} were provided", called_from)
|
65
67
|
end
|
66
68
|
|
67
69
|
# assert that too many arguments have not been provided
|
68
70
|
if args.count > required_argument_count + (has_optional_arguments ? 1 : 0)
|
69
|
-
raise TooManyArgumentsError
|
71
|
+
raise TooManyArgumentsError.new("Too many arguments provided", called_from)
|
70
72
|
end
|
71
73
|
|
72
74
|
# Assume all optonal arguments are their defaults (except booleans, which default to false).
|
@@ -88,7 +90,7 @@ module DSLCompose
|
|
88
90
|
# asset that, if provided, then the optional argument (always the last one) is a Hash
|
89
91
|
if has_optional_arguments && !optional_arg.nil?
|
90
92
|
unless optional_arg.is_a? Hash
|
91
|
-
raise OptionalArgumentsShouldBeHashError
|
93
|
+
raise OptionalArgumentsShouldBeHashError.new("If provided, then the optional arguments must be last, and be represented as a Hash", called_from)
|
92
94
|
end
|
93
95
|
|
94
96
|
# assert the each provided optional argument is valid
|
@@ -110,7 +112,7 @@ module DSLCompose
|
|
110
112
|
end
|
111
113
|
|
112
114
|
if optional_arg_value.is_a?(Array) && !optional_argument.array
|
113
|
-
raise ArrayNotValidError
|
115
|
+
raise ArrayNotValidError.new("An array was provided to an argument which does not accept an array of values", called_from)
|
114
116
|
end
|
115
117
|
|
116
118
|
# to simplify the code, we always process the reset of the validations as an array, even
|
@@ -121,38 +123,38 @@ module DSLCompose
|
|
121
123
|
case optional_argument.type
|
122
124
|
when :integer
|
123
125
|
unless value.is_a? Integer
|
124
|
-
raise InvalidArgumentTypeError
|
126
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not an Integer", called_from)
|
125
127
|
end
|
126
128
|
optional_argument.validate_integer! value
|
127
129
|
|
128
130
|
when :float
|
129
131
|
# float allows either floats or integers
|
130
132
|
unless value.is_a?(Float) || value.is_a?(Integer)
|
131
|
-
raise InvalidArgumentTypeError
|
133
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not an Float or Integer", called_from)
|
132
134
|
end
|
133
135
|
optional_argument.validate_float! value
|
134
136
|
|
135
137
|
when :symbol
|
136
138
|
unless value.is_a? Symbol
|
137
|
-
raise InvalidArgumentTypeError
|
139
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a Symbol", called_from)
|
138
140
|
end
|
139
141
|
optional_argument.validate_symbol! value
|
140
142
|
|
141
143
|
when :string
|
142
144
|
unless value.is_a? String
|
143
|
-
raise InvalidArgumentTypeError
|
145
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a String", called_from)
|
144
146
|
end
|
145
147
|
optional_argument.validate_string! value
|
146
148
|
|
147
149
|
when :boolean
|
148
150
|
unless value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
149
|
-
raise InvalidArgumentTypeError
|
151
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a boolean", called_from)
|
150
152
|
end
|
151
153
|
optional_argument.validate_boolean! value
|
152
154
|
|
153
155
|
when :class
|
154
156
|
unless value.is_a?(ClassCoerce)
|
155
|
-
raise InvalidArgumentTypeError
|
157
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a class coerce (String)", called_from)
|
156
158
|
end
|
157
159
|
optional_argument.validate_class! value
|
158
160
|
|
@@ -160,7 +162,7 @@ module DSLCompose
|
|
160
162
|
optional_argument.validate_object! value
|
161
163
|
|
162
164
|
else
|
163
|
-
raise InvalidArgumentTypeError
|
165
|
+
raise InvalidArgumentTypeError.new("The argument value `#{value}` is not a supported type", called_from)
|
164
166
|
end
|
165
167
|
end
|
166
168
|
|
@@ -174,7 +176,7 @@ module DSLCompose
|
|
174
176
|
optional_arg_value
|
175
177
|
end
|
176
178
|
rescue => e
|
177
|
-
raise e, "Error processing optional argument #{optional_argument_name}
|
179
|
+
raise e, "Error processing optional argument #{optional_argument_name}\n#{e.message}", e.backtrace
|
178
180
|
end
|
179
181
|
|
180
182
|
end
|
@@ -200,7 +202,7 @@ module DSLCompose
|
|
200
202
|
end
|
201
203
|
|
202
204
|
if required_arg_value.is_a?(Array) && !required_argument.array
|
203
|
-
raise ArrayNotValidError
|
205
|
+
raise ArrayNotValidError.new("An array was provided to an argument which does not accept an array of values", called_from)
|
204
206
|
end
|
205
207
|
|
206
208
|
# to simplify the code, we always process the reset of the validations as an array, even
|
@@ -211,38 +213,38 @@ module DSLCompose
|
|
211
213
|
case required_argument.type
|
212
214
|
when :integer
|
213
215
|
unless value.is_a? Integer
|
214
|
-
raise InvalidArgumentTypeError
|
216
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not an Integer", called_from)
|
215
217
|
end
|
216
218
|
required_argument.validate_integer! value
|
217
219
|
|
218
220
|
when :float
|
219
221
|
# float allows either floats or integers
|
220
222
|
unless value.is_a?(Float) || value.is_a?(Integer)
|
221
|
-
raise InvalidArgumentTypeError
|
223
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not an Float or Integer", called_from)
|
222
224
|
end
|
223
225
|
required_argument.validate_float! value
|
224
226
|
|
225
227
|
when :symbol
|
226
228
|
unless value.is_a? Symbol
|
227
|
-
raise InvalidArgumentTypeError
|
229
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a Symbol", called_from)
|
228
230
|
end
|
229
231
|
required_argument.validate_symbol! value
|
230
232
|
|
231
233
|
when :string
|
232
234
|
unless value.is_a? String
|
233
|
-
raise InvalidArgumentTypeError
|
235
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a String", called_from)
|
234
236
|
end
|
235
237
|
required_argument.validate_string! value
|
236
238
|
|
237
239
|
when :boolean
|
238
240
|
unless value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
239
|
-
raise InvalidArgumentTypeError
|
241
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a boolean", called_from)
|
240
242
|
end
|
241
243
|
required_argument.validate_boolean! value
|
242
244
|
|
243
245
|
when :class
|
244
246
|
unless value.is_a?(ClassCoerce)
|
245
|
-
raise InvalidArgumentTypeError
|
247
|
+
raise InvalidArgumentTypeError.new("`#{value}` is not a class coerce (String)", called_from)
|
246
248
|
end
|
247
249
|
required_argument.validate_class! value
|
248
250
|
|
@@ -250,7 +252,7 @@ module DSLCompose
|
|
250
252
|
required_argument.validate_object! value
|
251
253
|
|
252
254
|
else
|
253
|
-
raise InvalidArgumentTypeError
|
255
|
+
raise InvalidArgumentTypeError.new("The argument `#{value}` is not a supported type", called_from)
|
254
256
|
end
|
255
257
|
end
|
256
258
|
|
@@ -264,7 +266,7 @@ module DSLCompose
|
|
264
266
|
required_arg_value
|
265
267
|
end
|
266
268
|
rescue => e
|
267
|
-
raise e, "Error processing required argument #{argument_name}
|
269
|
+
raise e, "Error processing required argument #{argument_name}\n#{e.message}", e.backtrace
|
268
270
|
end
|
269
271
|
end
|
270
272
|
|
@@ -5,15 +5,17 @@ module DSLCompose
|
|
5
5
|
class Execution
|
6
6
|
class MethodCalls
|
7
7
|
class MethodCall
|
8
|
-
class InvalidDescriptionError <
|
8
|
+
class InvalidDescriptionError < InterpreterError
|
9
9
|
end
|
10
10
|
|
11
11
|
attr_reader :dsl_method
|
12
|
+
attr_reader :called_from
|
12
13
|
attr_reader :arguments
|
13
14
|
|
14
|
-
def initialize dsl_method, *args, &block
|
15
|
+
def initialize dsl_method, called_from, *args, &block
|
15
16
|
@dsl_method = dsl_method
|
16
|
-
@
|
17
|
+
@called_from = called_from
|
18
|
+
@arguments = Arguments.new(dsl_method.arguments, called_from, *args)
|
17
19
|
end
|
18
20
|
|
19
21
|
def method_name
|
@@ -30,7 +32,7 @@ module DSLCompose
|
|
30
32
|
# generate documentation
|
31
33
|
def add_parser_usage_note note
|
32
34
|
unless note.is_a?(String) && note.strip.length > 0
|
33
|
-
raise InvalidDescriptionError
|
35
|
+
raise InvalidDescriptionError.new("The parser usage description `#{note}` is invalid, it must be of type string and have length greater than 0", @called_from)
|
34
36
|
end
|
35
37
|
|
36
38
|
@parser_usage_notes ||= []
|
@@ -14,16 +14,18 @@ module DSLCompose
|
|
14
14
|
@method_calls.filter { |mc| mc.method_name == method_name }.any?
|
15
15
|
end
|
16
16
|
|
17
|
-
def add_method_call(dsl_method, ...)
|
17
|
+
def add_method_call(dsl_method, called_from, ...)
|
18
18
|
# make sure we always have a variable which can be used in the exception message
|
19
|
+
# set to nil first, so that if we get an exception while setting them
|
20
|
+
# it wont break the error message generation
|
19
21
|
dsl_method_name = nil
|
20
22
|
dsl_method_name = dsl_method.name
|
21
23
|
|
22
|
-
method_call = MethodCall.new(dsl_method, ...)
|
24
|
+
method_call = MethodCall.new(dsl_method, called_from, ...)
|
23
25
|
@method_calls << method_call
|
24
26
|
method_call
|
25
27
|
rescue => e
|
26
|
-
raise e, "Error while executing method #{dsl_method_name}
|
28
|
+
raise e, "Error while executing method #{dsl_method_name}\n#{e.message}", e.backtrace
|
27
29
|
end
|
28
30
|
|
29
31
|
def method_calls_by_name method_name
|
@@ -3,26 +3,28 @@
|
|
3
3
|
module DSLCompose
|
4
4
|
class Interpreter
|
5
5
|
class Execution
|
6
|
-
class MethodIsUniqueError <
|
6
|
+
class MethodIsUniqueError < InterpreterError
|
7
7
|
end
|
8
8
|
|
9
|
-
class RequiredMethodNotCalledError <
|
9
|
+
class RequiredMethodNotCalledError < InterpreterError
|
10
10
|
end
|
11
11
|
|
12
|
-
class InvalidDescriptionError <
|
12
|
+
class InvalidDescriptionError < InterpreterError
|
13
13
|
end
|
14
14
|
|
15
15
|
attr_reader :dsl
|
16
|
+
attr_reader :called_from
|
16
17
|
attr_reader :klass
|
17
18
|
attr_reader :method_calls
|
18
19
|
attr_reader :arguments
|
19
20
|
|
20
21
|
# execute/process a dynamically defined DSL
|
21
|
-
def initialize klass, dsl, *args, &block
|
22
|
+
def initialize klass, dsl, called_from, *args, &block
|
22
23
|
@klass = klass
|
23
24
|
@dsl = dsl
|
25
|
+
@called_from = called_from
|
24
26
|
@method_calls = MethodCalls.new
|
25
|
-
@arguments = Arguments.new(dsl.arguments, *args)
|
27
|
+
@arguments = Arguments.new(dsl.arguments, called_from, *args)
|
26
28
|
|
27
29
|
# dynamically process the DSL by calling the provided block
|
28
30
|
# all methods executions will be caught and processed by the method_missing method below
|
@@ -34,7 +36,7 @@ module DSLCompose
|
|
34
36
|
dsl.required_dsl_methods.each do |dsl_method|
|
35
37
|
unless @method_calls.method_called? dsl_method.name
|
36
38
|
dsl_method_name = dsl_method&.name
|
37
|
-
raise RequiredMethodNotCalledError
|
39
|
+
raise RequiredMethodNotCalledError.new("The method #{dsl_method_name} is required, but was not called within this DSL", called_from)
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
@@ -43,7 +45,7 @@ module DSLCompose
|
|
43
45
|
# generate documentation
|
44
46
|
def add_parser_usage_note note
|
45
47
|
unless note.is_a?(String) && note.strip.length > 0
|
46
|
-
raise InvalidDescriptionError
|
48
|
+
raise InvalidDescriptionError.new("The parser usage description `#{note}` is invalid, it must be of type string and have length greater than 0", called_from)
|
47
49
|
end
|
48
50
|
|
49
51
|
@parser_usage_notes ||= []
|
@@ -60,15 +62,17 @@ module DSLCompose
|
|
60
62
|
|
61
63
|
# catch and process any method calls within the DSL block
|
62
64
|
def method_missing(method_name, ...)
|
65
|
+
called_from = caller(1..1).first
|
66
|
+
|
63
67
|
# if the method does not exist, then this will raise a MethodDoesNotExistError
|
64
68
|
dsl_method = @dsl.dsl_method method_name
|
65
69
|
|
66
70
|
# if the method is unique, then it can only be called once per DSL
|
67
71
|
if dsl_method.unique? && @method_calls.method_called?(method_name)
|
68
|
-
raise MethodIsUniqueError
|
72
|
+
raise MethodIsUniqueError.new("This method `#{method_name}` is unique and can only be called once within this DSL", called_from)
|
69
73
|
end
|
70
74
|
|
71
|
-
@method_calls.add_method_call(dsl_method, ...)
|
75
|
+
@method_calls.add_method_call(dsl_method, called_from, ...)
|
72
76
|
end
|
73
77
|
|
74
78
|
def respond_to_missing?(method_name, *args)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSLCompose
|
4
|
+
class Interpreter
|
5
|
+
class InterpreterError < StandardError
|
6
|
+
attr_reader :original_context
|
7
|
+
|
8
|
+
def initialize(message, original_context)
|
9
|
+
super(message)
|
10
|
+
@original_context = original_context
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"#{super}\ndsl source: #{@original_context}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -4,10 +4,7 @@ module DSLCompose
|
|
4
4
|
# The class is reponsible for parsing and executing a dynamic DSL (dynamic DSLs are
|
5
5
|
# created using the DSLCompose::DSL class).
|
6
6
|
class Interpreter
|
7
|
-
class
|
8
|
-
end
|
9
|
-
|
10
|
-
class InvalidDescriptionError < StandardError
|
7
|
+
class InvalidDescriptionError < InterpreterError
|
11
8
|
end
|
12
9
|
|
13
10
|
# A dynamic DSL can be used multiple times on the same class, each time the DSL is used
|
@@ -23,7 +20,7 @@ module DSLCompose
|
|
23
20
|
# generate documentation
|
24
21
|
def add_parser_usage_note child_class, note
|
25
22
|
unless note.is_a?(String) && note.strip.length > 0
|
26
|
-
raise InvalidDescriptionError
|
23
|
+
raise InvalidDescriptionError.new("The parser usage description `#{note}` is invalid, it must be of type string and have length greater than 0", called_from)
|
27
24
|
end
|
28
25
|
@parser_usage_notes ||= {}
|
29
26
|
@parser_usage_notes[child_class] ||= []
|
@@ -40,20 +37,23 @@ module DSLCompose
|
|
40
37
|
# Execute/process a dynamically defined DSL on a class.
|
41
38
|
# `klass` is the class in which the DSL is being used, not
|
42
39
|
# the class in which the DSL was defined.
|
43
|
-
def execute_dsl(klass, dsl, ...)
|
40
|
+
def execute_dsl(klass, dsl, called_from, ...)
|
44
41
|
# make sure we have these variables for the exception message below
|
42
|
+
# set to nil first, so that if we get an exception while setting them
|
43
|
+
# it wont break the error message generation
|
45
44
|
class_name = nil
|
46
|
-
class_name = klass.name
|
47
45
|
dsl_name = nil
|
46
|
+
class_name = klass.name
|
48
47
|
dsl_name = dsl.name
|
49
48
|
|
50
|
-
execution = Execution.new(klass, dsl, ...)
|
49
|
+
execution = Execution.new(klass, dsl, called_from, ...)
|
51
50
|
@executions << execution
|
52
51
|
execution
|
53
52
|
rescue => e
|
54
|
-
raise e, "Error
|
53
|
+
raise e, "Error while defining DSL #{dsl_name} for class #{class_name}:\n#{e.message}", e.backtrace
|
55
54
|
end
|
56
55
|
|
56
|
+
#
|
57
57
|
# Returns an array of all executions for a given class.
|
58
58
|
def class_executions klass
|
59
59
|
@executions.filter { |e| e.klass == klass }
|
@@ -28,6 +28,8 @@ module DSLCompose
|
|
28
28
|
@dsl_execution = dsl_execution
|
29
29
|
@method_names = method_names
|
30
30
|
|
31
|
+
dsl_name = dsl_execution.dsl.name
|
32
|
+
|
31
33
|
# assert that a block was provided
|
32
34
|
unless block
|
33
35
|
raise NoBlockProvided
|
@@ -100,6 +102,14 @@ module DSLCompose
|
|
100
102
|
|
101
103
|
# yeild the block in the context of this class
|
102
104
|
instance_exec(**args, &block)
|
105
|
+
rescue => e
|
106
|
+
# if this is an InterpreterError, then it already has the called_from metadata
|
107
|
+
# just continue raising the original error
|
108
|
+
if e.is_a? Interpreter::InterpreterError
|
109
|
+
raise
|
110
|
+
end
|
111
|
+
# otherwise, decorate the error with where the DSL was defined
|
112
|
+
raise e, "#{e.message}\nparsing class: #{child_class.name}\ndsl name: #{dsl_name}\ndsl method name: #{method_name}\ndsl source: #{method_call.called_from}", e.backtrace
|
103
113
|
end
|
104
114
|
end
|
105
115
|
end
|
@@ -108,6 +108,14 @@ module DSLCompose
|
|
108
108
|
@dsl_execution = dsl_execution
|
109
109
|
# yield the block in the context of this class
|
110
110
|
instance_exec(**args, &block)
|
111
|
+
rescue => e
|
112
|
+
# if this is an InterpreterError, then it already has the called_from metadata
|
113
|
+
# just continue raising the original error
|
114
|
+
if e.is_a? Interpreter::InterpreterError
|
115
|
+
raise
|
116
|
+
end
|
117
|
+
# otherwise, decorate the error with where the DSL was defined
|
118
|
+
raise e, "#{e.message}\nparsing class: #{child_class.name}\ndsl name: #{dsl_name}\ndsl source: #{dsl_execution.called_from}", e.backtrace
|
111
119
|
end
|
112
120
|
end
|
113
121
|
end
|
data/lib/dsl_compose/version.rb
CHANGED
data/lib/dsl_compose.rb
CHANGED
@@ -34,6 +34,7 @@ require "dsl_compose/reader/execution_reader/arguments_reader"
|
|
34
34
|
|
35
35
|
require "dsl_compose/reader_base"
|
36
36
|
|
37
|
+
require "dsl_compose/interpreter/interpreter_error"
|
37
38
|
require "dsl_compose/interpreter/execution/method_calls/method_call"
|
38
39
|
require "dsl_compose/interpreter/execution/method_calls"
|
39
40
|
require "dsl_compose/interpreter/execution/arguments"
|
@@ -4,23 +4,24 @@ module DSLCompose
|
|
4
4
|
class Execution
|
5
5
|
class Arguments
|
6
6
|
attr_reader arguments: Hash[untyped, untyped]
|
7
|
-
|
7
|
+
attr_reader called_from: String
|
8
|
+
|
9
|
+
def initialize: (untyped arguments, String called_from, *untyped args) -> void
|
8
10
|
def to_h: -> Hash[untyped, untyped]
|
9
11
|
|
10
|
-
class MissingRequiredArgumentsError <
|
11
|
-
def initialize: (untyped required_count, untyped provided_count) -> void
|
12
|
+
class MissingRequiredArgumentsError < InterpreterError
|
12
13
|
end
|
13
14
|
|
14
|
-
class TooManyArgumentsError <
|
15
|
+
class TooManyArgumentsError < InterpreterError
|
15
16
|
end
|
16
17
|
|
17
|
-
class OptionalArgumentsShouldBeHashError <
|
18
|
+
class OptionalArgumentsShouldBeHashError < InterpreterError
|
18
19
|
end
|
19
20
|
|
20
|
-
class InvalidArgumentTypeError <
|
21
|
+
class InvalidArgumentTypeError < InterpreterError
|
21
22
|
end
|
22
23
|
|
23
|
-
class ArrayNotValidError <
|
24
|
+
class ArrayNotValidError < InterpreterError
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
@@ -4,21 +4,22 @@ module DSLCompose
|
|
4
4
|
class Execution
|
5
5
|
class MethodCalls
|
6
6
|
class MethodCall
|
7
|
-
class InvalidDescriptionError < StandardError
|
8
|
-
end
|
9
|
-
|
10
7
|
@method_call: MethodCall
|
11
8
|
@parser_usage_notes: Array[String]
|
12
9
|
|
13
10
|
attr_reader dsl_method: DSL::DSLMethod
|
11
|
+
attr_reader called_from: String
|
14
12
|
attr_reader arguments: Arguments
|
15
13
|
|
16
|
-
def initialize: (DSL::DSLMethod dsl_method, *untyped args) -> void
|
14
|
+
def initialize: (DSL::DSLMethod dsl_method, String called_from, *untyped args) -> void
|
17
15
|
def method_name: -> Symbol
|
18
16
|
def add_parser_usage_note: (String note) -> void
|
19
17
|
def parser_usage_notes: () -> Array[String]
|
20
18
|
|
21
19
|
def to_h: -> Hash[untyped, untyped]
|
20
|
+
|
21
|
+
class InvalidDescriptionError < InterpreterError
|
22
|
+
end
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -9,7 +9,7 @@ module DSLCompose
|
|
9
9
|
def method_calls: () -> Array[MethodCall]
|
10
10
|
def method_called?: (Symbol method_name) -> bool
|
11
11
|
def method_calls_by_name: (Symbol method_name) -> Array[MethodCall]
|
12
|
-
def add_method_call: (DSL::DSLMethod dsl_method, *untyped args) -> MethodCall
|
12
|
+
def add_method_call: (DSL::DSLMethod dsl_method, String called_from, *untyped args) -> MethodCall
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -5,11 +5,12 @@ module DSLCompose
|
|
5
5
|
@parser_usage_notes: Array[String]
|
6
6
|
|
7
7
|
attr_reader dsl: DSL
|
8
|
+
attr_reader called_from: String
|
8
9
|
attr_reader klass: Object
|
9
10
|
attr_reader method_calls: MethodCalls
|
10
11
|
attr_reader arguments: Arguments
|
11
12
|
|
12
|
-
def initialize: (Object klass, DSL dsl, *untyped args) -> void
|
13
|
+
def initialize: (Object klass, DSL dsl, String called_from, *untyped args) -> void
|
13
14
|
def instance_eval: () -> void
|
14
15
|
def add_parser_usage_note: (String note) -> void
|
15
16
|
def parser_usage_notes: () -> Array[String]
|
@@ -18,11 +19,15 @@ module DSLCompose
|
|
18
19
|
def method_missing: (Symbol method_name, *untyped args) -> untyped
|
19
20
|
def respond_to_missing?: (Symbol method_name, *untyped args) -> untyped
|
20
21
|
|
21
|
-
class MethodIsUniqueError <
|
22
|
+
class MethodIsUniqueError < InterpreterError
|
22
23
|
end
|
23
24
|
|
24
|
-
class RequiredMethodNotCalledError <
|
25
|
+
class RequiredMethodNotCalledError < InterpreterError
|
25
26
|
end
|
27
|
+
|
28
|
+
class InvalidDescriptionError < InterpreterError
|
29
|
+
end
|
30
|
+
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
@@ -12,10 +12,7 @@ module DSLCompose
|
|
12
12
|
def add_parser_usage_note: (singleton(Object) klass, String note) -> void
|
13
13
|
def parser_usage_notes: (singleton(Object) klass) -> Array[String]
|
14
14
|
|
15
|
-
class InvalidDescriptionError <
|
16
|
-
end
|
17
|
-
|
18
|
-
class DSLExecutionNotFoundError < StandardError
|
15
|
+
class InvalidDescriptionError < InterpreterError
|
19
16
|
end
|
20
17
|
end
|
21
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dsl_compose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.15.
|
4
|
+
version: 2.15.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Craig Ulliott
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: class_spec_helper
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/dsl_compose/interpreter/execution/arguments.rb
|
68
68
|
- lib/dsl_compose/interpreter/execution/method_calls.rb
|
69
69
|
- lib/dsl_compose/interpreter/execution/method_calls/method_call.rb
|
70
|
+
- lib/dsl_compose/interpreter/interpreter_error.rb
|
70
71
|
- lib/dsl_compose/parser.rb
|
71
72
|
- lib/dsl_compose/parser/block_arguments.rb
|
72
73
|
- lib/dsl_compose/parser/for_children_of_parser.rb
|
@@ -109,6 +110,7 @@ files:
|
|
109
110
|
- sig/dsl_compose/interpreter/execution/arguments.rbs
|
110
111
|
- sig/dsl_compose/interpreter/execution/method_calls.rbs
|
111
112
|
- sig/dsl_compose/interpreter/execution/method_calls/method_call.rbs
|
113
|
+
- sig/dsl_compose/interpreter/interpreter_error.rbs
|
112
114
|
- sig/dsl_compose/parser.rbs
|
113
115
|
- sig/dsl_compose/parser/block_arguments.rbs
|
114
116
|
- sig/dsl_compose/parser/for_children_of_parser.rbs
|