@jsprismarine/brigadier 0.2.0-rc.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +57 -39
  2. package/dist/index.js +6 -2
  3. package/dist/index.js.map +1 -1
  4. package/dist/lib/CommandDispatcher.js +1 -3
  5. package/dist/lib/CommandDispatcher.js.map +1 -1
  6. package/dist/lib/builder/LiteralArgumentBuilder.js.map +1 -1
  7. package/dist/lib/builder/RequiredArgumentBuilder.js.map +1 -1
  8. package/dist/lib/context/CommandContext.js +4 -4
  9. package/dist/lib/context/CommandContext.js.map +1 -1
  10. package/dist/lib/suggestion/Suggestion.js +1 -1
  11. package/dist/lib/suggestion/Suggestion.js.map +1 -1
  12. package/dist/lib/suggestion/Suggestions.js +1 -1
  13. package/dist/lib/suggestion/Suggestions.js.map +1 -1
  14. package/dist/lib/tree/ArgumentCommandNode.js +1 -1
  15. package/dist/lib/tree/ArgumentCommandNode.js.map +1 -1
  16. package/dist/lib/tree/CommandNode.js +2 -2
  17. package/dist/lib/tree/CommandNode.js.map +1 -1
  18. package/package.json +55 -48
  19. package/.prettierrc +0 -10
  20. package/.renovaterc +0 -3
  21. package/CHANGELOG.md +0 -30
  22. package/dist/index.d.ts +0 -23
  23. package/dist/lib/AmbiguityConsumer.d.ts +0 -4
  24. package/dist/lib/Command.d.ts +0 -4
  25. package/dist/lib/CommandDispatcher.d.ts +0 -29
  26. package/dist/lib/ImmutableStringReader.d.ts +0 -12
  27. package/dist/lib/LiteralMessage.d.ts +0 -7
  28. package/dist/lib/Message.d.ts +0 -3
  29. package/dist/lib/ParseResults.d.ts +0 -13
  30. package/dist/lib/Predicate.d.ts +0 -3
  31. package/dist/lib/RedirectModifier.d.ts +0 -4
  32. package/dist/lib/ResultConsumer.d.ts +0 -4
  33. package/dist/lib/SingleRedirectModifier.d.ts +0 -4
  34. package/dist/lib/StringReader.d.ts +0 -27
  35. package/dist/lib/arguments/ArgumentType.d.ts +0 -21
  36. package/dist/lib/arguments/BoolArgumentType.d.ts +0 -13
  37. package/dist/lib/arguments/FloatArgumentType.d.ts +0 -16
  38. package/dist/lib/arguments/IntegerArgumentType.d.ts +0 -16
  39. package/dist/lib/arguments/StringArgumentType.d.ts +0 -21
  40. package/dist/lib/builder/ArgumentBuilder.d.ts +0 -28
  41. package/dist/lib/builder/LiteralArgumentBuilder.d.ts +0 -11
  42. package/dist/lib/builder/RequiredArgumentBuilder.d.ts +0 -18
  43. package/dist/lib/context/CommandContext.d.ts +0 -33
  44. package/dist/lib/context/CommandContextBuilder.d.ts +0 -38
  45. package/dist/lib/context/ParsedArgument.d.ts +0 -9
  46. package/dist/lib/context/ParsedCommandNode.d.ts +0 -11
  47. package/dist/lib/context/StringRange.d.ts +0 -16
  48. package/dist/lib/context/SuggestionContext.d.ts +0 -6
  49. package/dist/lib/exceptions/BuiltInExceptionProvider.d.ts +0 -23
  50. package/dist/lib/exceptions/BuiltInExceptions.d.ts +0 -43
  51. package/dist/lib/exceptions/CommandExceptionType.d.ts +0 -2
  52. package/dist/lib/exceptions/CommandSyntaxException.d.ts +0 -19
  53. package/dist/lib/exceptions/DynamicCommandExceptionType.d.ts +0 -10
  54. package/dist/lib/exceptions/SimpleCommandExceptionType.d.ts +0 -11
  55. package/dist/lib/suggestion/IntegerSuggestion.d.ts +0 -12
  56. package/dist/lib/suggestion/Suggestion.d.ts +0 -17
  57. package/dist/lib/suggestion/SuggestionProvider.d.ts +0 -6
  58. package/dist/lib/suggestion/Suggestions.d.ts +0 -16
  59. package/dist/lib/suggestion/SuggestionsBuilder.d.ts +0 -18
  60. package/dist/lib/tree/ArgumentCommandNode.d.ts +0 -31
  61. package/dist/lib/tree/CommandNode.d.ts +0 -45
  62. package/dist/lib/tree/LiteralCommandNode.d.ts +0 -27
  63. package/dist/lib/tree/RootCommandNode.d.ts +0 -21
  64. package/dist/lib/util/isEqual.d.ts +0 -1
  65. package/example/fill.js +0 -47
  66. package/example/fill.ts +0 -50
  67. package/src/index.ts +0 -50
  68. package/src/lib/AmbiguityConsumer.ts +0 -6
  69. package/src/lib/Command.ts +0 -5
  70. package/src/lib/CommandDispatcher.ts +0 -480
  71. package/src/lib/ImmutableStringReader.ts +0 -22
  72. package/src/lib/LiteralMessage.ts +0 -17
  73. package/src/lib/Message.ts +0 -3
  74. package/src/lib/ParseResults.ts +0 -32
  75. package/src/lib/Predicate.ts +0 -3
  76. package/src/lib/RedirectModifier.ts +0 -5
  77. package/src/lib/ResultConsumer.ts +0 -6
  78. package/src/lib/SingleRedirectModifier.ts +0 -6
  79. package/src/lib/StringReader.ts +0 -210
  80. package/src/lib/arguments/ArgumentType.ts +0 -28
  81. package/src/lib/arguments/BoolArgumentType.ts +0 -41
  82. package/src/lib/arguments/FloatArgumentType.ts +0 -75
  83. package/src/lib/arguments/IntegerArgumentType.ts +0 -75
  84. package/src/lib/arguments/StringArgumentType.ts +0 -83
  85. package/src/lib/builder/ArgumentBuilder.ts +0 -94
  86. package/src/lib/builder/LiteralArgumentBuilder.ts +0 -35
  87. package/src/lib/builder/RequiredArgumentBuilder.ts +0 -54
  88. package/src/lib/context/CommandContext.ts +0 -118
  89. package/src/lib/context/CommandContextBuilder.ts +0 -155
  90. package/src/lib/context/ParsedArgument.ts +0 -27
  91. package/src/lib/context/ParsedCommandNode.ts +0 -35
  92. package/src/lib/context/StringRange.ts +0 -57
  93. package/src/lib/context/SuggestionContext.ts +0 -12
  94. package/src/lib/exceptions/BuiltInExceptionProvider.ts +0 -43
  95. package/src/lib/exceptions/BuiltInExceptions.ts +0 -121
  96. package/src/lib/exceptions/CommandExceptionType.ts +0 -2
  97. package/src/lib/exceptions/CommandSyntaxException.ts +0 -77
  98. package/src/lib/exceptions/DynamicCommandExceptionType.ts +0 -22
  99. package/src/lib/exceptions/SimpleCommandExceptionType.ts +0 -26
  100. package/src/lib/suggestion/IntegerSuggestion.ts +0 -46
  101. package/src/lib/suggestion/Suggestion.ts +0 -87
  102. package/src/lib/suggestion/SuggestionProvider.ts +0 -7
  103. package/src/lib/suggestion/Suggestions.ts +0 -85
  104. package/src/lib/suggestion/SuggestionsBuilder.ts +0 -69
  105. package/src/lib/tree/ArgumentCommandNode.ts +0 -140
  106. package/src/lib/tree/CommandNode.ts +0 -208
  107. package/src/lib/tree/LiteralCommandNode.ts +0 -111
  108. package/src/lib/tree/RootCommandNode.ts +0 -62
  109. package/src/lib/util/isEqual.ts +0 -75
  110. package/test/CommandDispatcherTest.ts +0 -427
  111. package/test/CommandDispatcherUsagesTest.ts +0 -163
  112. package/test/CommandSuggestionsTest.ts +0 -283
  113. package/test/StringReaderTest.ts +0 -391
  114. package/test/arguments/BoolArgumentTypeTest.ts +0 -18
  115. package/test/arguments/FloatArgumentTypeTest.ts +0 -61
  116. package/test/arguments/IntegerArgumentTypeTest.ts +0 -63
  117. package/test/arguments/StringArgumentTypeTest.ts +0 -61
  118. package/test/benchmarks/ExecuteBenchmark.js +0 -33
  119. package/test/benchmarks/ParsingBenchmark.js +0 -96
  120. package/test/builder/ArgumentBuilderTest.ts +0 -61
  121. package/test/builder/LiteralArgumentBuilderTest.ts +0 -37
  122. package/test/builder/RequiredArgumentBuilderTest.ts +0 -40
  123. package/test/context/CommandContextTest.ts +0 -77
  124. package/test/context/ParsedArgumentTest.ts +0 -19
  125. package/test/exceptions/DynamicCommandSyntaxExceptionTypeTest.ts +0 -18
  126. package/test/exceptions/SimpleCommandSyntaxExceptionTypeTest.ts +0 -33
  127. package/test/suggestion/SuggestionBuilderTest.ts +0 -66
  128. package/test/suggestion/SuggestionTest.ts +0 -65
  129. package/test/suggestion/SuggestionsTest.ts +0 -24
  130. package/test/tree/AbstractCommandNodeTest.ts +0 -57
  131. package/test/tree/ArgumentCommandNodeTest.ts +0 -81
  132. package/test/tree/LiteralCommandNodeTest.ts +0 -112
  133. package/test/tree/RootCommandNodeTest.ts +0 -70
  134. package/test/utils/testEquality.ts +0 -10
  135. package/tsconfig.json +0 -41
  136. package/tsconfig.tsbuildinfo +0 -1585
