redscript-mc 1.2.14 → 1.2.16

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/dist/cli.js CHANGED
@@ -48,6 +48,7 @@ const cmdblock_1 = require("./codegen/cmdblock");
48
48
  const structure_1 = require("./codegen/structure");
49
49
  const diagnostics_1 = require("./diagnostics");
50
50
  const repl_1 = require("./repl");
51
+ const metadata_1 = require("./builtins/metadata");
51
52
  const fs = __importStar(require("fs"));
52
53
  const path = __importStar(require("path"));
53
54
  // Parse command line arguments
@@ -61,16 +62,18 @@ Usage:
61
62
  redscript watch <dir> [-o <outdir>] [--namespace <ns>] [--hot-reload <url>]
62
63
  redscript check <file>
63
64
  redscript fmt <file.mcrs> [file2.mcrs ...]
65
+ redscript generate-dts [-o <file>]
64
66
  redscript repl
65
67
  redscript version
66
68
 
67
69
  Commands:
68
- compile Compile a RedScript file to a Minecraft datapack
69
- watch Watch a directory for .mcrs file changes, recompile, and hot reload
70
- check Check a RedScript file for errors without generating output
71
- fmt Auto-format RedScript source files
72
- repl Start an interactive RedScript REPL
73
- version Print the RedScript version
70
+ compile Compile a RedScript file to a Minecraft datapack
71
+ watch Watch a directory for .mcrs file changes, recompile, and hot reload
72
+ check Check a RedScript file for errors without generating output
73
+ fmt Auto-format RedScript source files
74
+ generate-dts Generate builtin function declaration file (builtins.d.mcrs)
75
+ repl Start an interactive RedScript REPL
76
+ version Print the RedScript version
74
77
 
75
78
  Options:
76
79
  -o, --output <path> Output directory or file path, depending on target
@@ -414,6 +417,13 @@ async function main() {
414
417
  }
415
418
  break;
416
419
  }
420
+ case 'generate-dts': {
421
+ const output = parsed.output ?? 'builtins.d.mcrs';
422
+ const dtsContent = (0, metadata_1.generateDts)();
423
+ fs.writeFileSync(output, dtsContent, 'utf-8');
424
+ console.log(`Generated ${output}`);
425
+ break;
426
+ }
417
427
  case 'repl':
418
428
  await (0, repl_1.startRepl)(parsed.namespace ?? 'repl');
419
429
  break;
@@ -151,6 +151,17 @@ export declare class Lowering {
151
151
  private getArrayStorageName;
152
152
  private inferLambdaReturnType;
153
153
  private inferExprType;
154
+ /**
155
+ * Checks a raw() command string for `${...}` interpolation containing runtime variables.
156
+ * - If the interpolated expression is a numeric literal → OK (MC macro syntax).
157
+ * - If the interpolated name is a compile-time constant (in constValues) → OK.
158
+ * - If the interpolated name is a known runtime variable (in varMap) → DiagnosticError.
159
+ * - Unknown names → OK (could be MC macro params or external constants).
160
+ *
161
+ * This catches the common mistake of writing raw("say ${score}") expecting interpolation,
162
+ * which would silently emit a literal `${score}` in the MC command.
163
+ */
164
+ private checkRawCommandInterpolation;
154
165
  private resolveInstanceMethod;
155
166
  private normalizeType;
156
167
  private readArrayElement;
@@ -50,10 +50,8 @@ const types_1 = require("../events/types");
50
50
  // as literal values (coordinates, entity types, block types), so they
51
51
  // require MC macro syntax when called with runtime variables.
52
52
  // ---------------------------------------------------------------------------
53
- const MACRO_AWARE_BUILTINS = new Set([
54
- 'summon', 'particle', 'setblock', 'fill', 'clone',
55
- 'playsound', 'tp', 'tp_to', 'effect', 'effect_clear', 'give',
56
- ]);
53
+ // All builtins support macro parameters - any arg that's a function param
54
+ // will automatically use MC 1.20.2+ macro syntax when needed
57
55
  // ---------------------------------------------------------------------------
58
56
  // Builtin Functions
59
57
  // ---------------------------------------------------------------------------
@@ -313,7 +311,7 @@ class Lowering {
313
311
  }
314
312
  }
