@barefootjs/mojolicious 0.18.3 → 0.18.4

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 +1 @@
1
- {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,YAAY,EAMlB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AA+CzD,qBAAa,iBAAkB,YAAW,iBAAiB;IAEvD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAI5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAK7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IAXjC,YACmB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAIhC,YAAY,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAqB,EAKlD,aAAa,CAAC,GAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,aAAA,EACzE;IAEJ,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/B;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,CAKjF;IAED,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAYxG;IAED,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAE1F;IAED,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAMpF;IAED,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAS/E;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAmB/F;IAED,OAAO,CAAC,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAM5G;IAED,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,EAC7C,SAAS,EAAE,UAAU,EAAE,EACvB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAgCR;IAED,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAQ5E;IAED,WAAW,CACT,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAMR;IAED,UAAU,CACR,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,SAAS,GAAG;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAEtF;IAED,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAE9C;IAED,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAKpF;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1B;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;IAED,aAAa,CAAC,WAAW,EAAE,qBAAqB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAM1G;CACF;AAED;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,iBAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAhC,YAA6B,GAAG,EAAE,eAAe,EAAI;IAErD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe/B;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,CAKjF;IAED,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAkBxG;IAED,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAE1F;IAED,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CA4CpF;IAED,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAK/E;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAqB/F;IAED,OAAO,CAAC,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAM5G;IAED,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,EAC7C,QAAQ,EAAE,UAAU,EAAE,EACtB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAqER;IAED,OAAO,CAAC,eAAe;IAiDvB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAO5E;IAED,WAAW,CACT,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,UAAU,CACR,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,SAAS,GAAG;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,WAAW,CACT,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,UAAU,EACrB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAER;IAED,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CA6B9E;IAED,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAOpF;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK1B;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOjD;IAED,aAAa,CAAC,UAAU,EAAE,qBAAqB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,CAWzG;CACF"}
1
+ {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,17 @@
1
1
  /**
2
- * Operand-type classification + index-access lowering for the Mojolicious
3
- * EP template adapter.
2
+ * Index-access lowering for the Mojolicious EP template adapter.
4
3
  *
5
4
  * Extracted from `mojo-adapter.ts` (domain-module refactor, issue #2018
6
- * track D). Pure functions over `ParsedExpr` — they take an `isStringName`
5
+ * track D). Pure function over `ParsedExpr` — it takes an `isStringName`
7
6
  * predicate (supplied by the emitter from adapter state) rather than reading
8
7
  * adapter instance state directly.
9
8
  *
10
- * SHARED CANDIDATE: `isStringTypedOperand` is byte-identical to the Xslate
11
- * adapter's copy and is adapter-agnostic an extraction candidate for a
12
- * shared Perl-family codegen module (groundwork for the future Perl evaluator
13
- * integration, issue #2018 track D). `emitIndexAccessPerl` stays Mojo-specific
9
+ * The string-typed-operand classifier that used to live here (marked
10
+ * SHARED CANDIDATE) was promoted to `@barefootjs/jsx` as
11
+ * `isStringTypedOperand` (#2176); `emitIndexAccessPerl` stays Mojo-specific
14
12
  * (Perl's `->[]` vs `->{}` split has no Kolon equivalent).
15
13
  */
16
- import type { ParsedExpr } from '@barefootjs/jsx';
17
- /**
18
- * Whether a comparison operand is string-typed, so JS `===`/`!==` against it
19
- * must lower to Perl `eq`/`ne` instead of numeric `==`/`!=` (#1672). Covers a
20
- * string literal, a string-signal getter call (`sel()`), and a string prop
21
- * access (`props.x`). `isStringName` reports whether a getter/prop name is
22
- * known-string. Loop-element fields (`t.id`) on untyped arrays have no known
23
- * type and stay undetected — a separate, narrower gap.
24
- */
25
- export declare function isStringTypedOperand(expr: ParsedExpr, isStringName: (n: string) => boolean): boolean;
14
+ import { type ParsedExpr } from '@barefootjs/jsx';
26
15
  /**
27
16
  * Lower `arr[index]` to a Perl deref. Perl distinguishes array
28
17
  * (`->[$i]`) from hash (`->{$k}`) access, which JS's single `[]` does
@@ -1 +1 @@
1
- {"version":3,"file":"operand.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/operand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CASpG;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GACnC,MAAM,CAKR"}
1
+ {"version":3,"file":"operand.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/operand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEvE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GACnC,MAAM,CAKR"}
@@ -325,6 +325,9 @@ function renderFlatMethod(recv, depth, emit) {
325
325
 
326
326
  // src/adapter/expr/emitters.ts
327
327
  import {
328
+ groupBinaryOperand,
329
+ isStringTypedOperand as isStringTypedOperand2,
330
+ isStringConcatBinary,
328
331
  emitParsedExpr,
329
332
  identifierPath,
330
333
  matchSearchParamsMethodCall,
@@ -333,17 +336,7 @@ import {
333
336
  } from "@barefootjs/jsx";
334
337
 
335
338
  // src/adapter/expr/operand.ts
336
- function isStringTypedOperand(expr, isStringName) {
337
- if (expr.kind === "literal" && expr.literalType === "string")
338
- return true;
339
- if (expr.kind === "call" && expr.callee.kind === "identifier" && expr.args.length === 0) {
340
- return isStringName(expr.callee.name);
341
- }
342
- if (expr.kind === "member" && expr.object.kind === "identifier" && expr.object.name === "props") {
343
- return isStringName(expr.property);
344
- }
345
- return false;
346
- }
339
+ import { isStringTypedOperand } from "@barefootjs/jsx";
347
340
  function emitIndexAccessPerl(object, index, emit, isStringName) {
348
341
  const i = emit(index);
349
342
  return isStringTypedOperand(index, isStringName) ? `${emit(object)}->{${i}}` : `${emit(object)}->[${i}]`;
@@ -414,9 +407,9 @@ class MojoFilterEmitter {
414
407
  return arg;
415
408
  }
416
409
  binary(op, left, right, emit) {
417
- const l = emit(left);
418
- const r = emit(right);
419
- const isStr = (e) => isStringTypedOperand(e, this.isStringName);
410
+ const l = groupBinaryOperand(left, emit(left));
411
+ const r = groupBinaryOperand(right, emit(right));
412
+ const isStr = (e) => isStringTypedOperand2(e, this.isStringName);
420
413
  const stringCmp = isStr(left) || isStr(right);
421
414
  if ((op === "===" || op === "==") && stringCmp) {
422
415
  return `${l} eq ${r}`;
@@ -424,6 +417,9 @@ class MojoFilterEmitter {
424
417
  if ((op === "!==" || op === "!=") && stringCmp) {
425
418
  return `${l} ne ${r}`;
426
419
  }
420
+ if (isStringConcatBinary(op, left, right, this.isStringName)) {
421
+ return `${l} . ${r}`;
422
+ }
427
423
  const opMap = {
428
424
  "===": "==",
429
425
  "!==": "!=",
@@ -567,9 +563,9 @@ class MojoTopLevelEmitter {
567
563
  return arg;
568
564
  }
569
565
  binary(op, left, right, emit) {
570
- const l = emit(left);
571
- const r = emit(right);
572
- const isStr = (e) => isStringTypedOperand(e, (n) => this.ctx._isStringValueName(n));
566
+ const l = groupBinaryOperand(left, emit(left));
567
+ const r = groupBinaryOperand(right, emit(right));
568
+ const isStr = (e) => isStringTypedOperand2(e, (n) => this.ctx._isStringValueName(n));
573
569
  const stringCmp = isStr(left) || isStr(right);
574
570
  if ((op === "===" || op === "==") && stringCmp) {
575
571
  return `${l} eq ${r}`;
@@ -577,6 +573,9 @@ class MojoTopLevelEmitter {
577
573
  if ((op === "!==" || op === "!=") && stringCmp) {
578
574
  return `${l} ne ${r}`;
579
575
  }
576
+ if (isStringConcatBinary(op, left, right, (n) => this.ctx._isStringValueName(n))) {
577
+ return `${l} . ${r}`;
578
+ }
580
579
  const opMap = {
581
580
  "===": "==",
582
581
  "!==": "!=",
package/dist/build.js CHANGED
@@ -325,6 +325,9 @@ function renderFlatMethod(recv, depth, emit) {
325
325
 
326
326
  // src/adapter/expr/emitters.ts
327
327
  import {
328
+ groupBinaryOperand,
329
+ isStringTypedOperand as isStringTypedOperand2,
330
+ isStringConcatBinary,
328
331
  emitParsedExpr,
329
332
  identifierPath,
330
333
  matchSearchParamsMethodCall,
@@ -333,17 +336,7 @@ import {
333
336
  } from "@barefootjs/jsx";
334
337
 
335
338
  // src/adapter/expr/operand.ts
336
- function isStringTypedOperand(expr, isStringName) {
337
- if (expr.kind === "literal" && expr.literalType === "string")
338
- return true;
339
- if (expr.kind === "call" && expr.callee.kind === "identifier" && expr.args.length === 0) {
340
- return isStringName(expr.callee.name);
341
- }
342
- if (expr.kind === "member" && expr.object.kind === "identifier" && expr.object.name === "props") {
343
- return isStringName(expr.property);
344
- }
345
- return false;
346
- }
339
+ import { isStringTypedOperand } from "@barefootjs/jsx";
347
340
  function emitIndexAccessPerl(object, index, emit, isStringName) {
348
341
  const i = emit(index);
349
342
  return isStringTypedOperand(index, isStringName) ? `${emit(object)}->{${i}}` : `${emit(object)}->[${i}]`;
@@ -414,9 +407,9 @@ class MojoFilterEmitter {
414
407
  return arg;
415
408
  }
416
409
  binary(op, left, right, emit) {
417
- const l = emit(left);
418
- const r = emit(right);
419
- const isStr = (e) => isStringTypedOperand(e, this.isStringName);
410
+ const l = groupBinaryOperand(left, emit(left));
411
+ const r = groupBinaryOperand(right, emit(right));
412
+ const isStr = (e) => isStringTypedOperand2(e, this.isStringName);
420
413
  const stringCmp = isStr(left) || isStr(right);
421
414
  if ((op === "===" || op === "==") && stringCmp) {
422
415
  return `${l} eq ${r}`;
@@ -424,6 +417,9 @@ class MojoFilterEmitter {
424
417
  if ((op === "!==" || op === "!=") && stringCmp) {
425
418
  return `${l} ne ${r}`;
426
419
  }
420
+ if (isStringConcatBinary(op, left, right, this.isStringName)) {
421
+ return `${l} . ${r}`;
422
+ }
427
423
  const opMap = {
428
424
  "===": "==",
429
425
  "!==": "!=",
@@ -567,9 +563,9 @@ class MojoTopLevelEmitter {
567
563
  return arg;
568
564
  }
569
565
  binary(op, left, right, emit) {
570
- const l = emit(left);
571
- const r = emit(right);
572
- const isStr = (e) => isStringTypedOperand(e, (n) => this.ctx._isStringValueName(n));
566
+ const l = groupBinaryOperand(left, emit(left));
567
+ const r = groupBinaryOperand(right, emit(right));
568
+ const isStr = (e) => isStringTypedOperand2(e, (n) => this.ctx._isStringValueName(n));
573
569
  const stringCmp = isStr(left) || isStr(right);
574
570
  if ((op === "===" || op === "==") && stringCmp) {
575
571
  return `${l} eq ${r}`;
@@ -577,6 +573,9 @@ class MojoTopLevelEmitter {
577
573
  if ((op === "!==" || op === "!=") && stringCmp) {
578
574
  return `${l} ne ${r}`;
579
575
  }
576
+ if (isStringConcatBinary(op, left, right, (n) => this.ctx._isStringValueName(n))) {
577
+ return `${l} . ${r}`;
578
+ }
580
579
  const opMap = {
581
580
  "===": "==",
582
581
  "!==": "!=",
package/dist/index.js CHANGED
@@ -325,6 +325,9 @@ function renderFlatMethod(recv, depth, emit) {
325
325
 
326
326
  // src/adapter/expr/emitters.ts
327
327
  import {
328
+ groupBinaryOperand,
329
+ isStringTypedOperand as isStringTypedOperand2,
330
+ isStringConcatBinary,
328
331
  emitParsedExpr,
329
332
  identifierPath,
330
333
  matchSearchParamsMethodCall,
@@ -333,17 +336,7 @@ import {
333
336
  } from "@barefootjs/jsx";
334
337
 
335
338
  // src/adapter/expr/operand.ts
336
- function isStringTypedOperand(expr, isStringName) {
337
- if (expr.kind === "literal" && expr.literalType === "string")
338
- return true;
339
- if (expr.kind === "call" && expr.callee.kind === "identifier" && expr.args.length === 0) {
340
- return isStringName(expr.callee.name);
341
- }
342
- if (expr.kind === "member" && expr.object.kind === "identifier" && expr.object.name === "props") {
343
- return isStringName(expr.property);
344
- }
345
- return false;
346
- }
339
+ import { isStringTypedOperand } from "@barefootjs/jsx";
347
340
  function emitIndexAccessPerl(object, index, emit, isStringName) {
348
341
  const i = emit(index);
349
342
  return isStringTypedOperand(index, isStringName) ? `${emit(object)}->{${i}}` : `${emit(object)}->[${i}]`;
@@ -414,9 +407,9 @@ class MojoFilterEmitter {
414
407
  return arg;
415
408
  }
416
409
  binary(op, left, right, emit) {
417
- const l = emit(left);
418
- const r = emit(right);
419
- const isStr = (e) => isStringTypedOperand(e, this.isStringName);
410
+ const l = groupBinaryOperand(left, emit(left));
411
+ const r = groupBinaryOperand(right, emit(right));
412
+ const isStr = (e) => isStringTypedOperand2(e, this.isStringName);
420
413
  const stringCmp = isStr(left) || isStr(right);
421
414
  if ((op === "===" || op === "==") && stringCmp) {
422
415
  return `${l} eq ${r}`;
@@ -424,6 +417,9 @@ class MojoFilterEmitter {
424
417
  if ((op === "!==" || op === "!=") && stringCmp) {
425
418
  return `${l} ne ${r}`;
426
419
  }
420
+ if (isStringConcatBinary(op, left, right, this.isStringName)) {
421
+ return `${l} . ${r}`;
422
+ }
427
423
  const opMap = {
428
424
  "===": "==",
429
425
  "!==": "!=",
@@ -567,9 +563,9 @@ class MojoTopLevelEmitter {
567
563
  return arg;
568
564
  }
569
565
  binary(op, left, right, emit) {
570
- const l = emit(left);
571
- const r = emit(right);
572
- const isStr = (e) => isStringTypedOperand(e, (n) => this.ctx._isStringValueName(n));
566
+ const l = groupBinaryOperand(left, emit(left));
567
+ const r = groupBinaryOperand(right, emit(right));
568
+ const isStr = (e) => isStringTypedOperand2(e, (n) => this.ctx._isStringValueName(n));
573
569
  const stringCmp = isStr(left) || isStr(right);
574
570
  if ((op === "===" || op === "==") && stringCmp) {
575
571
  return `${l} eq ${r}`;
@@ -577,6 +573,9 @@ class MojoTopLevelEmitter {
577
573
  if ((op === "!==" || op === "!=") && stringCmp) {
578
574
  return `${l} ne ${r}`;
579
575
  }
576
+ if (isStringConcatBinary(op, left, right, (n) => this.ctx._isStringValueName(n))) {
577
+ return `${l} . ${r}`;
578
+ }
580
579
  const opMap = {
581
580
  "===": "==",
582
581
  "!==": "!=",
@@ -1806,16 +1805,11 @@ var conformancePins = {
1806
1805
  };
1807
1806
  // src/render-divergences.ts
1808
1807
  var renderDivergences = {
1809
- "arithmetic-text": "`(count() + 2) * 3` renders 10 instead of 18 — the parenthesised sub-expression loses its grouping (silent wrong arithmetic)",
1810
- "string-concat-plus": "`'Hello, ' + name` renders \"0\" — Perl's numeric `+` coerces the strings; JS string-concat `+` needs Perl's `.`",
1811
1808
  "string-length-text": "`.length` on a STRING prop diverges (array-length lowering misapplied to a scalar)",
1812
1809
  "number-tofixed": "the literal `¥` in template text reaches the output as U+FFFD — a UTF-8 encoding gap for non-ASCII literal text adjacent to a dynamic slot",
1813
1810
  "html-entity-text": "`©` in JSX literal text: Hono decodes to `©`, this adapter re-emits the raw entity — same DOM, different bytes",
1814
1811
  "math-methods": "Math.min/max/abs over a signal render empty (only Math.floor is in the template-primitive registry)",
1815
- "boolean-attr-literals": 'camelCase boolean alias `readOnly`: Hono SSRs `readOnly="true"`, this adapter emits bare presence',
1816
- "camelcase-attributes": "`htmlFor` is not lowered to `for` (Hono maps it)",
1817
1812
  "static-attr-escape": 'static attribute values are not HTML-escaped (`title="Fish & Chips"` emitted raw; Hono escapes)',
1818
- "svg-icon": "SVG camelCase presentation attrs (`strokeWidth`, `strokeLinecap`) pass through unmapped; Hono lowers to kebab-case",
1819
1813
  "object-entries-map": "`Object.entries(prop).map(([k, v]) => …)` renders an EMPTY list — the object-shaped prop silently produces zero iterations",
1820
1814
  "nested-loop-outer-binding": "nested-loop inner items carry `data-key` where the reference emits the depth-suffixed `data-key-1`",
1821
1815
  "jsx-element-prop": "a JSX element passed as a NON-children prop renders an empty slot — the element value is silently dropped",
@@ -1 +1 @@
1
- {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBA+B/B,CAAA"}
1
+ {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAqB/B,CAAA"}
@@ -1,5 +1,5 @@
1
1
  package BarefootJS::Backend::Mojo;
2
- our $VERSION = "0.18.2";
2
+ our $VERSION = "0.18.3";
3
3
  use Mojo::Base -base, -signatures;
4
4
 
5
5
  use Mojo::ByteStream qw(b);
@@ -1,5 +1,5 @@
1
1
  package Mojolicious::Plugin::BarefootJS::DevReload;
2
- our $VERSION = "0.18.2";
2
+ our $VERSION = "0.18.3";
3
3
  use Mojo::Base 'Mojolicious::Plugin', -signatures;
4
4
 
5
5
  =head1 NAME
@@ -1,5 +1,5 @@
1
1
  package Mojolicious::Plugin::BarefootJS;
2
- our $VERSION = "0.18.2";
2
+ our $VERSION = "0.18.3";
3
3
  use Mojo::Base 'Mojolicious::Plugin', -signatures;
4
4
 
5
5
  use Mojo::File qw(path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/mojolicious",
3
- "version": "0.18.3",
3
+ "version": "0.18.4",
4
4
  "description": "Mojolicious EP template adapter for BarefootJS - generates .html.ep files from IR",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,7 +52,7 @@
52
52
  "directory": "packages/adapter-mojolicious"
53
53
  },
54
54
  "dependencies": {
55
- "@barefootjs/shared": "0.18.3"
55
+ "@barefootjs/shared": "0.18.4"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "@barefootjs/jsx": ">=0.2.0",
@@ -60,6 +60,6 @@
60
60
  },
61
61
  "devDependencies": {
62
62
  "@barefootjs/adapter-tests": "0.1.0",
63
- "@barefootjs/jsx": "0.18.3"
63
+ "@barefootjs/jsx": "0.18.4"
64
64
  }
65
65
  }
@@ -11,7 +11,9 @@
11
11
  * adapter only through the narrow `MojoEmitContext` seam.
12
12
  */
13
13
 
14
- import {
14
+ import { groupBinaryOperand,
15
+ isStringTypedOperand,
16
+ isStringConcatBinary,
15
17
  type ParsedExprEmitter,
16
18
  type HigherOrderMethod,
17
19
  type ArrayMethod,
@@ -29,7 +31,7 @@ import {
29
31
 
30
32
  import type { MojoEmitContext } from '../emit-context.ts'
31
33
  import { MOJO_TEMPLATE_PRIMITIVES } from '../lib/constants.ts'
32
- import { emitIndexAccessPerl, isStringTypedOperand } from './operand.ts'
34
+ import { emitIndexAccessPerl } from './operand.ts'
33
35
  import {
34
36
  renderArrayMethod,
35
37
  renderSortMethod,
@@ -141,8 +143,11 @@ export class MojoFilterEmitter implements ParsedExprEmitter {
141
143
  }
142
144
 
143
145
  binary(op: string, left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string {
144
- const l = emit(left)
145
- const r = emit(right)
146
+ // Preserve source grouping: a compound operand re-emitted as infix
147
+ // text is otherwise re-parsed under THIS language's precedence —
148
+ // `(count() + 2) * 3` would silently become `count + 2 * 3` (#2173).
149
+ const l = groupBinaryOperand(left, emit(left))
150
+ const r = groupBinaryOperand(right, emit(right))
146
151
  // String equality: `eq`/`ne` when EITHER operand is string-typed — a string
147
152
  // literal, a string signal getter, or a string prop. Numeric `==`/`!=`
148
153
  // would coerce both sides to 0 and match unrelated non-numeric strings (#1672).
@@ -154,6 +159,12 @@ export class MojoFilterEmitter implements ParsedExprEmitter {
154
159
  if ((op === '!==' || op === '!=') && stringCmp) {
155
160
  return `${l} ne ${r}`
156
161
  }
162
+ // JS `+` with a string-typed operand is CONCATENATION, not addition —
163
+ // Perl's numeric `+` coerces `'Hello, ' + $name` to 0 (#2176). Lower
164
+ // to Perl's `.` concat operator.
165
+ if (isStringConcatBinary(op, left, right, this.isStringName)) {
166
+ return `${l} . ${r}`
167
+ }
157
168
  const opMap: Record<string, string> = {
158
169
  '===': '==', '!==': '!=', '>': '>', '<': '<', '>=': '>=', '<=': '<=',
159
170
  '+': '+', '-': '-', '*': '*', '/': '/',
@@ -389,8 +400,11 @@ export class MojoTopLevelEmitter implements ParsedExprEmitter {
389
400
  }
390
401
 
391
402
  binary(op: string, left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string {
392
- const l = emit(left)
393
- const r = emit(right)
403
+ // Preserve source grouping: a compound operand re-emitted as infix
404
+ // text is otherwise re-parsed under THIS language's precedence —
405
+ // `(count() + 2) * 3` would silently become `count + 2 * 3` (#2173).
406
+ const l = groupBinaryOperand(left, emit(left))
407
+ const r = groupBinaryOperand(right, emit(right))
394
408
  // String equality: `eq`/`ne` when EITHER operand is string-typed — a string
395
409
  // literal (`role() === 'admin'`), a string signal getter (`sel()`), or a
396
410
  // string prop (`props.x`). Falling back to numeric `==`/`!=` would make
@@ -404,6 +418,12 @@ export class MojoTopLevelEmitter implements ParsedExprEmitter {
404
418
  if ((op === '!==' || op === '!=') && stringCmp) {
405
419
  return `${l} ne ${r}`
406
420
  }
421
+ // JS `+` with a string-typed operand is CONCATENATION, not addition —
422
+ // Perl's numeric `+` coerces `'Hello, ' + $name` to 0 (#2176). Lower
423
+ // to Perl's `.` concat operator.
424
+ if (isStringConcatBinary(op, left, right, n => this.ctx._isStringValueName(n))) {
425
+ return `${l} . ${r}`
426
+ }
407
427
  const opMap: Record<string, string> = {
408
428
  '===': '==', '!==': '!=', '>': '>', '<': '<', '>=': '>=', '<=': '<=',
409
429
  '+': '+', '-': '-', '*': '*',
@@ -1,39 +1,18 @@
1
1
  /**
2
- * Operand-type classification + index-access lowering for the Mojolicious
3
- * EP template adapter.
2
+ * Index-access lowering for the Mojolicious EP template adapter.
4
3
  *
5
4
  * Extracted from `mojo-adapter.ts` (domain-module refactor, issue #2018
6
- * track D). Pure functions over `ParsedExpr` — they take an `isStringName`
5
+ * track D). Pure function over `ParsedExpr` — it takes an `isStringName`
7
6
  * predicate (supplied by the emitter from adapter state) rather than reading
8
7
  * adapter instance state directly.
9
8
  *
10
- * SHARED CANDIDATE: `isStringTypedOperand` is byte-identical to the Xslate
11
- * adapter's copy and is adapter-agnostic an extraction candidate for a
12
- * shared Perl-family codegen module (groundwork for the future Perl evaluator
13
- * integration, issue #2018 track D). `emitIndexAccessPerl` stays Mojo-specific
9
+ * The string-typed-operand classifier that used to live here (marked
10
+ * SHARED CANDIDATE) was promoted to `@barefootjs/jsx` as
11
+ * `isStringTypedOperand` (#2176); `emitIndexAccessPerl` stays Mojo-specific
14
12
  * (Perl's `->[]` vs `->{}` split has no Kolon equivalent).
15
13
  */
16
14
 
17
- import type { ParsedExpr } from '@barefootjs/jsx'
18
-
19
- /**
20
- * Whether a comparison operand is string-typed, so JS `===`/`!==` against it
21
- * must lower to Perl `eq`/`ne` instead of numeric `==`/`!=` (#1672). Covers a
22
- * string literal, a string-signal getter call (`sel()`), and a string prop
23
- * access (`props.x`). `isStringName` reports whether a getter/prop name is
24
- * known-string. Loop-element fields (`t.id`) on untyped arrays have no known
25
- * type and stay undetected — a separate, narrower gap.
26
- */
27
- export function isStringTypedOperand(expr: ParsedExpr, isStringName: (n: string) => boolean): boolean {
28
- if (expr.kind === 'literal' && expr.literalType === 'string') return true
29
- if (expr.kind === 'call' && expr.callee.kind === 'identifier' && expr.args.length === 0) {
30
- return isStringName(expr.callee.name)
31
- }
32
- if (expr.kind === 'member' && expr.object.kind === 'identifier' && expr.object.name === 'props') {
33
- return isStringName(expr.property)
34
- }
35
- return false
36
- }
15
+ import { isStringTypedOperand, type ParsedExpr } from '@barefootjs/jsx'
37
16
 
38
17
  /**
39
18
  * Lower `arr[index]` to a Perl deref. Perl distinguishes array
@@ -15,10 +15,6 @@
15
15
  import type { RenderDivergences } from '@barefootjs/jsx'
16
16
 
17
17
  export const renderDivergences: RenderDivergences = {
18
- 'arithmetic-text':
19
- '`(count() + 2) * 3` renders 10 instead of 18 — the parenthesised sub-expression loses its grouping (silent wrong arithmetic)',
20
- 'string-concat-plus':
21
- "`'Hello, ' + name` renders \"0\" — Perl's numeric `+` coerces the strings; JS string-concat `+` needs Perl's `.`",
22
18
  'string-length-text':
23
19
  '`.length` on a STRING prop diverges (array-length lowering misapplied to a scalar)',
24
20
  'number-tofixed':
@@ -27,14 +23,8 @@ export const renderDivergences: RenderDivergences = {
27
23
  '`&copy;` in JSX literal text: Hono decodes to `©`, this adapter re-emits the raw entity — same DOM, different bytes',
28
24
  'math-methods':
29
25
  'Math.min/max/abs over a signal render empty (only Math.floor is in the template-primitive registry)',
30
- 'boolean-attr-literals':
31
- 'camelCase boolean alias `readOnly`: Hono SSRs `readOnly="true"`, this adapter emits bare presence',
32
- 'camelcase-attributes':
33
- '`htmlFor` is not lowered to `for` (Hono maps it)',
34
26
  'static-attr-escape':
35
27
  'static attribute values are not HTML-escaped (`title="Fish & Chips"` emitted raw; Hono escapes)',
36
- 'svg-icon':
37
- 'SVG camelCase presentation attrs (`strokeWidth`, `strokeLinecap`) pass through unmapped; Hono lowers to kebab-case',
38
28
  'object-entries-map':
39
29
  '`Object.entries(prop).map(([k, v]) => …)` renders an EMPTY list — the object-shaped prop silently produces zero iterations',
40
30
  'nested-loop-outer-binding':