redscript-mc 1.2.15 → 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;
@@ -704,6 +704,7 @@ class Lowering {
704
704
  this.lowerExecuteStmt(stmt);
705
705
  break;
706
706
  case 'raw':
707
+ this.checkRawCommandInterpolation(stmt.cmd, stmt.span);
707
708
  this.builder.emitRaw(stmt.cmd);
708
709
  break;
709
710
  }
@@ -2830,6 +2831,39 @@ class Lowering {
2830
2831
  }
2831
2832
  return undefined;
2832
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
+ }
2833
2867
  resolveInstanceMethod(expr) {
2834
2868
  const receiver = expr.args[0];
2835
2869
  if (!receiver) {