@@ -1,26 +0,0 @@
1
- import Message from "../Message"
2
- import ImmutableStringReader from "../ImmutableStringReader"
3
- import CommandExceptionType from "./CommandExceptionType"
4
- import CommandSyntaxException from "./CommandSyntaxException";
5
-
6
- export default class SimpleCommandExceptionType implements CommandExceptionType {
7
-
8
- private message: Message;
9
-
10
- public constructor (message: Message) {
11
- this.message = message;
12
- Error.captureStackTrace(this, SimpleCommandExceptionType)
13
- }
14
-
15
- public create(): CommandSyntaxException {
16
- return new CommandSyntaxException(this, this.message)
17
- }
18
-
19
- public createWithContext(reader: ImmutableStringReader): CommandSyntaxException {
20
- return new CommandSyntaxException(this, this.message, reader.getString(), reader.getCursor());
21
- }
22
-
23
- public toString(): string {
24
- return this.message.getString();
25
- }
26
- }
@@ -1,46 +0,0 @@
1
- import Message from "../Message"
2
- import StringRange from "../context/StringRange"
3
- import Suggestion from "./Suggestion"
4
-
5
- export default class IntegerSuggestion extends Suggestion {
6
-
7
- private value: number;
8
-
9
- public constructor (range: StringRange, value: number, tooltip: Message = null) {
10
- super(range, value.toString(), tooltip);
11
- this.value = value;
12
- }
13
-
14
- public getValue(): number {
15
- return this.value;
16
- }
17
-
18
- public equals(o: object): boolean {
19
- if (this === o) return true;
20
-
21
- if (!(o instanceof IntegerSuggestion)) return false;
22
-
23
- return this.value == o.value && super.equals(o);
24
- }
25
-
26
- public toString(): String {
27
- return "IntegerSuggestion{" +
28
- "value=" + this.value +
29
- ", range=" + this.getRange() +
30
- ", text='" + this.getText() + '\'' +
31
- ", tooltip='" + this.getTooltip() + '\'' +
32
- '}';
33
- }
34
-
35
- public compareTo(o: Suggestion): number {
36
- if (o instanceof IntegerSuggestion) {
37
- return this.value < o.value ? 1 : - 1;
38
- }
39
-
40
- return super.compareTo(o);
41
- }
42
-
43
- public compareToIgnoreCase(b: Suggestion): number {
44
- return this.compareTo(b);
45
- }
46
- }
@@ -1,87 +0,0 @@
1
- import isEqual from "../util/isEqual"
2
- import Message from "../Message"
3
- import StringRange from "../context/StringRange"
4
-
5
- export default class Suggestion {
6
-
7
- private range: StringRange;
8
- private text: string;
9
- private tooltip: Message;
10
-
11
- public constructor (range: StringRange, text: string, tooltip: Message = null) {
12
- this.range = range;
13
- this.text = text;
14
- this.tooltip = tooltip;
15
- }
16
-
17
- public getRange(): StringRange {
18
- return this.range;
19
- }
20
-
21
- public getText(): string {
22
- return this.text;
23
- }
24
-
25
- public getTooltip(): Message {
26
- return this.tooltip;
27
- }
28
-
29
- public apply(input: string): string {
30
- if (this.range.getStart() === 0 && this.range.getEnd() == input.length) {
31
- return this.text;
32
- }
33
-
34
- let result = "";
35
- if (this.range.getStart() > 0) {
36
- result += input.substring(0, this.range.getStart());
37
- }
38
-
39
- result += this.text;
40
- if (this.range.getEnd() < input.length) {
41
- result += input.substring(this.range.getEnd());
42
- }
43
-
44
- return result;
45
- }
46
-
47
- public equals(o: object): boolean {
48
- if (this === o) return true;
49
- if (!(o instanceof Suggestion)) return false;
50
-
51
- return isEqual(this.range, o.range) && (this.text === o.text) && isEqual(this.tooltip, o.tooltip);
52
- }
53
-
54
- public toString(): String {
55
- return "Suggestion{" +
56
- "range=" + this.range +
57
- ", text='" + this.text + '\'' +
58
- ", tooltip='" + this.tooltip + '\'' +
59
- '}';
60
- }
61
-
62
- public compareTo(o: Suggestion): number {
63
- return this.text < o.text ? 1 : -1;
64
- }
65
-
66
- public compareToIgnoreCase(b: Suggestion): number {
67
- return this.text.toLowerCase() < b.text.toLowerCase() ? 1 : -1;
68
- }
69
-
70
- public expand(command: string, range: StringRange): Suggestion {
71
- if (range.equals(this.range)) {
72
- return this;
73
- }
74
-
75
- let result = "";
76
- if (range.getStart() < this.range.getStart()) {
77
- result += command.substring(range.getStart(), this.range.getStart());
78
- }
79
-
80
- result += this.text;
81
- if (range.getEnd() > this.range.getEnd()) {
82
- result += command.substring(this.range.getEnd(), range.getEnd());
83
- }
84
-
85
- return new Suggestion(range, result, this.tooltip);
86
- }
87
- }
@@ -1,7 +0,0 @@
1
- import Suggestions from "./Suggestions"
2
- import SuggestionsBuilder from "./SuggestionsBuilder"
3
- import CommandContext from "../context/CommandContext"
4
-
5
- export default interface SuggestionProvider<S> {
6
- getSuggestions(context: CommandContext<S>, builder: SuggestionsBuilder): Promise<Suggestions>;
7
- }
@@ -1,85 +0,0 @@
1
- import isEqual from "../util/isEqual"
2
- import StringRange from "../context/StringRange"
3
- import Suggestion from "./Suggestion"
4
-
5
- export default class Suggestions {
6
-
7
- private static EMPTY = new Suggestions(StringRange.at(0), []);
8
-
9
- private range: StringRange;
10
-
11
- private suggestions: Array<Suggestion>;
12
-
13
- public constructor (range: StringRange, suggestions: Array<Suggestion>) {
14
- this.range = range;
15
- this.suggestions = suggestions;
16
- }
17
-
18
- public getRange(): StringRange {
19
- return this.range;
20
- }
21
-
22
- public getList(): Array<Suggestion> {
23
- return this.suggestions;
24
- }
25
-
26
- public isEmpty(): boolean {
27
- return this.suggestions.length === 0;
28
- }
29
-
30
- public equals(o: object): boolean {
31
- if (this === o) return true;
32
-
33
- if (!(o instanceof Suggestions)) return false;
34
-
35
- return this.range.equals(o.range) && isEqual(this.suggestions, o.suggestions);
36
- }
37
-
38
- public toString(): String {
39
- return "Suggestions{" +
40
- "range=" + this.range +
41
- ", suggestions=" + this.suggestions + '}';
42
- }
43
-
44
- public static empty(): Promise<Suggestions> {
45
- return Promise.resolve(this.EMPTY);
46
- }
47
-
48
- public static merge(command: string, input: Array<Suggestions>): Suggestions {
49
- if (input.length === 0) {
50
- return this.EMPTY;
51
- }
52
- else if (input.length === 1) {
53
- return input[0];
54
- }
55
-
56
- const texts = [];
57
- for (let suggestions of input) {
58
- texts.push(...suggestions.getList());
59
- }
60
-
61
- return Suggestions.create(command, texts);
62
- }
63
-
64
- public static create(command: string, suggestions: Array<Suggestion>): Suggestions {
65
- if (suggestions.length === 0) {
66
- return this.EMPTY;
67
- }
68
-
69
- let start = Infinity;
70
- let end = -Infinity;
71
- for (let suggestion of suggestions) {
72
- start = Math.min(suggestion.getRange().getStart(), start);
73
- end = Math.max(suggestion.getRange().getEnd(), end);
74
- }
75
-
76
- let range = new StringRange(start, end);
77
- const texts = [];
78
- for (let suggestion of suggestions) {
79
- texts.push(suggestion.expand(command, range));
80
- }
81
-
82
- const sorted = texts.sort((a, b) => a.compareToIgnoreCase(b));
83
- return new Suggestions(range, sorted);
84
- }
85
- }
@@ -1,69 +0,0 @@
1
- import Message from "../Message"
2
- import StringRange from "../context/StringRange"
3
- import Suggestion from "./Suggestion"
4
- import Suggestions from "./Suggestions"
5
- import IntegerSuggestion from "./IntegerSuggestion"
6
-
7
- export default class SuggestionsBuilder {
8
-
9
- private input: string;
10
-
11
- private start: number;
12
-
13
- private remaining: string;
14
-
15
- private result: Array<Suggestion> = [];
16
-
17
- public constructor (input: string, start: number) {
18
- this.input = input;
19
- this.start = start;
20
- this.remaining = input.substring(start);
21
- }
22
-
23
- public getInput(): String {
24
- return this.input;
25
- }
26
-
27
- public getStart(): number {
28
- return this.start;
29
- }
30
-
31
- public getRemaining(): string {
32
- return this.remaining;
33
- }
34
-
35
- public build(): Suggestions {
36
- return Suggestions.create(this.input, this.result);
37
- }
38
-
39
- public buildPromise(): Promise<Suggestions> {
40
- return Promise.resolve(this.build());
41
- }
42
-
43
- public suggest(text: string | number, tooltip: Message = null): SuggestionsBuilder {
44
-
45
- if(typeof text === "number") {
46
- this.result.push(new IntegerSuggestion(StringRange.between(this.start, this.input.length), text, tooltip));
47
- return this;
48
- }
49
-
50
- if (text === this.remaining)
51
- return this;
52
-
53
- this.result.push(new Suggestion(StringRange.between(this.start, this.input.length), text, tooltip));
54
- return this;
55
- }
56
-
57
- public add(other: SuggestionsBuilder): SuggestionsBuilder {
58
- this.result.push(...other.result);
59
- return this;
60
- }
61
-
62
- public createOffset(start: number): SuggestionsBuilder {
63
- return new SuggestionsBuilder(this.input, this.start);
64
- }
65
-
66
- public restart(): SuggestionsBuilder {
67
- return new SuggestionsBuilder(this.input, this.start);
68
- }
69
- }
@@ -1,140 +0,0 @@
1
- import ArgumentType from '../arguments/ArgumentType';
2
- import Command from '../Command';
3
- import CommandContext from '../context/CommandContext';
4
- import CommandContextBuilder from '../context/CommandContextBuilder';
5
- import CommandNode from './CommandNode';
6
- import ParsedArgument from '../context/ParsedArgument';
7
- import Predicate from '../Predicate';
8
- import RedirectModifier from '../RedirectModifier';
9
- import RequiredArgumentBuilder from '../builder/RequiredArgumentBuilder';
10
- import StringReader from '../StringReader';
11
- import SuggestionProvider from '../suggestion/SuggestionProvider';
12
- import Suggestions from '../suggestion/Suggestions';
13
- import SuggestionsBuilder from '../suggestion/SuggestionsBuilder';
14
- import isEqual from '../util/isEqual';
15
-
16
- const USAGE_ARGUMENT_OPEN: string = '<';
17
- const USAGE_ARGUMENT_CLOSE: string = '>';
18
-
19
- export default class ArgumentCommandNode<S, T> extends CommandNode<S> {
20
- private name: string;
21
- private type: ArgumentType<T>;
22
- private customSuggestions: SuggestionProvider<S>;
23
-
24
- public constructor(
25
- name: string,
26
- type: ArgumentType<T>,
27
- command: Command<S>,
28
- requirement: Predicate<S>,
29
- redirect: CommandNode<S>,
30
- modifier: RedirectModifier<S>,
31
- forks: boolean,
32
- customSuggestions: SuggestionProvider<S>
33
- ) {
34
- super(command, requirement, redirect, modifier, forks);
35
- this.name = name;
36
- this.type = type;
37
- this.customSuggestions = customSuggestions;
38
- }
39
-
40
- public getNodeType(): string {
41
- return 'argument';
42
- }
43
-
44
- public getType(): ArgumentType<T> {
45
- return this.type;
46
- }
47
-
48
- public getName(): string {
49
- return this.name;
50
- }
51
-
52
- public getUsageText(): string {
53
- return USAGE_ARGUMENT_OPEN + this.name + USAGE_ARGUMENT_CLOSE;
54
- }
55
-
56
- public getCustomSuggestions(): SuggestionProvider<S> {
57
- return this.customSuggestions;
58
- }
59
-
60
- public parse(
61
- reader: StringReader,
62
- contextBuilder: CommandContextBuilder<S>
63
- ) {
64
- let start = reader.getCursor();
65
- let result: T = this.type.parse(reader, contextBuilder as any);
66
- let parsed: ParsedArgument<S, T> = new ParsedArgument(
67
- start,
68
- reader.getCursor(),
69
- result
70
- );
71
- contextBuilder.withArgument(this.name, parsed);
72
- contextBuilder.withNode(this, parsed.getRange());
73
- }
74
-
75
- public listSuggestions(
76
- context: CommandContext<S>,
77
- builder: SuggestionsBuilder
78
- ): Promise<Suggestions> {
79
- if (this.customSuggestions == null) {
80
- if (typeof this.type.listSuggestions === 'function')
81
- return this.type.listSuggestions(context, builder);
82
- else return Suggestions.empty();
83
- } else {
84
- return this.customSuggestions.getSuggestions(context, builder);
85
- }
86
- }
87
-
88
- public createBuilder(): RequiredArgumentBuilder<S, T> {
89
- let builder: RequiredArgumentBuilder<
90
- S,
91
- T
92
- > = RequiredArgumentBuilder.argument(this.name, this.type);
93
- builder.requires(this.getRequirement());
94
- builder.forward(
95
- this.getRedirect(),
96
- this.getRedirectModifier(),
97
- this.isFork()
98
- );
99
- builder.suggests(this.customSuggestions);
100
- if (this.getCommand() != null) {
101
- builder.executes(this.getCommand());
102
- }
103
-
104
- return builder;
105
- }
106
-
107
- public isValidInput(input: string, context: any): boolean {
108
- try {
109
- let reader: StringReader = new StringReader(input);
110
- this.type.parse(reader, context);
111
- return !reader.canRead() || reader.peek() == ' ';
112
- } catch (ignored) {}
113
-
114
- return false;
115
- }
116
-
117
- public equals(o: object): boolean {
118
- if (this === o) return true;
119
- if (!(o instanceof ArgumentCommandNode)) return false;
120
-
121
- if (!(this.name === o.name)) return false;
122
- if (!isEqual(this.type, o.type)) return false;
123
-
124
- return super.equals(o);
125
- }
126
-
127
- public getSortedKey(): string {
128
- return this.name;
129
- }
130
-
131
- public getExamples(): Iterable<string> {
132
- return typeof this.type.getExamples === 'function'
133
- ? this.type.getExamples()
134
- : [];
135
- }
136
-
137
- public toString(): string {
138
- return '<argument ' + this.name + ':' + this.type + '>';
139
- }
140
- }
@@ -1,208 +0,0 @@
1
- import AmbiguityConsumer from '../AmbiguityConsumer';
2
- import ArgumentBuilder from '../builder/ArgumentBuilder';
3
- import Command from '../Command';
4
- import CommandContext from '../context/CommandContext';
5
- import CommandContextBuilder from '../context/CommandContextBuilder';
6
- import Predicate from '../Predicate';
7
- import RedirectModifier from '../RedirectModifier';
8
- import StringReader from '../StringReader';
9
- import Suggestions from '../suggestion/Suggestions';
10
- import SuggestionsBuilder from '../suggestion/SuggestionsBuilder';
11
- import isEqual from '../util/isEqual';
12
-
13
- abstract class CommandNode<S> {
14
- private children: Map<string, CommandNode<S>> = new Map();
15
-
16
- private literals: Map<string, any> = new Map();
17
-
18
- private args: Map<string, any> = new Map();
19
-
20
- private requirement: Predicate<S>;
21
-
22
- private redirect: CommandNode<S>;
23
-
24
- private modifier: RedirectModifier<S>;
25
-
26
- private forks: boolean;
27
-
28
- private command: Command<S>;
29
-
30
- public abstract getNodeType(): string;
31
-
32
- public constructor(
33
- command: Command<S>,
34
- requirement: Predicate<S>,
35
- redirect: CommandNode<S>,
36
- modifier: RedirectModifier<S>,
37
- forks: boolean
38
- ) {
39
- this.command = command;
40
- this.requirement = requirement || (() => true);
41
- this.redirect = redirect;
42
- this.modifier = modifier;
43
- this.forks = forks;
44
- }
45
-
46
- public getCommand(): Command<S> {
47
- return this.command;
48
- }
49
-
50
- public getChildren(): IterableIterator<CommandNode<S>> {
51
- return this.children.values();
52
- }
53
-
54
- public getChildrenCount(): number {
55
- return this.children.size;
56
- }
57
-
58
- public getChild(name: string): CommandNode<S> {
59
- return this.children.get(name);
60
- }
61
-
62
- public getRedirect(): CommandNode<S> {
63
- return this.redirect;
64
- }
65
-
66
- public getRedirectModifier(): RedirectModifier<S> {
67
- return this.modifier;
68
- }
69
-
70
- public canUse(source: S): boolean {
71
- return this.requirement(source);
72
- }
73
-
74
- public addChild(node: CommandNode<S>) {
75
- if (node.getNodeType() === 'root') {
76
- throw new Error(
77
- 'Cannot add a RootCommandNode as a child to any other CommandNode'
78
- );
79
- }
80
-
81
- let child = this.children.get(node.getName());
82
- if (child != null) {
83
- // We've found something to merge onto
84
- if (node.getCommand() != null) {
85
- child.command = node.getCommand();
86
- }
87
-
88
- for (let grandchild of node.getChildren()) {
89
- child.addChild(grandchild);
90
- }
91
- } else {
92
- this.children.set(node.getName(), node);
93
- if (node.getNodeType() === 'literal') {
94
- this.literals.set(node.getName(), node);
95
- } else if (node.getNodeType() === 'argument') {
96
- this.args.set(node.getName(), node);
97
- }
98
- }
99
-
100
- this.children = new Map(
101
- [...this.children.entries()].sort((a, b) => a[1].compareTo(b[1]))
102
- );
103
- }
104
-
105
- public findAmbiguities(consumer: AmbiguityConsumer<S>, context: any) {
106
- let matches: Array<string> = [];
107
- for (let child of this.children.values()) {
108
- for (let sibling of this.children.values()) {
109
- if (child === sibling) {
110
- continue;
111
- }
112
-
113
- for (let input of child.getExamples()) {
114
- if (sibling.isValidInput(input, context)) {
115
- matches.push(input);
116
- }
117
- }
118
-
119
- if (matches.length > 0) {
120
- consumer.ambiguous(this, child, sibling, matches);
121
- matches = [];
122
- }
123
- }
124
-
125
- child.findAmbiguities(consumer, context);
126
- }
127
- }
128
-
129
- public abstract isValidInput(input: string, context: any): boolean;
130
-
131
- public equals(o: object): boolean {
132
- if (this === o) return true;
133
- if (!(o instanceof CommandNode)) return false;
134
-
135
- if (this.children.size !== o.children.size) {
136
- return false;
137
- }
138
-
139
- if (!isEqual(this.children, o.children)) return false;
140
-
141
- if (
142
- this.command != null
143
- ? !isEqual(this.command, o.command)
144
- : o.command != null
145
- )
146
- return false;
147
-
148
- return true;
149
- }
150
-
151
- public getRequirement() {
152
- return this.requirement;
153
- }
154
-
155
- public abstract getName(): string;
156
-
157
- public abstract getUsageText(): string;
158
-
159
- public abstract parse(
160
- reader: StringReader,
161
- contextBuilder: CommandContextBuilder<S>
162
- ): void;
163
-
164
- public abstract listSuggestions(
165
- context: CommandContext<S>,
166
- builder: SuggestionsBuilder
167
- ): Promise<Suggestions>;
168
-
169
- public abstract createBuilder(): ArgumentBuilder<S, any>;
170
-
171
- public abstract getSortedKey(): string;
172
-
173
- public getRelevantNodes(input: StringReader): Iterable<CommandNode<S>> {
174
- if (this.literals.size > 0) {
175
- let cursor: number = input.getCursor();
176
- while (input.canRead() && input.peek() != ' ') {
177
- input.skip();
178
- }
179
-
180
- let text = input.getString().substring(cursor, input.getCursor());
181
- input.setCursor(cursor);
182
- let literal = this.literals.get(text);
183
- if (literal != null) {
184
- return [literal];
185
- } else {
186
- return this.args.values();
187
- }
188
- } else {
189
- return this.args.values();
190
- }
191
- }
192
-
193
- public compareTo(o: CommandNode<S>): number {
194
- if (this.getNodeType() === o.getNodeType()) {
195
- return this.getSortedKey() > o.getSortedKey() ? 1 : -1;
196
- }
197
-
198
- return o.getNodeType() === 'literal' ? 1 : -1;
199
- }
200
-
201
- public isFork(): boolean {
202
- return this.forks;
203
- }
204
-
205
- public abstract getExamples(): Iterable<string>;
206
- }
207
-
208
- export default CommandNode;