@trioforge/brigadier 0.0.0-stage → 0.1.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.
- package/LICENSE +22 -0
- package/README.md +73 -2
- package/out/arguments.d.ts +91 -0
- package/out/arguments.luau +475 -0
- package/out/command-dispatcher.d.ts +38 -0
- package/out/command-dispatcher.luau +394 -0
- package/out/command.d.ts +13 -0
- package/out/command.luau +8 -0
- package/out/context.d.ts +121 -0
- package/out/context.luau +576 -0
- package/out/exceptions.d.ts +118 -0
- package/out/exceptions.luau +415 -0
- package/out/index.d.ts +10 -0
- package/out/init.luau +44 -0
- package/out/java.d.ts +40 -0
- package/out/java.luau +424 -0
- package/out/literal-message.d.ts +9 -0
- package/out/literal-message.luau +29 -0
- package/out/string-reader.d.ts +41 -0
- package/out/string-reader.luau +271 -0
- package/out/suggestion.d.ts +60 -0
- package/out/suggestion.luau +340 -0
- package/out/tree.d.ts +126 -0
- package/out/tree.luau +579 -0
- package/package.json +40 -3
package/out/context.luau
ADDED
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local catchSyntax = TS.import(script, script.Parent, "exceptions").catchSyntax
|
|
4
|
+
local _java = TS.import(script, script.Parent, "java")
|
|
5
|
+
local IllegalArgumentException = _java.IllegalArgumentException
|
|
6
|
+
local IllegalStateException = _java.IllegalStateException
|
|
7
|
+
local objectsEquals = _java.objectsEquals
|
|
8
|
+
local substring = _java.substring
|
|
9
|
+
local StringRange
|
|
10
|
+
do
|
|
11
|
+
StringRange = setmetatable({}, {
|
|
12
|
+
__tostring = function()
|
|
13
|
+
return "StringRange"
|
|
14
|
+
end,
|
|
15
|
+
})
|
|
16
|
+
StringRange.__index = StringRange
|
|
17
|
+
function StringRange.new(...)
|
|
18
|
+
local self = setmetatable({}, StringRange)
|
|
19
|
+
return self:constructor(...) or self
|
|
20
|
+
end
|
|
21
|
+
function StringRange:constructor(start, finish)
|
|
22
|
+
self.start = start
|
|
23
|
+
self.finish = finish
|
|
24
|
+
end
|
|
25
|
+
function StringRange:at(pos)
|
|
26
|
+
return StringRange.new(pos, pos)
|
|
27
|
+
end
|
|
28
|
+
function StringRange:between(start, finish)
|
|
29
|
+
return StringRange.new(start, finish)
|
|
30
|
+
end
|
|
31
|
+
function StringRange:encompassing(a, b)
|
|
32
|
+
return StringRange.new(math.min(a:getStart(), b:getStart()), math.max(a:getEnd(), b:getEnd()))
|
|
33
|
+
end
|
|
34
|
+
function StringRange:getStart()
|
|
35
|
+
return self.start
|
|
36
|
+
end
|
|
37
|
+
function StringRange:getEnd()
|
|
38
|
+
return self.finish
|
|
39
|
+
end
|
|
40
|
+
function StringRange:get(reader)
|
|
41
|
+
local _reader = reader
|
|
42
|
+
return substring(if type(_reader) == "string" then reader else reader:getString(), self.start, self.finish)
|
|
43
|
+
end
|
|
44
|
+
function StringRange:isEmpty()
|
|
45
|
+
return self.start == self.finish
|
|
46
|
+
end
|
|
47
|
+
function StringRange:getLength()
|
|
48
|
+
return self.finish - self.start
|
|
49
|
+
end
|
|
50
|
+
function StringRange:equals(other)
|
|
51
|
+
if rawequal(self, other) then
|
|
52
|
+
return true
|
|
53
|
+
end
|
|
54
|
+
if not (TS.instanceof(other, StringRange)) then
|
|
55
|
+
return false
|
|
56
|
+
end
|
|
57
|
+
return self.start == other.start and self.finish == other.finish
|
|
58
|
+
end
|
|
59
|
+
function StringRange:toString()
|
|
60
|
+
return `StringRange\{start={self.start}, end={self.finish}\}`
|
|
61
|
+
end
|
|
62
|
+
function StringRange:__tostring()
|
|
63
|
+
return self:toString()
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
local ParsedArgument
|
|
67
|
+
do
|
|
68
|
+
ParsedArgument = setmetatable({}, {
|
|
69
|
+
__tostring = function()
|
|
70
|
+
return "ParsedArgument"
|
|
71
|
+
end,
|
|
72
|
+
})
|
|
73
|
+
ParsedArgument.__index = ParsedArgument
|
|
74
|
+
function ParsedArgument.new(...)
|
|
75
|
+
local self = setmetatable({}, ParsedArgument)
|
|
76
|
+
return self:constructor(...) or self
|
|
77
|
+
end
|
|
78
|
+
function ParsedArgument:constructor(start, finish, result)
|
|
79
|
+
self.result = result
|
|
80
|
+
self.range = StringRange:between(start, finish)
|
|
81
|
+
end
|
|
82
|
+
function ParsedArgument:getRange()
|
|
83
|
+
return self.range
|
|
84
|
+
end
|
|
85
|
+
function ParsedArgument:getResult()
|
|
86
|
+
return self.result
|
|
87
|
+
end
|
|
88
|
+
function ParsedArgument:equals(other)
|
|
89
|
+
if rawequal(self, other) then
|
|
90
|
+
return true
|
|
91
|
+
end
|
|
92
|
+
if not (TS.instanceof(other, ParsedArgument)) then
|
|
93
|
+
return false
|
|
94
|
+
end
|
|
95
|
+
return objectsEquals(self.range, other.range) and objectsEquals(self.result, other.result)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
local ParsedCommandNode
|
|
99
|
+
do
|
|
100
|
+
ParsedCommandNode = setmetatable({}, {
|
|
101
|
+
__tostring = function()
|
|
102
|
+
return "ParsedCommandNode"
|
|
103
|
+
end,
|
|
104
|
+
})
|
|
105
|
+
ParsedCommandNode.__index = ParsedCommandNode
|
|
106
|
+
function ParsedCommandNode.new(...)
|
|
107
|
+
local self = setmetatable({}, ParsedCommandNode)
|
|
108
|
+
return self:constructor(...) or self
|
|
109
|
+
end
|
|
110
|
+
function ParsedCommandNode:constructor(node, range)
|
|
111
|
+
self.node = node
|
|
112
|
+
self.range = range
|
|
113
|
+
end
|
|
114
|
+
function ParsedCommandNode:getNode()
|
|
115
|
+
return self.node
|
|
116
|
+
end
|
|
117
|
+
function ParsedCommandNode:getRange()
|
|
118
|
+
return self.range
|
|
119
|
+
end
|
|
120
|
+
function ParsedCommandNode:toString()
|
|
121
|
+
return `{self.node}@{self.range}`
|
|
122
|
+
end
|
|
123
|
+
function ParsedCommandNode:equals(other)
|
|
124
|
+
if rawequal(self, other) then
|
|
125
|
+
return true
|
|
126
|
+
end
|
|
127
|
+
local _other = other
|
|
128
|
+
local _condition = not (type(_other) == "table")
|
|
129
|
+
if not _condition then
|
|
130
|
+
_condition = getmetatable(other) ~= getmetatable(self)
|
|
131
|
+
end
|
|
132
|
+
if _condition then
|
|
133
|
+
return false
|
|
134
|
+
end
|
|
135
|
+
local that = other
|
|
136
|
+
return objectsEquals(self.node, that.node) and objectsEquals(self.range, that.range)
|
|
137
|
+
end
|
|
138
|
+
function ParsedCommandNode:__tostring()
|
|
139
|
+
return self:toString()
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
local SuggestionContext
|
|
143
|
+
do
|
|
144
|
+
SuggestionContext = setmetatable({}, {
|
|
145
|
+
__tostring = function()
|
|
146
|
+
return "SuggestionContext"
|
|
147
|
+
end,
|
|
148
|
+
})
|
|
149
|
+
SuggestionContext.__index = SuggestionContext
|
|
150
|
+
function SuggestionContext.new(...)
|
|
151
|
+
local self = setmetatable({}, SuggestionContext)
|
|
152
|
+
return self:constructor(...) or self
|
|
153
|
+
end
|
|
154
|
+
function SuggestionContext:constructor(context, parent, startPos)
|
|
155
|
+
self.context = context
|
|
156
|
+
self.parent = parent
|
|
157
|
+
self.startPos = startPos
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
-- What Class.isAssignableFrom checks against: a Luau type name such as "number" or "Vector3", "any" for Object,
|
|
161
|
+
-- or a class.
|
|
162
|
+
local function isAssignable(clazz, value)
|
|
163
|
+
if clazz == "any" then
|
|
164
|
+
return true
|
|
165
|
+
end
|
|
166
|
+
local _clazz = clazz
|
|
167
|
+
if type(_clazz) == "string" then
|
|
168
|
+
local _value = value
|
|
169
|
+
return typeof(_value) == clazz
|
|
170
|
+
end
|
|
171
|
+
local _clazz_1 = clazz
|
|
172
|
+
if type(_clazz_1) == "table" then
|
|
173
|
+
return TS.instanceof(value, clazz)
|
|
174
|
+
end
|
|
175
|
+
error(IllegalArgumentException.new(`Unknown argument class {tostring(clazz)}`))
|
|
176
|
+
end
|
|
177
|
+
local CommandContext
|
|
178
|
+
do
|
|
179
|
+
CommandContext = setmetatable({}, {
|
|
180
|
+
__tostring = function()
|
|
181
|
+
return "CommandContext"
|
|
182
|
+
end,
|
|
183
|
+
})
|
|
184
|
+
CommandContext.__index = CommandContext
|
|
185
|
+
function CommandContext.new(...)
|
|
186
|
+
local self = setmetatable({}, CommandContext)
|
|
187
|
+
return self:constructor(...) or self
|
|
188
|
+
end
|
|
189
|
+
function CommandContext:constructor(source, input, args, command, rootNode, nodes, range, child, modifier, forks)
|
|
190
|
+
self.source = source
|
|
191
|
+
self.input = input
|
|
192
|
+
self.args = args
|
|
193
|
+
self.command = command
|
|
194
|
+
self.rootNode = rootNode
|
|
195
|
+
self.nodes = nodes
|
|
196
|
+
self.range = range
|
|
197
|
+
self.child = child
|
|
198
|
+
self.modifier = modifier
|
|
199
|
+
self.forks = forks
|
|
200
|
+
end
|
|
201
|
+
function CommandContext:copyFor(source)
|
|
202
|
+
if rawequal(self.source, source) then
|
|
203
|
+
return self
|
|
204
|
+
end
|
|
205
|
+
return CommandContext.new(source, self.input, self.args, self.command, self.rootNode, self.nodes, self.range, self.child, self.modifier, self.forks)
|
|
206
|
+
end
|
|
207
|
+
function CommandContext:getChild()
|
|
208
|
+
return self.child
|
|
209
|
+
end
|
|
210
|
+
function CommandContext:getLastChild()
|
|
211
|
+
local result = self.child
|
|
212
|
+
if result == nil then
|
|
213
|
+
return self
|
|
214
|
+
end
|
|
215
|
+
local child = result:getChild()
|
|
216
|
+
while child ~= nil do
|
|
217
|
+
result = child
|
|
218
|
+
child = result:getChild()
|
|
219
|
+
end
|
|
220
|
+
return result
|
|
221
|
+
end
|
|
222
|
+
function CommandContext:getCommand()
|
|
223
|
+
return self.command
|
|
224
|
+
end
|
|
225
|
+
function CommandContext:getSource()
|
|
226
|
+
return self.source
|
|
227
|
+
end
|
|
228
|
+
function CommandContext:getArgument(name, clazz)
|
|
229
|
+
local _args = self.args
|
|
230
|
+
local _name = name
|
|
231
|
+
local argument = _args[_name]
|
|
232
|
+
if argument == nil then
|
|
233
|
+
error(IllegalArgumentException.new(`No such argument '{name}' exists on this command`))
|
|
234
|
+
end
|
|
235
|
+
local result = argument:getResult()
|
|
236
|
+
if isAssignable(clazz, result) then
|
|
237
|
+
return result
|
|
238
|
+
end
|
|
239
|
+
error(IllegalArgumentException.new(`Argument '{name}' is defined as {typeof(result)}, not {tostring(clazz)}`))
|
|
240
|
+
end
|
|
241
|
+
function CommandContext:equals(other)
|
|
242
|
+
if rawequal(self, other) then
|
|
243
|
+
return true
|
|
244
|
+
end
|
|
245
|
+
if not (TS.instanceof(other, CommandContext)) then
|
|
246
|
+
return false
|
|
247
|
+
end
|
|
248
|
+
local that = other
|
|
249
|
+
if not objectsEquals(self.args, that.args) then
|
|
250
|
+
return false
|
|
251
|
+
end
|
|
252
|
+
if not self.rootNode:equals(that.rootNode) then
|
|
253
|
+
return false
|
|
254
|
+
end
|
|
255
|
+
if #self.nodes ~= #that.nodes or not objectsEquals(self.nodes, that.nodes) then
|
|
256
|
+
return false
|
|
257
|
+
end
|
|
258
|
+
if if self.command ~= nil then not objectsEquals(self.command, that.command) else that.command ~= nil then
|
|
259
|
+
return false
|
|
260
|
+
end
|
|
261
|
+
if not objectsEquals(self.source, that.source) then
|
|
262
|
+
return false
|
|
263
|
+
end
|
|
264
|
+
if if self.child ~= nil then not self.child:equals(that.child) else that.child ~= nil then
|
|
265
|
+
return false
|
|
266
|
+
end
|
|
267
|
+
return true
|
|
268
|
+
end
|
|
269
|
+
function CommandContext:getRedirectModifier()
|
|
270
|
+
return self.modifier
|
|
271
|
+
end
|
|
272
|
+
function CommandContext:getRange()
|
|
273
|
+
return self.range
|
|
274
|
+
end
|
|
275
|
+
function CommandContext:getInput()
|
|
276
|
+
return self.input
|
|
277
|
+
end
|
|
278
|
+
function CommandContext:getRootNode()
|
|
279
|
+
return self.rootNode
|
|
280
|
+
end
|
|
281
|
+
function CommandContext:getNodes()
|
|
282
|
+
return self.nodes
|
|
283
|
+
end
|
|
284
|
+
function CommandContext:hasNodes()
|
|
285
|
+
return #self.nodes > 0
|
|
286
|
+
end
|
|
287
|
+
function CommandContext:isForked()
|
|
288
|
+
return self.forks
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
local CommandContextBuilder
|
|
292
|
+
do
|
|
293
|
+
CommandContextBuilder = setmetatable({}, {
|
|
294
|
+
__tostring = function()
|
|
295
|
+
return "CommandContextBuilder"
|
|
296
|
+
end,
|
|
297
|
+
})
|
|
298
|
+
CommandContextBuilder.__index = CommandContextBuilder
|
|
299
|
+
function CommandContextBuilder.new(...)
|
|
300
|
+
local self = setmetatable({}, CommandContextBuilder)
|
|
301
|
+
return self:constructor(...) or self
|
|
302
|
+
end
|
|
303
|
+
function CommandContextBuilder:constructor(dispatcher, source, rootNode, start)
|
|
304
|
+
self.dispatcher = dispatcher
|
|
305
|
+
self.source = source
|
|
306
|
+
self.rootNode = rootNode
|
|
307
|
+
self.args = {}
|
|
308
|
+
self.nodes = {}
|
|
309
|
+
self.forks = false
|
|
310
|
+
self.range = StringRange:at(start)
|
|
311
|
+
end
|
|
312
|
+
function CommandContextBuilder:withSource(source)
|
|
313
|
+
self.source = source
|
|
314
|
+
return self
|
|
315
|
+
end
|
|
316
|
+
function CommandContextBuilder:getSource()
|
|
317
|
+
return self.source
|
|
318
|
+
end
|
|
319
|
+
function CommandContextBuilder:getRootNode()
|
|
320
|
+
return self.rootNode
|
|
321
|
+
end
|
|
322
|
+
function CommandContextBuilder:withArgument(name, argument)
|
|
323
|
+
local _args = self.args
|
|
324
|
+
local _name = name
|
|
325
|
+
local _argument = argument
|
|
326
|
+
_args[_name] = _argument
|
|
327
|
+
return self
|
|
328
|
+
end
|
|
329
|
+
function CommandContextBuilder:getArguments()
|
|
330
|
+
return self.args
|
|
331
|
+
end
|
|
332
|
+
function CommandContextBuilder:withCommand(command)
|
|
333
|
+
self.command = command
|
|
334
|
+
return self
|
|
335
|
+
end
|
|
336
|
+
function CommandContextBuilder:withNode(node, range)
|
|
337
|
+
local _nodes = self.nodes
|
|
338
|
+
local _parsedCommandNode = ParsedCommandNode.new(node, range)
|
|
339
|
+
table.insert(_nodes, _parsedCommandNode)
|
|
340
|
+
self.range = StringRange:encompassing(self.range, range)
|
|
341
|
+
self.modifier = node:getRedirectModifier()
|
|
342
|
+
self.forks = node:isFork()
|
|
343
|
+
return self
|
|
344
|
+
end
|
|
345
|
+
function CommandContextBuilder:copy()
|
|
346
|
+
local copy = CommandContextBuilder.new(self.dispatcher, self.source, self.rootNode, self.range:getStart())
|
|
347
|
+
copy.command = self.command
|
|
348
|
+
for name, argument in self.args do
|
|
349
|
+
copy.args[name] = argument
|
|
350
|
+
end
|
|
351
|
+
for _, node in self.nodes do
|
|
352
|
+
local _exp = copy.nodes
|
|
353
|
+
table.insert(_exp, node)
|
|
354
|
+
end
|
|
355
|
+
copy.child = self.child
|
|
356
|
+
copy.range = self.range
|
|
357
|
+
copy.forks = self.forks
|
|
358
|
+
return copy
|
|
359
|
+
end
|
|
360
|
+
function CommandContextBuilder:withChild(child)
|
|
361
|
+
self.child = child
|
|
362
|
+
return self
|
|
363
|
+
end
|
|
364
|
+
function CommandContextBuilder:getChild()
|
|
365
|
+
return self.child
|
|
366
|
+
end
|
|
367
|
+
function CommandContextBuilder:getLastChild()
|
|
368
|
+
local result = self.child
|
|
369
|
+
if result == nil then
|
|
370
|
+
return self
|
|
371
|
+
end
|
|
372
|
+
local child = result:getChild()
|
|
373
|
+
while child ~= nil do
|
|
374
|
+
result = child
|
|
375
|
+
child = result:getChild()
|
|
376
|
+
end
|
|
377
|
+
return result
|
|
378
|
+
end
|
|
379
|
+
function CommandContextBuilder:getCommand()
|
|
380
|
+
return self.command
|
|
381
|
+
end
|
|
382
|
+
function CommandContextBuilder:getNodes()
|
|
383
|
+
return self.nodes
|
|
384
|
+
end
|
|
385
|
+
function CommandContextBuilder:build(input)
|
|
386
|
+
local _exp = self.source
|
|
387
|
+
local _exp_1 = input
|
|
388
|
+
local _exp_2 = self.args
|
|
389
|
+
local _exp_3 = self.command
|
|
390
|
+
local _exp_4 = self.rootNode
|
|
391
|
+
local _exp_5 = self.nodes
|
|
392
|
+
local _exp_6 = self.range
|
|
393
|
+
local _result = self.child
|
|
394
|
+
if _result ~= nil then
|
|
395
|
+
_result = _result:build(input)
|
|
396
|
+
end
|
|
397
|
+
return CommandContext.new(_exp, _exp_1, _exp_2, _exp_3, _exp_4, _exp_5, _exp_6, _result, self.modifier, self.forks)
|
|
398
|
+
end
|
|
399
|
+
function CommandContextBuilder:getDispatcher()
|
|
400
|
+
return self.dispatcher
|
|
401
|
+
end
|
|
402
|
+
function CommandContextBuilder:getRange()
|
|
403
|
+
return self.range
|
|
404
|
+
end
|
|
405
|
+
function CommandContextBuilder:findSuggestionContext(cursor)
|
|
406
|
+
if self.range:getStart() <= cursor then
|
|
407
|
+
if self.range:getEnd() < cursor then
|
|
408
|
+
if self.child ~= nil then
|
|
409
|
+
return self.child:findSuggestionContext(cursor)
|
|
410
|
+
elseif #self.nodes > 0 then
|
|
411
|
+
local last = self.nodes[#self.nodes]
|
|
412
|
+
return SuggestionContext.new(self, last:getNode(), last:getRange():getEnd() + 1)
|
|
413
|
+
end
|
|
414
|
+
return SuggestionContext.new(self, self.rootNode, self.range:getStart())
|
|
415
|
+
end
|
|
416
|
+
local prev = self.rootNode
|
|
417
|
+
for _, node in self.nodes do
|
|
418
|
+
local nodeRange = node:getRange()
|
|
419
|
+
if nodeRange:getStart() <= cursor and cursor <= nodeRange:getEnd() then
|
|
420
|
+
return SuggestionContext.new(self, prev, nodeRange:getStart())
|
|
421
|
+
end
|
|
422
|
+
prev = node:getNode()
|
|
423
|
+
end
|
|
424
|
+
return SuggestionContext.new(self, prev, self.range:getStart())
|
|
425
|
+
end
|
|
426
|
+
error(IllegalStateException.new("Can't find node before cursor"))
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
local ContextChain
|
|
430
|
+
do
|
|
431
|
+
ContextChain = setmetatable({}, {
|
|
432
|
+
__tostring = function()
|
|
433
|
+
return "ContextChain"
|
|
434
|
+
end,
|
|
435
|
+
})
|
|
436
|
+
ContextChain.__index = ContextChain
|
|
437
|
+
function ContextChain.new(...)
|
|
438
|
+
local self = setmetatable({}, ContextChain)
|
|
439
|
+
return self:constructor(...) or self
|
|
440
|
+
end
|
|
441
|
+
function ContextChain:constructor(modifiers, executable)
|
|
442
|
+
self.modifiers = modifiers
|
|
443
|
+
self.executable = executable
|
|
444
|
+
if executable:getCommand() == nil then
|
|
445
|
+
error(IllegalArgumentException.new("Last command in chain must be executable"))
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
function ContextChain:tryFlatten(rootContext)
|
|
449
|
+
local modifiers = {}
|
|
450
|
+
local current = rootContext
|
|
451
|
+
while true do
|
|
452
|
+
local child = current:getChild()
|
|
453
|
+
if child == nil then
|
|
454
|
+
-- Last entry must be executable command
|
|
455
|
+
if current:getCommand() == nil then
|
|
456
|
+
return nil
|
|
457
|
+
end
|
|
458
|
+
return ContextChain.new(modifiers, current)
|
|
459
|
+
end
|
|
460
|
+
local _current = current
|
|
461
|
+
table.insert(modifiers, _current)
|
|
462
|
+
current = child
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
function ContextChain:runModifier(modifier, source, resultConsumer, forkedMode)
|
|
466
|
+
local sourceModifier = modifier:getRedirectModifier()
|
|
467
|
+
-- Note: source currently in context is irrelevant at this point, since we might have updated it in one of earlier stages
|
|
468
|
+
if sourceModifier == nil then
|
|
469
|
+
-- Simple redirect, just propagate source to next node
|
|
470
|
+
return { source }
|
|
471
|
+
end
|
|
472
|
+
local contextToUse = modifier:copyFor(source)
|
|
473
|
+
return catchSyntax(function()
|
|
474
|
+
return sourceModifier(contextToUse)
|
|
475
|
+
end, function(ex)
|
|
476
|
+
resultConsumer(contextToUse, false, 0)
|
|
477
|
+
if forkedMode then
|
|
478
|
+
return {}
|
|
479
|
+
end
|
|
480
|
+
error(ex)
|
|
481
|
+
end)
|
|
482
|
+
end
|
|
483
|
+
function ContextChain:runExecutable(executable, source, resultConsumer, forkedMode)
|
|
484
|
+
local contextToUse = executable:copyFor(source)
|
|
485
|
+
return catchSyntax(function()
|
|
486
|
+
local result = executable:getCommand()(contextToUse)
|
|
487
|
+
resultConsumer(contextToUse, true, result)
|
|
488
|
+
return if forkedMode then 1 else result
|
|
489
|
+
end, function(ex)
|
|
490
|
+
resultConsumer(contextToUse, false, 0)
|
|
491
|
+
if forkedMode then
|
|
492
|
+
return 0
|
|
493
|
+
end
|
|
494
|
+
error(ex)
|
|
495
|
+
end)
|
|
496
|
+
end
|
|
497
|
+
function ContextChain:executeAll(source, resultConsumer)
|
|
498
|
+
if #self.modifiers == 0 then
|
|
499
|
+
-- Fast path - just a single stage
|
|
500
|
+
return ContextChain:runExecutable(self.executable, source, resultConsumer, false)
|
|
501
|
+
end
|
|
502
|
+
local forkedMode = false
|
|
503
|
+
local currentSources = { source }
|
|
504
|
+
for _, modifier in self.modifiers do
|
|
505
|
+
local _condition = forkedMode
|
|
506
|
+
if not forkedMode then
|
|
507
|
+
_condition = modifier:isForked()
|
|
508
|
+
end
|
|
509
|
+
forkedMode = _condition
|
|
510
|
+
local nextSources = {}
|
|
511
|
+
for _1, sourceToRun in currentSources do
|
|
512
|
+
for _2, nextSource in ContextChain:runModifier(modifier, sourceToRun, resultConsumer, forkedMode) do
|
|
513
|
+
nextSources[#nextSources + 1] = nextSource
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
if #nextSources == 0 then
|
|
517
|
+
return 0
|
|
518
|
+
end
|
|
519
|
+
currentSources = nextSources
|
|
520
|
+
end
|
|
521
|
+
local result = 0
|
|
522
|
+
for _, executionSource in currentSources do
|
|
523
|
+
result += ContextChain:runExecutable(self.executable, executionSource, resultConsumer, forkedMode)
|
|
524
|
+
end
|
|
525
|
+
return result
|
|
526
|
+
end
|
|
527
|
+
function ContextChain:getStage()
|
|
528
|
+
return if #self.modifiers == 0 then ContextChain.Stage.EXECUTE else ContextChain.Stage.MODIFY
|
|
529
|
+
end
|
|
530
|
+
function ContextChain:getTopContext()
|
|
531
|
+
if #self.modifiers == 0 then
|
|
532
|
+
return self.executable
|
|
533
|
+
end
|
|
534
|
+
return self.modifiers[1]
|
|
535
|
+
end
|
|
536
|
+
function ContextChain:nextStage()
|
|
537
|
+
local modifierCount = #self.modifiers
|
|
538
|
+
if modifierCount == 0 then
|
|
539
|
+
return nil
|
|
540
|
+
end
|
|
541
|
+
if self.nextStageCache == nil then
|
|
542
|
+
local rest = {}
|
|
543
|
+
do
|
|
544
|
+
local index = 1
|
|
545
|
+
local _shouldIncrement = false
|
|
546
|
+
while true do
|
|
547
|
+
if _shouldIncrement then
|
|
548
|
+
index += 1
|
|
549
|
+
else
|
|
550
|
+
_shouldIncrement = true
|
|
551
|
+
end
|
|
552
|
+
if not (index < modifierCount) then
|
|
553
|
+
break
|
|
554
|
+
end
|
|
555
|
+
local _arg0 = self.modifiers[index + 1]
|
|
556
|
+
table.insert(rest, _arg0)
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
self.nextStageCache = ContextChain.new(rest, self.executable)
|
|
560
|
+
end
|
|
561
|
+
return self.nextStageCache
|
|
562
|
+
end
|
|
563
|
+
ContextChain.Stage = {
|
|
564
|
+
MODIFY = "MODIFY",
|
|
565
|
+
EXECUTE = "EXECUTE",
|
|
566
|
+
}
|
|
567
|
+
end
|
|
568
|
+
return {
|
|
569
|
+
StringRange = StringRange,
|
|
570
|
+
ParsedArgument = ParsedArgument,
|
|
571
|
+
ParsedCommandNode = ParsedCommandNode,
|
|
572
|
+
SuggestionContext = SuggestionContext,
|
|
573
|
+
CommandContext = CommandContext,
|
|
574
|
+
CommandContextBuilder = CommandContextBuilder,
|
|
575
|
+
ContextChain = ContextChain,
|
|
576
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type Message } from "./literal-message";
|
|
2
|
+
import type { ImmutableStringReader } from "./string-reader";
|
|
3
|
+
export type CommandExceptionType = object;
|
|
4
|
+
export declare class CommandSyntaxException {
|
|
5
|
+
private readonly exceptionType;
|
|
6
|
+
private readonly message;
|
|
7
|
+
private readonly input?;
|
|
8
|
+
static readonly CONTEXT_AMOUNT = 10;
|
|
9
|
+
static ENABLE_COMMAND_STACK_TRACES: boolean;
|
|
10
|
+
static BUILT_IN_EXCEPTIONS: BuiltInExceptionProvider;
|
|
11
|
+
private readonly cursor;
|
|
12
|
+
private readonly stackTrace?;
|
|
13
|
+
constructor(exceptionType: CommandExceptionType, message: Message, input?: string | undefined, cursor?: number);
|
|
14
|
+
getMessage(): string;
|
|
15
|
+
getRawMessage(): Message;
|
|
16
|
+
getContext(): string | undefined;
|
|
17
|
+
getType(): CommandExceptionType;
|
|
18
|
+
getInput(): string | undefined;
|
|
19
|
+
getCursor(): number;
|
|
20
|
+
getStackTrace(): string | undefined;
|
|
21
|
+
toString(): string;
|
|
22
|
+
}
|
|
23
|
+
export declare function catchSyntax<T>(body: () => T, onSyntaxException: (exception: CommandSyntaxException) => T): T;
|
|
24
|
+
export declare class SimpleCommandExceptionType implements CommandExceptionType {
|
|
25
|
+
private readonly message;
|
|
26
|
+
constructor(message: Message);
|
|
27
|
+
create(): CommandSyntaxException;
|
|
28
|
+
createWithContext(reader: ImmutableStringReader): CommandSyntaxException;
|
|
29
|
+
toString(): string;
|
|
30
|
+
}
|
|
31
|
+
export declare class DynamicCommandExceptionType implements CommandExceptionType {
|
|
32
|
+
private readonly fn;
|
|
33
|
+
constructor(fn: (arg: unknown) => Message);
|
|
34
|
+
create(arg: unknown): CommandSyntaxException;
|
|
35
|
+
createWithContext(reader: ImmutableStringReader, arg: unknown): CommandSyntaxException;
|
|
36
|
+
}
|
|
37
|
+
export declare class Dynamic2CommandExceptionType implements CommandExceptionType {
|
|
38
|
+
private readonly fn;
|
|
39
|
+
constructor(fn: (a: unknown, b: unknown) => Message);
|
|
40
|
+
create(a: unknown, b: unknown): CommandSyntaxException;
|
|
41
|
+
createWithContext(reader: ImmutableStringReader, a: unknown, b: unknown): CommandSyntaxException;
|
|
42
|
+
}
|
|
43
|
+
export declare class Dynamic3CommandExceptionType implements CommandExceptionType {
|
|
44
|
+
private readonly fn;
|
|
45
|
+
constructor(fn: (a: unknown, b: unknown, c: unknown) => Message);
|
|
46
|
+
create(a: unknown, b: unknown, c: unknown): CommandSyntaxException;
|
|
47
|
+
createWithContext(reader: ImmutableStringReader, a: unknown, b: unknown, c: unknown): CommandSyntaxException;
|
|
48
|
+
}
|
|
49
|
+
export declare class Dynamic4CommandExceptionType implements CommandExceptionType {
|
|
50
|
+
private readonly fn;
|
|
51
|
+
constructor(fn: (a: unknown, b: unknown, c: unknown, d: unknown) => Message);
|
|
52
|
+
create(a: unknown, b: unknown, c: unknown, d: unknown): CommandSyntaxException;
|
|
53
|
+
createWithContext(reader: ImmutableStringReader, a: unknown, b: unknown, c: unknown, d: unknown): CommandSyntaxException;
|
|
54
|
+
}
|
|
55
|
+
export declare class DynamicNCommandExceptionType implements CommandExceptionType {
|
|
56
|
+
private readonly fn;
|
|
57
|
+
constructor(fn: (args: unknown[]) => Message);
|
|
58
|
+
create(_a: unknown, ...args: unknown[]): CommandSyntaxException;
|
|
59
|
+
createWithContext(reader: ImmutableStringReader, ...args: unknown[]): CommandSyntaxException;
|
|
60
|
+
}
|
|
61
|
+
export interface BuiltInExceptionProvider {
|
|
62
|
+
doubleTooLow(): Dynamic2CommandExceptionType;
|
|
63
|
+
doubleTooHigh(): Dynamic2CommandExceptionType;
|
|
64
|
+
floatTooLow(): Dynamic2CommandExceptionType;
|
|
65
|
+
floatTooHigh(): Dynamic2CommandExceptionType;
|
|
66
|
+
integerTooLow(): Dynamic2CommandExceptionType;
|
|
67
|
+
integerTooHigh(): Dynamic2CommandExceptionType;
|
|
68
|
+
longTooLow(): Dynamic2CommandExceptionType;
|
|
69
|
+
longTooHigh(): Dynamic2CommandExceptionType;
|
|
70
|
+
literalIncorrect(): DynamicCommandExceptionType;
|
|
71
|
+
readerExpectedStartOfQuote(): SimpleCommandExceptionType;
|
|
72
|
+
readerExpectedEndOfQuote(): SimpleCommandExceptionType;
|
|
73
|
+
readerInvalidEscape(): DynamicCommandExceptionType;
|
|
74
|
+
readerInvalidBool(): DynamicCommandExceptionType;
|
|
75
|
+
readerInvalidInt(): DynamicCommandExceptionType;
|
|
76
|
+
readerExpectedInt(): SimpleCommandExceptionType;
|
|
77
|
+
readerInvalidLong(): DynamicCommandExceptionType;
|
|
78
|
+
readerExpectedLong(): SimpleCommandExceptionType;
|
|
79
|
+
readerInvalidDouble(): DynamicCommandExceptionType;
|
|
80
|
+
readerExpectedDouble(): SimpleCommandExceptionType;
|
|
81
|
+
readerInvalidFloat(): DynamicCommandExceptionType;
|
|
82
|
+
readerExpectedFloat(): SimpleCommandExceptionType;
|
|
83
|
+
readerExpectedBool(): SimpleCommandExceptionType;
|
|
84
|
+
readerExpectedSymbol(): DynamicCommandExceptionType;
|
|
85
|
+
dispatcherUnknownCommand(): SimpleCommandExceptionType;
|
|
86
|
+
dispatcherUnknownArgument(): SimpleCommandExceptionType;
|
|
87
|
+
dispatcherExpectedArgumentSeparator(): SimpleCommandExceptionType;
|
|
88
|
+
dispatcherParseException(): DynamicCommandExceptionType;
|
|
89
|
+
}
|
|
90
|
+
export declare class BuiltInExceptions implements BuiltInExceptionProvider {
|
|
91
|
+
doubleTooLow(): Dynamic2CommandExceptionType;
|
|
92
|
+
doubleTooHigh(): Dynamic2CommandExceptionType;
|
|
93
|
+
floatTooLow(): Dynamic2CommandExceptionType;
|
|
94
|
+
floatTooHigh(): Dynamic2CommandExceptionType;
|
|
95
|
+
integerTooLow(): Dynamic2CommandExceptionType;
|
|
96
|
+
integerTooHigh(): Dynamic2CommandExceptionType;
|
|
97
|
+
longTooLow(): Dynamic2CommandExceptionType;
|
|
98
|
+
longTooHigh(): Dynamic2CommandExceptionType;
|
|
99
|
+
literalIncorrect(): DynamicCommandExceptionType;
|
|
100
|
+
readerExpectedStartOfQuote(): SimpleCommandExceptionType;
|
|
101
|
+
readerExpectedEndOfQuote(): SimpleCommandExceptionType;
|
|
102
|
+
readerInvalidEscape(): DynamicCommandExceptionType;
|
|
103
|
+
readerInvalidBool(): DynamicCommandExceptionType;
|
|
104
|
+
readerInvalidInt(): DynamicCommandExceptionType;
|
|
105
|
+
readerExpectedInt(): SimpleCommandExceptionType;
|
|
106
|
+
readerInvalidLong(): DynamicCommandExceptionType;
|
|
107
|
+
readerExpectedLong(): SimpleCommandExceptionType;
|
|
108
|
+
readerInvalidDouble(): DynamicCommandExceptionType;
|
|
109
|
+
readerExpectedDouble(): SimpleCommandExceptionType;
|
|
110
|
+
readerInvalidFloat(): DynamicCommandExceptionType;
|
|
111
|
+
readerExpectedFloat(): SimpleCommandExceptionType;
|
|
112
|
+
readerExpectedBool(): SimpleCommandExceptionType;
|
|
113
|
+
readerExpectedSymbol(): DynamicCommandExceptionType;
|
|
114
|
+
dispatcherUnknownCommand(): SimpleCommandExceptionType;
|
|
115
|
+
dispatcherUnknownArgument(): SimpleCommandExceptionType;
|
|
116
|
+
dispatcherExpectedArgumentSeparator(): SimpleCommandExceptionType;
|
|
117
|
+
dispatcherParseException(): DynamicCommandExceptionType;
|
|
118
|
+
}
|