@spyglassmc/mcfunction 0.2.33 → 0.2.34

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.
@@ -1,9 +1,11 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  export const macro = (node, ctx) => {
3
3
  const tokens = [];
4
- tokens.push(core.ColorToken.create(core.Range.create(node.range.start, node.range.start + 1), 'literal')); // Dollar Sign
5
4
  for (const child of node.children) {
6
- if (child.type === 'mcfunction:macro/other') {
5
+ if (child.type === 'mcfunction:macro/prefix') {
6
+ tokens.push(core.ColorToken.create(child.range, 'literal'));
7
+ }
8
+ else if (child.type === 'mcfunction:macro/other') {
7
9
  tokens.push(core.ColorToken.create(child.range, 'string'));
8
10
  }
9
11
  else {
@@ -1,5 +1,5 @@
1
1
  import * as core from '@spyglassmc/core';
2
- import { CommandNode, MacroNode } from '../node/index.js';
2
+ import { CommandNode } from '../node/index.js';
3
3
  import { categorizeTreeChildren, redirect, resolveParentTreeNode } from '../tree/index.js';
4
4
  /**
5
5
  * @param getMockNodes A function that returns a mock AST Node from given {@link ArgumentTreeNode}. These mock nodes
@@ -8,11 +8,11 @@ import { categorizeTreeChildren, redirect, resolveParentTreeNode } from '../tree
8
8
  export function entry(tree, getMockNodes) {
9
9
  return (node, ctx) => {
10
10
  const childNode = core.AstNode.findChild(node, ctx.offset, true);
11
- if (core.CommentNode.is(childNode) || MacroNode.is(childNode)) {
12
- return [];
11
+ if (CommandNode.is(childNode)) {
12
+ return command(tree, getMockNodes)(childNode ?? CommandNode.mock(ctx.offset), ctx);
13
13
  }
14
14
  else {
15
- return command(tree, getMockNodes)(childNode ?? CommandNode.mock(ctx.offset), ctx);
15
+ return [];
16
16
  }
17
17
  };
18
18
  }
@@ -1,7 +1,7 @@
1
1
  import type * as core from '@spyglassmc/core';
2
2
  import type { CommandNode } from './command.js';
3
3
  import type { MacroNode } from './macro.js';
4
- export interface McfunctionNode extends core.SequenceNode<CommandNode | MacroNode | core.CommentNode> {
4
+ export interface McfunctionNode extends core.SequenceNode<CommandNode | MacroNode | core.CommentNode | core.ErrorNode> {
5
5
  type: 'mcfunction:entry';
6
6
  }
7
7
  export declare namespace McfunctionNode {
@@ -1,12 +1,15 @@
1
1
  import * as core from '@spyglassmc/core';
2
- export interface MacroNode extends core.SequenceNode<MacroOtherNode | MacroArgumentNode> {
2
+ export interface MacroNode extends core.SequenceNode<MacroPrefixNode | MacroOtherNode | MacroArgumentNode> {
3
3
  type: 'mcfunction:macro';
4
- children: (MacroOtherNode | MacroArgumentNode)[];
4
+ children: (MacroPrefixNode | MacroOtherNode | MacroArgumentNode)[];
5
5
  }
6
6
  export declare namespace MacroNode {
7
7
  function is<T extends core.DeepReadonly<core.AstNode> | undefined>(obj: T): obj is core.InheritReadonly<MacroNode, T>;
8
8
  function mock(range: core.RangeLike): MacroNode;
9
9
  }
10
+ export interface MacroPrefixNode extends core.AstNode {
11
+ type: 'mcfunction:macro/prefix';
12
+ }
10
13
  export interface MacroOtherNode extends core.AstNode {
11
14
  type: 'mcfunction:macro/other';
12
15
  value?: string;
@@ -1,4 +1,5 @@
1
1
  import * as core from '@spyglassmc/core';
2
+ import { localize } from '@spyglassmc/locales';
2
3
  import { command } from './command.js';
3
4
  import { macro } from './macro.js';
4
5
  function mcfunction(commandTree, argument, options) {
@@ -14,7 +15,19 @@ function mcfunction(commandTree, argument, options) {
14
15
  result = comment(src, ctx);
15
16
  }
16
17
  else if (src.peek() === '$') {
17
- result = macro(options.macros ?? false)(src, ctx);
18
+ const start = src.cursor;
19
+ if (options.macros) {
20
+ result = macro()(src, ctx);
21
+ }
22
+ else {
23
+ src.skipLine();
24
+ ans.range.end = src.cursor;
25
+ result = {
26
+ type: 'error',
27
+ range: core.Range.create(start, src),
28
+ };
29
+ ctx.err.report(localize('mcfunction.parser.macro.disallowed'), result);
30
+ }
18
31
  }
19
32
  else {
20
33
  result = command(commandTree, argument, options.commandOptions)(src, ctx);
@@ -2,8 +2,7 @@ import * as core from '@spyglassmc/core';
2
2
  import type { MacroNode } from '../node/index.js';
3
3
  /**
4
4
  * Parse a macro line.
5
- * @param supportsMacros When false, reports the entire line as an error (due to
6
- * the Minecraft version not supporting macros).
5
+ * @param hasPrefix When false, don't look for a starting '$'.
7
6
  */
8
- export declare function macro(supportsMacros?: boolean): core.Parser<MacroNode | core.ErrorNode>;
7
+ export declare function macro(hasPrefix?: boolean): core.InfallibleParser<MacroNode>;
9
8
  //# sourceMappingURL=macro.d.ts.map
@@ -2,26 +2,30 @@ import * as core from '@spyglassmc/core';
2
2
  import { localeQuote, localize } from '@spyglassmc/locales';
3
3
  /**
4
4
  * Parse a macro line.
5
- * @param supportsMacros When false, reports the entire line as an error (due to
6
- * the Minecraft version not supporting macros).
5
+ * @param hasPrefix When false, don't look for a starting '$'.
7
6
  */
8
- export function macro(supportsMacros = true) {
7
+ export function macro(hasPrefix = true) {
9
8
  return (src, ctx) => {
10
9
  const ans = {
11
10
  type: 'mcfunction:macro',
12
11
  range: core.Range.create(src.cursor),
13
12
  children: [],
14
13
  };
15
- if (!supportsMacros) {
16
- src.skipLine();
17
- ans.range.end = src.cursor;
18
- ctx.err.report(localize('mcfunction.parser.macro.disallowed'), ans.range);
19
- return { ...ans, type: 'error' };
20
- }
21
- // Skip the starting '$'
22
- src.skip();
23
14
  let start = src.cursor;
24
15
  let hasMacroArgs = false;
16
+ if (hasPrefix) {
17
+ // Skip the starting '$'
18
+ if (src.trySkip('$')) {
19
+ ans.children.push({
20
+ type: 'mcfunction:macro/prefix',
21
+ range: core.Range.create(start, src),
22
+ });
23
+ start = src.cursor;
24
+ }
25
+ else {
26
+ ctx.err.report(localize('expected', localeQuote('$')), ans);
27
+ }
28
+ }
25
29
  while (src.canReadInLine()) {
26
30
  src.skipUntilOrEnd(core.LF, core.CR, '$');
27
31
  if (src.peek(2) === '$(') {
@@ -31,7 +35,7 @@ export function macro(supportsMacros = true) {
31
35
  if (other.length > 0) {
32
36
  ans.children.push({
33
37
  type: 'mcfunction:macro/other',
34
- range: core.Range.create(start, src.cursor),
38
+ range: core.Range.create(start, src),
35
39
  value: other,
36
40
  });
37
41
  start = src.cursor;
@@ -53,7 +57,7 @@ export function macro(supportsMacros = true) {
53
57
  // No more macro arguments, add the remaining other stuff
54
58
  ans.children.push({
55
59
  type: 'mcfunction:macro/other',
56
- range: core.Range.create(start, src.cursor),
60
+ range: core.Range.create(start, src),
57
61
  value: src.sliceToCursor(start),
58
62
  });
59
63
  }
@@ -61,7 +65,7 @@ export function macro(supportsMacros = true) {
61
65
  }
62
66
  // A line with no macro arguments is invalid
63
67
  if (!hasMacroArgs) {
64
- ctx.err.report(localize('expected', localize('mcfunction.parser.macro.at-least-one')), core.Range.create(start, src.cursor));
68
+ ctx.err.report(localize('expected', localize('mcfunction.parser.macro.at-least-one')), core.Range.create(start, src));
65
69
  }
66
70
  ans.range.end = src.cursor;
67
71
  return ans;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/mcfunction",
3
- "version": "0.2.33",
3
+ "version": "0.2.34",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",