315
313
  preScanExpr(expr, paramNames, macroParams) {
316
- if (expr.kind === 'call' && MACRO_AWARE_BUILTINS.has(expr.fn)) {
314
+ if (expr.kind === 'call' && BUILTINS[expr.fn] !== undefined) {
317
315
  // All ident args to macro-aware builtins that are params → macro params
318
316
  for (const arg of expr.args) {
319
317
  if (arg.kind === 'ident' && paramNames.has(arg.name)) {
@@ -706,6 +704,7 @@ class Lowering {
706
704
  this.lowerExecuteStmt(stmt);
707
705
  break;
708
706
  case 'raw':
707
+ this.checkRawCommandInterpolation(stmt.cmd, stmt.span);
709
708
  this.builder.emitRaw(stmt.cmd);
710
709
  break;
711
710
  }
@@ -2197,28 +2196,17 @@ class Lowering {
2197
2196
  }
2198
2197
  return { kind: 'const', value: 0 };
2199
2198
  }
2200
- // For macro-aware builtins, check if any arg is a param needing macro treatment
2201
- if (MACRO_AWARE_BUILTINS.has(name)) {
2202
- const argResults = args.map(arg => this.exprToBuiltinArg(arg));
2203
- const hasMacroArg = argResults.some(r => r.macroParam !== undefined);
2204
- if (hasMacroArg) {
2205
- argResults.forEach(r => { if (r.macroParam)
2206
- this.currentFnMacroParams.add(r.macroParam); });
2207
- }
2208
- const strArgs = argResults.map(r => r.str);
2209
- const cmd = BUILTINS[name]?.(strArgs);
2210
- if (cmd) {
2211
- this.builder.emitRaw(hasMacroArg ? `$${cmd}` : cmd);
2212
- }
2213
- return { kind: 'const', value: 0 };
2199
+ // All builtins support macro params - check if any arg is a param needing macro treatment
2200
+ const argResults = args.map(arg => this.exprToBuiltinArg(arg));
2201
+ const hasMacroArg = argResults.some(r => r.macroParam !== undefined);
2202
+ if (hasMacroArg) {
2203
+ argResults.forEach(r => { if (r.macroParam)
2204
+ this.currentFnMacroParams.add(r.macroParam); });
2214
2205
  }
2215
- // Convert args to strings for builtin (use SNBT for struct/array literals)
2216
- const strArgs = args.map(arg => arg.kind === 'struct_lit' || arg.kind === 'array_lit'
2217
- ? this.exprToSnbt(arg)
2218
- : this.exprToString(arg));
2219
- const cmd = BUILTINS[name](strArgs);
2206
+ const strArgs = argResults.map(r => r.str);
2207
+ const cmd = BUILTINS[name]?.(strArgs);
2220
2208
  if (cmd) {
2221
- this.builder.emitRaw(cmd);
2209
+ this.builder.emitRaw(hasMacroArg ? `$${cmd}` : cmd);
2222
2210
  }
2223
2211
  return { kind: 'const', value: 0 };
2224
2212
  }
@@ -2843,6 +2831,39 @@ class Lowering {
2843
2831
  }
2844
2832
  return undefined;
2845
2833
  }
2834
+ /**
2835
+ * Checks a raw() command string for `${...}` interpolation containing runtime variables.
2836
+ * - If the interpolated expression is a numeric literal → OK (MC macro syntax).
2837
+ * - If the interpolated name is a compile-time constant (in constValues) → OK.
2838
+ * - If the interpolated name is a known runtime variable (in varMap) → DiagnosticError.
2839
+ * - Unknown names → OK (could be MC macro params or external constants).
2840
+ *
2841
+ * This catches the common mistake of writing raw("say ${score}") expecting interpolation,
2842
+ * which would silently emit a literal `${score}` in the MC command.
2843
+ */
2844
+ checkRawCommandInterpolation(cmd, span) {
2845
+ const interpRe = /\$\{([^}]+)\}/g;
2846
+ let match;
2847
+ while ((match = interpRe.exec(cmd)) !== null) {
2848
+ const name = match[1].trim();
2849
+ // Numeric/boolean literals are fine (intentional MC macro syntax)
2850
+ if (/^\d+(\.\d+)?$/.test(name) || name === 'true' || name === 'false') {
2851
+ continue;
2852
+ }
2853
+ // Compile-time constants are fine
2854
+ if (this.constValues.has(name)) {
2855
+ continue;
2856
+ }
2857
+ // Only error if it's a known runtime variable (in varMap or function params)
2858
+ // Unknown identifiers are left alone (could be MC macro params the user intends)
2859
+ if (this.varMap.has(name) || this.currentFnParamNames.has(name)) {
2860
+ const loc = span ?? { line: 1, col: 1 };
2861
+ throw new diagnostics_1.DiagnosticError('LoweringError', `raw() command contains runtime variable interpolation '\${${name}}'. ` +
2862
+ `Variables cannot be interpolated into raw commands at compile time. ` +
2863
+ `Use f-string messages (say/tell/announce) or MC macro syntax '$(${name})' for MC 1.20.2+ commands.`, loc);
2864
+ }
2865
+ }
2866
+ }
2846
2867
  resolveInstanceMethod(expr) {
2847
2868
  const receiver = expr.args[0];
2848
2869
  if (!receiver) {