@spyglassmc/mcfunction 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/README.md +49 -0
- package/lib/colorizer/index.d.ts +3 -0
- package/lib/colorizer/index.js +29 -0
- package/lib/completer/command.d.ts +1 -0
- package/lib/completer/command.js +2 -0
- package/lib/completer/index.d.ts +12 -0
- package/lib/completer/index.js +70 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +39 -0
- package/lib/node/argument.d.ts +11 -0
- package/lib/node/argument.js +3 -0
- package/lib/node/command.d.ts +35 -0
- package/lib/node/command.js +54 -0
- package/lib/node/entry.d.ts +9 -0
- package/lib/node/entry.js +12 -0
- package/lib/node/index.d.ts +3 -0
- package/lib/node/index.js +15 -0
- package/lib/node/literal.d.ts +9 -0
- package/lib/node/literal.js +12 -0
- package/lib/parser/argument.d.ts +12 -0
- package/lib/parser/argument.js +9 -0
- package/lib/parser/command.d.ts +12 -0
- package/lib/parser/command.js +181 -0
- package/lib/parser/common.d.ts +8 -0
- package/lib/parser/common.js +39 -0
- package/lib/parser/entry.d.ts +8 -0
- package/lib/parser/entry.js +55 -0
- package/lib/parser/index.d.ts +6 -0
- package/lib/parser/index.js +18 -0
- package/lib/parser/literal.d.ts +4 -0
- package/lib/parser/literal.js +49 -0
- package/lib/tree/index.d.ts +4 -0
- package/lib/tree/index.js +16 -0
- package/lib/tree/registry.d.ts +27 -0
- package/lib/tree/registry.js +60 -0
- package/lib/tree/type.d.ts +32 -0
- package/lib/tree/type.js +3 -0
- package/lib/tree/util.d.ts +21 -0
- package/lib/tree/util.js +42 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# `@spyglassmc/mcfunction`
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
[](https://npmjs.com/package/@spyglassmc/mcfunction)
|
|
6
|
+
|
|
7
|
+
This package contains parsers and processors for [mcfunction][mcfunction].
|
|
8
|
+
|
|
9
|
+
# Usage
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import * as mcf from '@spyglassmc/mcfunction'
|
|
13
|
+
|
|
14
|
+
// Register the command tree for a specific version.
|
|
15
|
+
mcf.CommandTreeRegistry.instance.register('1.15', vanillaCommandTreeFor1_15, customCommandTreePatchFor1_15)
|
|
16
|
+
|
|
17
|
+
// Define a function that returns the corresponding parser for the provided argument tree node.
|
|
18
|
+
const argument: mcf.parser.ArgumentParserGetter = (treeNode: mcf.ArgumentTreeNode) => {
|
|
19
|
+
switch (treeNode.parser) {
|
|
20
|
+
case 'brigadier:double':
|
|
21
|
+
return parser1
|
|
22
|
+
case 'brigadier:int':
|
|
23
|
+
return parser2
|
|
24
|
+
// ...
|
|
25
|
+
default:
|
|
26
|
+
// Unsupported parser.
|
|
27
|
+
// Just return `undefined`.
|
|
28
|
+
return undefined
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Get the command parser.
|
|
33
|
+
const commandParser = mcf.parser.command('1.15', argument)
|
|
34
|
+
|
|
35
|
+
// Or the mcfunction parser.
|
|
36
|
+
const mcfunctionParser = mcf.parser.entry('1.15', argument)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
# Contributions
|
|
40
|
+
|
|
41
|
+
## Languages
|
|
42
|
+
|
|
43
|
+
- `mcfunction` language that is associated with the `.mcfunction` file extension.
|
|
44
|
+
|
|
45
|
+
## AST Nodes
|
|
46
|
+
|
|
47
|
+
## Processors
|
|
48
|
+
|
|
49
|
+
[mcfunction]: https://minecraft.fandom.com/Function_(Java_Edition)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.register = void 0;
|
|
23
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
24
|
+
function register(meta) {
|
|
25
|
+
meta.registerColorizer('mcfunction:command_child/literal', core.colorizer.literal);
|
|
26
|
+
meta.registerColorizer('mcfunction:command_child/trailing', core.colorizer.error);
|
|
27
|
+
}
|
|
28
|
+
exports.register = register;
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
import type { McfunctionNode } from '../node';
|
|
3
|
+
import { CommandNode } from '../node';
|
|
4
|
+
import type { ArgumentTreeNode, RootTreeNode } from '../tree';
|
|
5
|
+
export declare type MockNodesGetter = (treeNode: ArgumentTreeNode, range: core.RangeLike) => core.Arrayable<core.AstNode>;
|
|
6
|
+
/**
|
|
7
|
+
* @param getMockNodes A function that returns a mock AST Node from given {@link ArgumentTreeNode}. These mock nodes
|
|
8
|
+
* will be used for completing the argument.
|
|
9
|
+
*/
|
|
10
|
+
export declare function entry(commandTreeName: string, getMockNodes: MockNodesGetter): core.Completer<McfunctionNode>;
|
|
11
|
+
export declare function command(tree: RootTreeNode, getMockNodes: MockNodesGetter): core.Completer<CommandNode>;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.command = exports.entry = void 0;
|
|
23
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
24
|
+
const node_1 = require("../node");
|
|
25
|
+
const tree_1 = require("../tree");
|
|
26
|
+
/**
|
|
27
|
+
* @param getMockNodes A function that returns a mock AST Node from given {@link ArgumentTreeNode}. These mock nodes
|
|
28
|
+
* will be used for completing the argument.
|
|
29
|
+
*/
|
|
30
|
+
function entry(commandTreeName, getMockNodes) {
|
|
31
|
+
return (node, ctx) => {
|
|
32
|
+
const tree = tree_1.CommandTreeRegistry.instance.get(commandTreeName);
|
|
33
|
+
const childNode = core.AstNode.findChild(node, ctx.offset, true);
|
|
34
|
+
if (core.CommentNode.is(childNode)) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
return command(tree, getMockNodes)(childNode ?? node_1.CommandNode.mock(ctx.offset), ctx);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exports.entry = entry;
|
|
43
|
+
function command(tree, getMockNodes) {
|
|
44
|
+
return (node, ctx) => {
|
|
45
|
+
const index = core.AstNode.findChildIndex(node, ctx.offset, true);
|
|
46
|
+
const selectedChildNode = node.children[index]?.children[0];
|
|
47
|
+
if (selectedChildNode) {
|
|
48
|
+
return core.completer.dispatch(selectedChildNode, ctx);
|
|
49
|
+
}
|
|
50
|
+
const lastChildNode = core.AstNode.findLastChild(node, ctx.offset);
|
|
51
|
+
if (!lastChildNode) {
|
|
52
|
+
return Object
|
|
53
|
+
.keys(tree.children ?? {})
|
|
54
|
+
.map(v => core.CompletionItem.create(v, ctx.offset, { kind: 14 /* Keyword */ }));
|
|
55
|
+
}
|
|
56
|
+
const treePath = lastChildNode.path;
|
|
57
|
+
const { treeNode: parentTreeNode } = (0, tree_1.resolveParentTreeNode)((0, tree_1.redirect)(tree, treePath), tree);
|
|
58
|
+
if (!parentTreeNode?.children) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const { literalTreeNodes, argumentTreeNodes } = (0, tree_1.categorizeTreeChildren)(parentTreeNode.children);
|
|
62
|
+
return [
|
|
63
|
+
...literalTreeNodes.map(([name]) => core.CompletionItem.create(name, ctx.offset, { kind: 14 /* Keyword */ })),
|
|
64
|
+
...argumentTreeNodes.flatMap(([_name, treeNode]) => core.Arrayable.toArray(getMockNodes(treeNode, ctx.offset))
|
|
65
|
+
.flatMap(n => core.completer.dispatch(n, ctx))),
|
|
66
|
+
];
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
exports.command = command;
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
export * as colorizer from './colorizer';
|
|
3
|
+
export * as completer from './completer';
|
|
4
|
+
export * from './node';
|
|
5
|
+
export * from './parser';
|
|
6
|
+
export * from './tree';
|
|
7
|
+
export declare const initialize: core.ProjectInitializer;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
22
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.initialize = exports.completer = exports.colorizer = void 0;
|
|
26
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
27
|
+
const colorizer = __importStar(require("./colorizer"));
|
|
28
|
+
exports.colorizer = __importStar(require("./colorizer"));
|
|
29
|
+
exports.completer = __importStar(require("./completer"));
|
|
30
|
+
__exportStar(require("./node"), exports);
|
|
31
|
+
__exportStar(require("./parser"), exports);
|
|
32
|
+
__exportStar(require("./tree"), exports);
|
|
33
|
+
/* istanbul ignore next */
|
|
34
|
+
const initialize = ({ meta }) => {
|
|
35
|
+
colorizer.register(meta);
|
|
36
|
+
meta.registerCompleter('mcfunction:command_child/literal', core.completer.literal);
|
|
37
|
+
};
|
|
38
|
+
exports.initialize = initialize;
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ChildBaseNode } from './command';
|
|
2
|
+
export interface SpyglassmcTrailingArgumentNode extends ChildBaseNode {
|
|
3
|
+
type: 'mcfunction:argument/spyglassmc:trailing';
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SpyglassmcUnknownArgumentNode extends ChildBaseNode {
|
|
7
|
+
type: 'mcfunction:argument/spyglassmc:unknown';
|
|
8
|
+
value: string;
|
|
9
|
+
}
|
|
10
|
+
export declare type SpecialArgumentNode = SpyglassmcTrailingArgumentNode | SpyglassmcUnknownArgumentNode;
|
|
11
|
+
//# sourceMappingURL=argument.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
export interface CommandNode extends core.SequenceNode<CommandChildNode> {
|
|
3
|
+
type: 'mcfunction:command';
|
|
4
|
+
slash?: core.Range;
|
|
5
|
+
}
|
|
6
|
+
export declare namespace CommandNode {
|
|
7
|
+
function is(node: core.AstNode): node is CommandNode;
|
|
8
|
+
function mock(range: core.RangeLike): CommandNode;
|
|
9
|
+
}
|
|
10
|
+
export interface CommandChildNode extends core.AstNode {
|
|
11
|
+
type: 'mcfunction:command_child';
|
|
12
|
+
/**
|
|
13
|
+
* The path of this node in the command tree. Empty if the current node does not correspond to an actual tree node.
|
|
14
|
+
*/
|
|
15
|
+
path: string[];
|
|
16
|
+
children: [core.AstNode];
|
|
17
|
+
}
|
|
18
|
+
export declare namespace CommandChildNode {
|
|
19
|
+
function is(node: core.AstNode): node is CommandChildNode;
|
|
20
|
+
}
|
|
21
|
+
export interface TrailingCommandChildNode extends core.AstNode {
|
|
22
|
+
type: 'mcfunction:command_child/trailing';
|
|
23
|
+
value: string;
|
|
24
|
+
}
|
|
25
|
+
export interface UnknownCommandChildNode extends core.AstNode {
|
|
26
|
+
type: 'mcfunction:command_child/unknown';
|
|
27
|
+
value: string;
|
|
28
|
+
}
|
|
29
|
+
export interface LiteralCommandChildNode extends core.LiteralBaseNode {
|
|
30
|
+
type: 'mcfunction:command_child/literal';
|
|
31
|
+
}
|
|
32
|
+
export declare namespace LiteralCommandChildNode {
|
|
33
|
+
function is(node: core.AstNode | undefined): node is LiteralCommandChildNode;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.LiteralCommandChildNode = exports.CommandChildNode = exports.CommandNode = void 0;
|
|
23
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
24
|
+
var CommandNode;
|
|
25
|
+
(function (CommandNode) {
|
|
26
|
+
/* istanbul ignore next */
|
|
27
|
+
function is(node) {
|
|
28
|
+
return node.type === 'mcfunction:command';
|
|
29
|
+
}
|
|
30
|
+
CommandNode.is = is;
|
|
31
|
+
function mock(range) {
|
|
32
|
+
return {
|
|
33
|
+
type: 'mcfunction:command',
|
|
34
|
+
range: core.Range.get(range),
|
|
35
|
+
children: [],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
CommandNode.mock = mock;
|
|
39
|
+
})(CommandNode = exports.CommandNode || (exports.CommandNode = {}));
|
|
40
|
+
var CommandChildNode;
|
|
41
|
+
(function (CommandChildNode) {
|
|
42
|
+
function is(node) {
|
|
43
|
+
return node.type === 'mcfunction:command_child';
|
|
44
|
+
}
|
|
45
|
+
CommandChildNode.is = is;
|
|
46
|
+
})(CommandChildNode = exports.CommandChildNode || (exports.CommandChildNode = {}));
|
|
47
|
+
var LiteralCommandChildNode;
|
|
48
|
+
(function (LiteralCommandChildNode) {
|
|
49
|
+
function is(node) {
|
|
50
|
+
return node?.type === 'mcfunction:command_child/literal';
|
|
51
|
+
}
|
|
52
|
+
LiteralCommandChildNode.is = is;
|
|
53
|
+
})(LiteralCommandChildNode = exports.LiteralCommandChildNode || (exports.LiteralCommandChildNode = {}));
|
|
54
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as core from '@spyglassmc/core';
|
|
2
|
+
import type { CommandNode } from './command';
|
|
3
|
+
export interface McfunctionNode extends core.SequenceNode<CommandNode | core.CommentNode> {
|
|
4
|
+
type: 'mcfunction:entry';
|
|
5
|
+
}
|
|
6
|
+
export declare namespace McfunctionNode {
|
|
7
|
+
function is(node: core.AstNode | undefined): node is McfunctionNode;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=entry.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.McfunctionNode = void 0;
|
|
4
|
+
var McfunctionNode;
|
|
5
|
+
(function (McfunctionNode) {
|
|
6
|
+
/* istanbul ignore next */
|
|
7
|
+
function is(node) {
|
|
8
|
+
return node?.type === 'mcfunction:entry';
|
|
9
|
+
}
|
|
10
|
+
McfunctionNode.is = is;
|
|
11
|
+
})(McfunctionNode = exports.McfunctionNode || (exports.McfunctionNode = {}));
|
|
12
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./command"), exports);
|
|
14
|
+
__exportStar(require("./entry"), exports);
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as core from '@spyglassmc/core';
|
|
2
|
+
import type { ChildBaseNode } from './command';
|
|
3
|
+
export interface LiteralNode extends core.LiteralBaseNode, ChildBaseNode {
|
|
4
|
+
type: 'mcfunction:literal';
|
|
5
|
+
}
|
|
6
|
+
export declare namespace LiteralNode {
|
|
7
|
+
function is(node: core.AstNode): node is LiteralNode;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=literal.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LiteralNode = void 0;
|
|
4
|
+
var LiteralNode;
|
|
5
|
+
(function (LiteralNode) {
|
|
6
|
+
/* istanbul ignore next */
|
|
7
|
+
function is(node) {
|
|
8
|
+
return node.type === 'mcfunction:literal';
|
|
9
|
+
}
|
|
10
|
+
LiteralNode.is = is;
|
|
11
|
+
})(LiteralNode = exports.LiteralNode || (exports.LiteralNode = {}));
|
|
12
|
+
//# sourceMappingURL=literal.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type * as core from '@spyglassmc/core';
|
|
2
|
+
import type { ArgumentTreeNode } from '../tree';
|
|
3
|
+
/**
|
|
4
|
+
* A function that returns a parser for the provided tree node.
|
|
5
|
+
*
|
|
6
|
+
* @param treeNode The argument tree node.
|
|
7
|
+
*
|
|
8
|
+
* @returns The parser corresponding to that tree node, or `undefined` if such parser doesn't exist.
|
|
9
|
+
*/
|
|
10
|
+
export declare type ArgumentParserGetter = (treeNode: ArgumentTreeNode) => core.Parser | undefined;
|
|
11
|
+
export declare function argumentTreeNodeToString(name: string, treeNode: ArgumentTreeNode): string;
|
|
12
|
+
//# sourceMappingURL=argument.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.argumentTreeNodeToString = void 0;
|
|
4
|
+
function argumentTreeNodeToString(name, treeNode) {
|
|
5
|
+
const parserName = treeNode.parser.slice(treeNode.parser.indexOf(':') + 1);
|
|
6
|
+
return `<${name}: ${parserName}>`;
|
|
7
|
+
}
|
|
8
|
+
exports.argumentTreeNodeToString = argumentTreeNodeToString;
|
|
9
|
+
//# sourceMappingURL=argument.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
import type { CommandNode } from '../node';
|
|
3
|
+
import type { RootTreeNode, TreeNode } from '../tree/type';
|
|
4
|
+
import type { ArgumentParserGetter } from './argument';
|
|
5
|
+
/**
|
|
6
|
+
* @returns A parser that always takes a whole line (excluding line turn characters) and tries to parse it as a command.
|
|
7
|
+
*/
|
|
8
|
+
export declare function command(tree: RootTreeNode, argument: ArgumentParserGetter): core.InfallibleParser<CommandNode>;
|
|
9
|
+
export declare function treeNodeChildrenToStringArray(children: Exclude<TreeNode['children'], undefined>, executable?: boolean): string[];
|
|
10
|
+
export declare function treeNodeChildrenToString(children: Exclude<TreeNode['children'], undefined>): string;
|
|
11
|
+
export declare function treeNodeToString(name: string, treeNode: TreeNode): string;
|
|
12
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.treeNodeToString = exports.treeNodeChildrenToString = exports.treeNodeChildrenToStringArray = exports.command = void 0;
|
|
23
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
24
|
+
const locales_1 = require("@spyglassmc/locales");
|
|
25
|
+
const tree_1 = require("../tree");
|
|
26
|
+
const argument_1 = require("./argument");
|
|
27
|
+
const common_1 = require("./common");
|
|
28
|
+
const literal_1 = require("./literal");
|
|
29
|
+
/**
|
|
30
|
+
* @returns A parser that always takes a whole line (excluding line turn characters) and tries to parse it as a command.
|
|
31
|
+
*/
|
|
32
|
+
function command(tree, argument) {
|
|
33
|
+
return (src, ctx) => {
|
|
34
|
+
const ans = {
|
|
35
|
+
type: 'mcfunction:command',
|
|
36
|
+
range: core.Range.create(src),
|
|
37
|
+
children: [],
|
|
38
|
+
};
|
|
39
|
+
const start = src.cursor;
|
|
40
|
+
if (src.trySkip('/')) {
|
|
41
|
+
ans.slash = core.Range.create(start, src.cursor);
|
|
42
|
+
}
|
|
43
|
+
dispatch(ans.children, src, ctx, [], tree, tree, argument);
|
|
44
|
+
if (src.canReadInLine()) {
|
|
45
|
+
// There is trailing string after the command.
|
|
46
|
+
const node = trailing(src, ctx);
|
|
47
|
+
ans.children.push({
|
|
48
|
+
type: 'mcfunction:command_child',
|
|
49
|
+
range: node.range,
|
|
50
|
+
children: [node],
|
|
51
|
+
path: [],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
ans.range.end = src.cursor;
|
|
55
|
+
return ans;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
exports.command = command;
|
|
59
|
+
/**
|
|
60
|
+
* Dispatch and parse based on the specified command tree node's children.
|
|
61
|
+
*
|
|
62
|
+
* @param ans An array where child nodes will be pushed into.
|
|
63
|
+
*/
|
|
64
|
+
function dispatch(ans, src, ctx, path, rootTreeNode, parentTreeNode, argument) {
|
|
65
|
+
// Convention: suffix `Node` is for AST nodes; `TreeNode` is for command tree nodes.
|
|
66
|
+
function _dispatch(path, parentTreeNode) {
|
|
67
|
+
const { treeNode: parent, path: resolvedPath } = (0, tree_1.resolveParentTreeNode)(parentTreeNode, rootTreeNode, path);
|
|
68
|
+
path = resolvedPath;
|
|
69
|
+
const children = parent?.children;
|
|
70
|
+
if (!children) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const { literalTreeNodes, argumentTreeNodes } = (0, tree_1.categorizeTreeChildren)(children);
|
|
74
|
+
const argumentParsers = argumentTreeNodes.map(([name, treeNode]) => ({
|
|
75
|
+
name,
|
|
76
|
+
parser: argument(treeNode) ?? unknown(treeNode),
|
|
77
|
+
}));
|
|
78
|
+
const literalParser = literalTreeNodes.length
|
|
79
|
+
? (0, literal_1.literal)(literalTreeNodes.map(([name, _treeNode]) => name), parent.type === 'root')
|
|
80
|
+
: undefined;
|
|
81
|
+
const parsers = [
|
|
82
|
+
...literalParser ? [literalParser] : [],
|
|
83
|
+
...argumentParsers.map(v => v.parser),
|
|
84
|
+
];
|
|
85
|
+
const out = { index: 0 };
|
|
86
|
+
const parser = parsers.length > 1 ? core.any(parsers, out) : parsers[0];
|
|
87
|
+
const result = parser(src, ctx);
|
|
88
|
+
if (result !== core.Failure) {
|
|
89
|
+
const takenName = argumentParsers[out.index]?.name ?? result.value;
|
|
90
|
+
const childPath = [...path, takenName];
|
|
91
|
+
ans.push({
|
|
92
|
+
type: 'mcfunction:command_child',
|
|
93
|
+
range: result.range,
|
|
94
|
+
children: [result],
|
|
95
|
+
path: childPath,
|
|
96
|
+
});
|
|
97
|
+
const childTreeNode = children[takenName];
|
|
98
|
+
if (!childTreeNode) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
const requiredPermissionLevel = childTreeNode.permission ?? 2;
|
|
102
|
+
if (ctx.config.env.permissionLevel < requiredPermissionLevel) {
|
|
103
|
+
ctx.err.report((0, locales_1.localize)('mcfunction.parser.no-permission', requiredPermissionLevel, ctx.config.env.permissionLevel), result);
|
|
104
|
+
}
|
|
105
|
+
if (result.type === 'mcfunction:command_child/unknown') {
|
|
106
|
+
// Encountered an unsupported parser. Stop parsing this command.
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if (src.canReadInLine()) {
|
|
110
|
+
// Skip command argument separation (a space).
|
|
111
|
+
(0, common_1.sep)(src, ctx);
|
|
112
|
+
return { childPath, childTreeNode };
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// End-of-command.
|
|
116
|
+
if (!childTreeNode.executable) {
|
|
117
|
+
ctx.err.report((0, locales_1.localize)('mcfunction.parser.eoc-unexpected'), src);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Failed to parse as any arguments.
|
|
123
|
+
ctx.err.report((0, locales_1.localize)('expected', treeNodeChildrenToString(children)), core.Range.create(src));
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
let result = _dispatch(path, parentTreeNode);
|
|
128
|
+
while (result) {
|
|
129
|
+
result = _dispatch(result.childPath, result.childTreeNode);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function unknown(treeNode) {
|
|
133
|
+
return (src, ctx) => {
|
|
134
|
+
const start = src.cursor;
|
|
135
|
+
const value = src.readUntilLineEnd();
|
|
136
|
+
const range = core.Range.create(start, src);
|
|
137
|
+
ctx.err.report((0, locales_1.localize)('mcfunction.parser.unknown-parser', (0, locales_1.localeQuote)(treeNode.parser)), range, 0 /* Hint */);
|
|
138
|
+
return {
|
|
139
|
+
type: 'mcfunction:command_child/unknown',
|
|
140
|
+
range,
|
|
141
|
+
value,
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const trailing = (src, ctx) => {
|
|
146
|
+
const start = src.cursor;
|
|
147
|
+
const value = src.readUntilLineEnd();
|
|
148
|
+
const range = core.Range.create(start, src);
|
|
149
|
+
ctx.err.report((0, locales_1.localize)('mcfunction.parser.trailing', (0, locales_1.localeQuote)(value)), range);
|
|
150
|
+
return {
|
|
151
|
+
type: 'mcfunction:command_child/trailing',
|
|
152
|
+
range,
|
|
153
|
+
value,
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
function wrapWithBrackets(syntax, executable) {
|
|
157
|
+
return executable ? `[${syntax}]` : syntax;
|
|
158
|
+
}
|
|
159
|
+
function treeNodeChildrenToStringArray(children, executable = false) {
|
|
160
|
+
const entries = Object.entries(children)
|
|
161
|
+
.map(([name, treeNode]) => wrapWithBrackets(treeNodeToString(name, treeNode), executable));
|
|
162
|
+
return entries;
|
|
163
|
+
}
|
|
164
|
+
exports.treeNodeChildrenToStringArray = treeNodeChildrenToStringArray;
|
|
165
|
+
function treeNodeChildrenToString(children) {
|
|
166
|
+
const entries = treeNodeChildrenToStringArray(children);
|
|
167
|
+
return entries.length > 5
|
|
168
|
+
? `${entries.slice(0, 3).join('|')}|...|${entries.slice(-2).join('|')}`
|
|
169
|
+
: entries.join('|');
|
|
170
|
+
}
|
|
171
|
+
exports.treeNodeChildrenToString = treeNodeChildrenToString;
|
|
172
|
+
function treeNodeToString(name, treeNode) {
|
|
173
|
+
if (treeNode.type === 'argument') {
|
|
174
|
+
return (0, argument_1.argumentTreeNodeToString)(name, treeNode);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
return name;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.treeNodeToString = treeNodeToString;
|
|
181
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
/**
|
|
3
|
+
* A parser that takes a continuous sequence of spaces and tabs, and marks an error if it is not a single space.
|
|
4
|
+
*
|
|
5
|
+
* @returns The accepted spaces and tabs.
|
|
6
|
+
*/
|
|
7
|
+
export declare const sep: core.InfallibleParser<string>;
|
|
8
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.sep = void 0;
|
|
23
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
24
|
+
const locales_1 = require("@spyglassmc/locales");
|
|
25
|
+
/**
|
|
26
|
+
* A parser that takes a continuous sequence of spaces and tabs, and marks an error if it is not a single space.
|
|
27
|
+
*
|
|
28
|
+
* @returns The accepted spaces and tabs.
|
|
29
|
+
*/
|
|
30
|
+
const sep = (src, ctx) => {
|
|
31
|
+
const start = src.cursor;
|
|
32
|
+
const ans = src.readSpace();
|
|
33
|
+
if (ans !== ' ') {
|
|
34
|
+
ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('mcfunction.parser.sep', (0, locales_1.localeQuote)(' '))), core.Range.create(start, src));
|
|
35
|
+
}
|
|
36
|
+
return ans;
|
|
37
|
+
};
|
|
38
|
+
exports.sep = sep;
|
|
39
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
import type { McfunctionNode } from '../node';
|
|
3
|
+
import type { ArgumentParserGetter } from './argument';
|
|
4
|
+
/**
|
|
5
|
+
* @throws When there's no command tree associated with `commandTreeName`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function entry(commandTreeName: string, argument: ArgumentParserGetter): core.Parser<McfunctionNode>;
|
|
8
|
+
//# sourceMappingURL=entry.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.entry = void 0;
|
|
23
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
24
|
+
const tree_1 = require("../tree");
|
|
25
|
+
const command_1 = require("./command");
|
|
26
|
+
/**
|
|
27
|
+
* @throws When there's no command tree associated with `commandTreeName`.
|
|
28
|
+
*/
|
|
29
|
+
function entry(commandTreeName, argument) {
|
|
30
|
+
return (src, ctx) => {
|
|
31
|
+
const ans = {
|
|
32
|
+
type: 'mcfunction:entry',
|
|
33
|
+
range: core.Range.create(src),
|
|
34
|
+
children: [],
|
|
35
|
+
};
|
|
36
|
+
while (src.skipWhitespace().canReadInLine()) {
|
|
37
|
+
let result;
|
|
38
|
+
if (src.peek() === '#') {
|
|
39
|
+
result = comment(src, ctx);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result = (0, command_1.command)(tree_1.CommandTreeRegistry.instance.get(commandTreeName), argument)(src, ctx);
|
|
43
|
+
}
|
|
44
|
+
ans.children.push(result);
|
|
45
|
+
src.nextLine();
|
|
46
|
+
}
|
|
47
|
+
ans.range.end = src.cursor;
|
|
48
|
+
return ans;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
exports.entry = entry;
|
|
52
|
+
const comment = core.comment({
|
|
53
|
+
singleLinePrefixes: new Set(['#']),
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./argument"), exports);
|
|
14
|
+
__exportStar(require("./command"), exports);
|
|
15
|
+
__exportStar(require("./common"), exports);
|
|
16
|
+
__exportStar(require("./entry"), exports);
|
|
17
|
+
__exportStar(require("./literal"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.literal = void 0;
|
|
23
|
+
const core = __importStar(require("@spyglassmc/core"));
|
|
24
|
+
const locales_1 = require("@spyglassmc/locales");
|
|
25
|
+
function literal(names, isRoot = false) {
|
|
26
|
+
const options = {
|
|
27
|
+
pool: names,
|
|
28
|
+
colorTokenType: isRoot ? 'keyword' : 'literal',
|
|
29
|
+
};
|
|
30
|
+
return (src, ctx) => {
|
|
31
|
+
const start = src.cursor;
|
|
32
|
+
const value = src.readUntil(' ', '\r', '\n');
|
|
33
|
+
if (!value.length) {
|
|
34
|
+
return core.Failure;
|
|
35
|
+
}
|
|
36
|
+
const ans = {
|
|
37
|
+
type: 'mcfunction:command_child/literal',
|
|
38
|
+
range: core.Range.create(start, src),
|
|
39
|
+
options,
|
|
40
|
+
value,
|
|
41
|
+
};
|
|
42
|
+
if (!names.includes(value)) {
|
|
43
|
+
ctx.err.report((0, locales_1.localize)('expected', names), ans);
|
|
44
|
+
}
|
|
45
|
+
return ans;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
exports.literal = literal;
|
|
49
|
+
//# sourceMappingURL=literal.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./registry"), exports);
|
|
14
|
+
__exportStar(require("./type"), exports);
|
|
15
|
+
__exportStar(require("./util"), exports);
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PartialRootTreeNode, RootTreeNode } from './type';
|
|
2
|
+
/**
|
|
3
|
+
* The registry for mcfunction command trees.
|
|
4
|
+
* This is a singleton; use the `instance` static property to get an instance.
|
|
5
|
+
*/
|
|
6
|
+
export declare class CommandTreeRegistry {
|
|
7
|
+
#private;
|
|
8
|
+
/**
|
|
9
|
+
* Register command tree for an arbitrary version.
|
|
10
|
+
*
|
|
11
|
+
* @param version The game version. e.g. `1.15-tdn`.
|
|
12
|
+
* @param tree The command tree for this version.
|
|
13
|
+
* @param treePatch A custom command tree patch that will be merged onto `tree`.
|
|
14
|
+
*/
|
|
15
|
+
register(version: string, tree: RootTreeNode, treePatch?: PartialRootTreeNode): void;
|
|
16
|
+
/**
|
|
17
|
+
* @throws When there's no command tree associated with the version.
|
|
18
|
+
*/
|
|
19
|
+
get(version: string): RootTreeNode;
|
|
20
|
+
/**
|
|
21
|
+
* An instance of `CommandTreeRegistry`.
|
|
22
|
+
*/
|
|
23
|
+
static get instance(): CommandTreeRegistry;
|
|
24
|
+
private constructor();
|
|
25
|
+
private static _instance;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var _CommandTreeRegistry_trees;
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CommandTreeRegistry = void 0;
|
|
10
|
+
const core_1 = require("@spyglassmc/core");
|
|
11
|
+
/* istanbul ignore next */
|
|
12
|
+
/**
|
|
13
|
+
* The registry for mcfunction command trees.
|
|
14
|
+
* This is a singleton; use the `instance` static property to get an instance.
|
|
15
|
+
*/
|
|
16
|
+
class CommandTreeRegistry {
|
|
17
|
+
constructor() {
|
|
18
|
+
_CommandTreeRegistry_trees.set(this, new Map()
|
|
19
|
+
/**
|
|
20
|
+
* Register command tree for an arbitrary version.
|
|
21
|
+
*
|
|
22
|
+
* @param version The game version. e.g. `1.15-tdn`.
|
|
23
|
+
* @param tree The command tree for this version.
|
|
24
|
+
* @param treePatch A custom command tree patch that will be merged onto `tree`.
|
|
25
|
+
*/
|
|
26
|
+
);
|
|
27
|
+
if (CommandTreeRegistry._instance) {
|
|
28
|
+
throw new Error('Use the `instance` static property to get an instance.');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Register command tree for an arbitrary version.
|
|
33
|
+
*
|
|
34
|
+
* @param version The game version. e.g. `1.15-tdn`.
|
|
35
|
+
* @param tree The command tree for this version.
|
|
36
|
+
* @param treePatch A custom command tree patch that will be merged onto `tree`.
|
|
37
|
+
*/
|
|
38
|
+
register(version, tree, treePatch) {
|
|
39
|
+
__classPrivateFieldGet(this, _CommandTreeRegistry_trees, "f").set(version, treePatch ? (0, core_1.merge)(tree, treePatch) : tree);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @throws When there's no command tree associated with the version.
|
|
43
|
+
*/
|
|
44
|
+
get(version) {
|
|
45
|
+
const ans = __classPrivateFieldGet(this, _CommandTreeRegistry_trees, "f").get(version);
|
|
46
|
+
if (!ans) {
|
|
47
|
+
throw new Error(`No command tree exist for version “${version}”`);
|
|
48
|
+
}
|
|
49
|
+
return ans;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* An instance of `CommandTreeRegistry`.
|
|
53
|
+
*/
|
|
54
|
+
static get instance() {
|
|
55
|
+
return this._instance ?? (this._instance = new CommandTreeRegistry());
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.CommandTreeRegistry = CommandTreeRegistry;
|
|
59
|
+
_CommandTreeRegistry_trees = new WeakMap();
|
|
60
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface BaseTreeNode {
|
|
2
|
+
type: string;
|
|
3
|
+
children?: {
|
|
4
|
+
[name: string]: TreeNode;
|
|
5
|
+
};
|
|
6
|
+
executable?: boolean;
|
|
7
|
+
redirect?: readonly string[];
|
|
8
|
+
/**
|
|
9
|
+
* The permission level required to use this node.
|
|
10
|
+
* @default 2
|
|
11
|
+
*/
|
|
12
|
+
permission?: 0 | 1 | 2 | 3 | 4;
|
|
13
|
+
}
|
|
14
|
+
export interface ArgumentTreeNode extends BaseTreeNode {
|
|
15
|
+
type: 'argument';
|
|
16
|
+
parser: string;
|
|
17
|
+
properties?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export interface LiteralTreeNode extends BaseTreeNode {
|
|
20
|
+
type: 'literal';
|
|
21
|
+
}
|
|
22
|
+
export interface RootTreeNode extends BaseTreeNode {
|
|
23
|
+
type: 'root';
|
|
24
|
+
}
|
|
25
|
+
export declare type TreeNode = ArgumentTreeNode | LiteralTreeNode | RootTreeNode;
|
|
26
|
+
declare type RecursivePartial<T> = T extends object ? {
|
|
27
|
+
[K in keyof T]?: RecursivePartial<T[K]>;
|
|
28
|
+
} : T;
|
|
29
|
+
export declare type PartialTreeNode = RecursivePartial<TreeNode>;
|
|
30
|
+
export declare type PartialRootTreeNode = RecursivePartial<RootTreeNode>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=type.d.ts.map
|
package/lib/tree/type.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ArgumentTreeNode, LiteralTreeNode, RootTreeNode, TreeNode } from './type';
|
|
2
|
+
export declare function redirect(rootTreeNode: TreeNode, path: readonly string[]): TreeNode | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* @returns A `TreeNode` whose `children` property, if exists, contains its subsequent `TreeNode`s.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveParentTreeNode(parentTreeNode: TreeNode | undefined, rootTreeNode: RootTreeNode): {
|
|
7
|
+
treeNode: TreeNode | undefined;
|
|
8
|
+
path: undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare function resolveParentTreeNode(parentTreeNode: TreeNode | undefined, rootTreeNode: RootTreeNode, parentPath: string[]): {
|
|
11
|
+
treeNode: TreeNode | undefined;
|
|
12
|
+
path: string[];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Categorize command tree children to literal entries and argument entries.
|
|
16
|
+
*/
|
|
17
|
+
export declare function categorizeTreeChildren(children: Exclude<TreeNode['children'], undefined>): {
|
|
18
|
+
literalTreeNodes: [string, LiteralTreeNode][];
|
|
19
|
+
argumentTreeNodes: [string, ArgumentTreeNode][];
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=util.d.ts.map
|
package/lib/tree/util.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.categorizeTreeChildren = exports.resolveParentTreeNode = exports.redirect = void 0;
|
|
4
|
+
function redirect(rootTreeNode, path) {
|
|
5
|
+
return path.reduce((p, c) => p?.children?.[c], rootTreeNode);
|
|
6
|
+
}
|
|
7
|
+
exports.redirect = redirect;
|
|
8
|
+
function resolveParentTreeNode(parentTreeNode, rootTreeNode, parentPath) {
|
|
9
|
+
if (parentTreeNode?.redirect) {
|
|
10
|
+
return { treeNode: redirect(rootTreeNode, parentTreeNode.redirect), path: [...parentTreeNode.redirect] };
|
|
11
|
+
}
|
|
12
|
+
else if (parentTreeNode && !parentTreeNode.children && !parentTreeNode.executable) {
|
|
13
|
+
// The `execute.run` literal tree node doesn't have any property.
|
|
14
|
+
// We should use children from the root tree node in this case.
|
|
15
|
+
return { treeNode: rootTreeNode, path: [] };
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return { treeNode: parentTreeNode, path: parentPath };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.resolveParentTreeNode = resolveParentTreeNode;
|
|
22
|
+
/**
|
|
23
|
+
* Categorize command tree children to literal entries and argument entries.
|
|
24
|
+
*/
|
|
25
|
+
function categorizeTreeChildren(children) {
|
|
26
|
+
const ans = {
|
|
27
|
+
literalTreeNodes: [],
|
|
28
|
+
argumentTreeNodes: [],
|
|
29
|
+
};
|
|
30
|
+
for (const e of Object.entries(children)) {
|
|
31
|
+
/* istanbul ignore else */
|
|
32
|
+
if (e[1].type === 'literal') {
|
|
33
|
+
ans.literalTreeNodes.push(e);
|
|
34
|
+
}
|
|
35
|
+
else if (e[1].type === 'argument') {
|
|
36
|
+
ans.argumentTreeNodes.push(e);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return ans;
|
|
40
|
+
}
|
|
41
|
+
exports.categorizeTreeChildren = categorizeTreeChildren;
|
|
42
|
+
//# sourceMappingURL=util.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spyglassmc/mcfunction",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "lib/index.js",
|
|
5
|
+
"types": "lib/index.d.ts",
|
|
6
|
+
"author": "SPGoding",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"directories": {
|
|
9
|
+
"test": "test/"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"release": "npm publish",
|
|
13
|
+
"release:dry": "npm publish --dry-run"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/SpyglassMC/Spyglass.git"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://spyglassmc.com",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/SpyglassMC/Spyglass/issues"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@spyglassmc/core": "0.1.0",
|
|
28
|
+
"@spyglassmc/locales": "0.1.0"
|
|
29
|
+
}
|
|
30
|
+
}
|