@barefootjs/mojolicious 0.16.0 → 0.17.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/dist/adapter/analysis/component-tree.d.ts +30 -0
- package/dist/adapter/analysis/component-tree.d.ts.map +1 -0
- package/dist/adapter/emit-context.d.ts +96 -0
- package/dist/adapter/emit-context.d.ts.map +1 -0
- package/dist/adapter/expr/array-method.d.ts +75 -0
- package/dist/adapter/expr/array-method.d.ts.map +1 -0
- package/dist/adapter/expr/emitters.d.ts +77 -0
- package/dist/adapter/expr/emitters.d.ts.map +1 -0
- package/dist/adapter/expr/operand.d.ts +34 -0
- package/dist/adapter/expr/operand.d.ts.map +1 -0
- package/dist/adapter/index.js +1490 -1336
- package/dist/adapter/lib/constants.d.ts +27 -0
- package/dist/adapter/lib/constants.d.ts.map +1 -0
- package/dist/adapter/lib/ir-scope.d.ts +40 -0
- package/dist/adapter/lib/ir-scope.d.ts.map +1 -0
- package/dist/adapter/lib/perl-naming.d.ts +29 -0
- package/dist/adapter/lib/perl-naming.d.ts.map +1 -0
- package/dist/adapter/lib/types.d.ts +28 -0
- package/dist/adapter/lib/types.d.ts.map +1 -0
- package/dist/adapter/memo/seed.d.ts +43 -0
- package/dist/adapter/memo/seed.d.ts.map +1 -0
- package/dist/adapter/mojo-adapter.d.ts +46 -104
- package/dist/adapter/mojo-adapter.d.ts.map +1 -1
- package/dist/adapter/props/prop-classes.d.ts +48 -0
- package/dist/adapter/props/prop-classes.d.ts.map +1 -0
- package/dist/adapter/spread/spread-codegen.d.ts +64 -0
- package/dist/adapter/spread/spread-codegen.d.ts.map +1 -0
- package/dist/adapter/value/parsed-literal.d.ts +26 -0
- package/dist/adapter/value/parsed-literal.d.ts.map +1 -0
- package/dist/build.js +1490 -1336
- package/dist/index.js +1490 -1336
- package/dist/test-render.d.ts.map +1 -1
- package/lib/BarefootJS/Backend/Mojo.pm +1 -1
- package/lib/Mojolicious/Plugin/BarefootJS/DevReload.pm +1 -1
- package/lib/Mojolicious/Plugin/BarefootJS.pm +1 -1
- package/package.json +3 -3
- package/src/__tests__/mojo-adapter.test.ts +124 -60
- package/src/__tests__/query-href.test.ts +94 -0
- package/src/adapter/analysis/component-tree.ts +128 -0
- package/src/adapter/emit-context.ts +107 -0
- package/src/adapter/expr/array-method.ts +408 -0
- package/src/adapter/expr/emitters.ts +607 -0
- package/src/adapter/expr/operand.ts +55 -0
- package/src/adapter/lib/constants.ts +39 -0
- package/src/adapter/lib/ir-scope.ts +70 -0
- package/src/adapter/lib/perl-naming.ts +36 -0
- package/src/adapter/lib/types.ts +31 -0
- package/src/adapter/memo/seed.ts +126 -0
- package/src/adapter/mojo-adapter.ts +223 -1476
- package/src/adapter/props/prop-classes.ts +87 -0
- package/src/adapter/spread/spread-codegen.ts +181 -0
- package/src/adapter/value/parsed-literal.ts +34 -0
- package/src/test-render.ts +2 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prop classification for the Mojolicious EP template adapter.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `mojo-adapter.ts` (domain-module refactor, issue #2018
|
|
5
|
+
* track D). Pure functions over `ir.metadata` that derive the per-compile
|
|
6
|
+
* prop/name sets the adapter consults during lowering. Mirror of the Go
|
|
7
|
+
* adapter's `props/prop-types.ts`. No adapter instance state.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ComponentIR } from '@barefootjs/jsx'
|
|
11
|
+
import { isStringTypeInfo, isBareStringLiteral } from '../value/parsed-literal.ts'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* (#1971) SSR-resolvable context-value names: props, signal getters, memos.
|
|
15
|
+
* A `<Ctx.Provider value>` member NOT in this set is a client-only function
|
|
16
|
+
* with no SSR value, lowered to `undef`.
|
|
17
|
+
*/
|
|
18
|
+
export function collectProviderDataNames(ir: ComponentIR): Set<string> {
|
|
19
|
+
return new Set<string>([
|
|
20
|
+
...ir.metadata.propsParams.map(p => p.name),
|
|
21
|
+
...(ir.metadata.signals ?? []).map(s => s.getter),
|
|
22
|
+
...(ir.metadata.memos ?? []).map(m => m.name),
|
|
23
|
+
])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Props whose declared TS type is boolean — a bare binding of one
|
|
28
|
+
* (`data-active={props.isActive}`) must stringify as JS `String(boolean)`
|
|
29
|
+
* ("true"/"false"), not Perl's native `1`/`''` (#1897, pagination's
|
|
30
|
+
* data-active).
|
|
31
|
+
*/
|
|
32
|
+
export function collectBooleanTypedProps(ir: ComponentIR): Set<string> {
|
|
33
|
+
return new Set(
|
|
34
|
+
ir.metadata.propsParams
|
|
35
|
+
.filter(prop => prop.type?.primitive === 'boolean' || prop.type?.raw === 'boolean')
|
|
36
|
+
.map(prop => prop.name),
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* No-destructure-default props → `undef` when the caller omits them → guard
|
|
42
|
+
* their bare-reference attribute emission with Perl `defined` so the
|
|
43
|
+
* attribute drops instead of rendering `attr=""` (Hono-style nullish
|
|
44
|
+
* omission). A prop WITH a destructure default (`value = ''`) is never
|
|
45
|
+
* `undef` in the body and must stay unconditional, so it is excluded. This
|
|
46
|
+
* mirrors the Go adapter's nillable-field guard: there the witness is the
|
|
47
|
+
* resolved `interface{}` field type; here it is the absence of a default (the
|
|
48
|
+
* analyzer reports `rows` — a `TextareaHTMLAttributes` member destructured
|
|
49
|
+
* without a default — as no-default, `type.kind: 'unknown'`).
|
|
50
|
+
* Excludes concrete-primitive types (`string`/`number`/`boolean`) to match
|
|
51
|
+
* the Go adapter's scope, which guards only `interface{}` (nillable) fields
|
|
52
|
+
* and leaves concrete fields unconditional. So a required, no-default
|
|
53
|
+
* `string` prop still emits `attr=""` like Hono, and only nillable
|
|
54
|
+
* (`unknown`/object/array) no-default props guard.
|
|
55
|
+
*/
|
|
56
|
+
export function collectNullableOptionalProps(ir: ComponentIR): Set<string> {
|
|
57
|
+
return new Set(
|
|
58
|
+
ir.metadata.propsParams
|
|
59
|
+
.filter(
|
|
60
|
+
p =>
|
|
61
|
+
p.defaultValue === undefined &&
|
|
62
|
+
!p.isRest &&
|
|
63
|
+
p.type?.kind !== 'primitive',
|
|
64
|
+
)
|
|
65
|
+
.map(p => p.name),
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* String-typed signals and props, so equality comparisons against them lower
|
|
71
|
+
* to `eq`/`ne` (#1672). A signal is string-typed when its inferred type is
|
|
72
|
+
* `string` (the analyzer infers this from a string-literal initial value) or,
|
|
73
|
+
* defensively, when its initial value is a bare string literal; a prop when
|
|
74
|
+
* its annotated type is `string`.
|
|
75
|
+
*/
|
|
76
|
+
export function collectStringValueNames(ir: ComponentIR): Set<string> {
|
|
77
|
+
const names = new Set<string>()
|
|
78
|
+
for (const s of ir.metadata.signals) {
|
|
79
|
+
if (isStringTypeInfo(s.type) || isBareStringLiteral(s.initialValue)) {
|
|
80
|
+
names.add(s.getter)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const p of ir.metadata.propsParams) {
|
|
84
|
+
if (isStringTypeInfo(p.type)) names.add(p.name)
|
|
85
|
+
}
|
|
86
|
+
return names
|
|
87
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object-literal / conditional-spread → Perl hashref lowering for the
|
|
3
|
+
* Mojolicious EP template adapter.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `mojo-adapter.ts` (domain-module refactor, issue #2018
|
|
6
|
+
* track D). Free functions taking a `MojoSpreadContext` (built by the adapter's
|
|
7
|
+
* `spreadCtx` getter) so the cluster depends on the narrow seam — the recursive
|
|
8
|
+
* expression entry plus per-compile bookkeeping — rather than the whole
|
|
9
|
+
* adapter class. Mirror of the Go adapter's `spread/spread-codegen.ts`.
|
|
10
|
+
*
|
|
11
|
+
* The conditional-spread / object-literal entries read the IR-carried
|
|
12
|
+
* structured `ParsedExpr` tree (#2018, mirroring go-template's U5/U6) instead
|
|
13
|
+
* of re-parsing the source with `ts.createSourceFile`. The condition and scalar
|
|
14
|
+
* values are threaded straight into `ctx.convertExpressionToPerl` as its
|
|
15
|
+
* `preParsed` argument (cf. go-template's
|
|
16
|
+
* `convertExpressionToGo(jsExpr, out?, preParsed?)`), so no stringify→re-parse
|
|
17
|
+
* round-trip occurs — the emitted Perl is byte-identical to the former path
|
|
18
|
+
* because the carried tree is exactly what re-parsing the stringified text
|
|
19
|
+
* produced. The `ts.factory` rebuild in `recordIndexAccessToPerl` only
|
|
20
|
+
* reconstructs the `IDENT[KEY]` node the shared `parseRecordIndexAccess` parser
|
|
21
|
+
* accepts; no source-text re-parse. `stringifyParsedExpr` is retained solely for
|
|
22
|
+
* the BF101 diagnostic message (display purposes).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import ts from 'typescript'
|
|
26
|
+
import { parseRecordIndexAccess, stringifyParsedExpr } from '@barefootjs/jsx'
|
|
27
|
+
import type { ParsedExpr } from '@barefootjs/jsx'
|
|
28
|
+
|
|
29
|
+
import type { MojoSpreadContext } from '../emit-context.ts'
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Lower a `cond ? {…} : {…}` conditional-spread expression — carried as the
|
|
33
|
+
* IR's structured `ParsedExpr` tree — to a Perl ternary over two hashrefs, or
|
|
34
|
+
* null when it isn't that shape. `parseExpression` already strips redundant
|
|
35
|
+
* parentheses, so the conditional / object-literal shapes surface directly.
|
|
36
|
+
*/
|
|
37
|
+
export function conditionalSpreadToPerl(
|
|
38
|
+
ctx: MojoSpreadContext,
|
|
39
|
+
expr: ParsedExpr | undefined,
|
|
40
|
+
): string | null {
|
|
41
|
+
if (!expr || expr.kind !== 'conditional') return null
|
|
42
|
+
const whenTrue = expr.consequent
|
|
43
|
+
const whenFalse = expr.alternate
|
|
44
|
+
if (whenTrue.kind !== 'object-literal' || whenFalse.kind !== 'object-literal') {
|
|
45
|
+
return null
|
|
46
|
+
}
|
|
47
|
+
// Thread the condition's carried `ParsedExpr` tree straight through as
|
|
48
|
+
// `preParsed` (#2018) — no stringify→re-parse round-trip; `convertExpressionToPerl`
|
|
49
|
+
// uses the tree directly and derives any diagnostic text from it.
|
|
50
|
+
const condPerl = ctx.convertExpressionToPerl('', expr.test)
|
|
51
|
+
const truePerl = objectLiteralToPerlHashref(ctx, whenTrue)
|
|
52
|
+
const falsePerl = objectLiteralToPerlHashref(ctx, whenFalse)
|
|
53
|
+
if (truePerl === null || falsePerl === null) return null
|
|
54
|
+
return `${condPerl} ? ${truePerl} : ${falsePerl}`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* (#1971 Perl) Lower a bare object-literal expression (`{ align: 'start' }`),
|
|
59
|
+
* carried as the IR's structured `ParsedExpr` tree, to a Perl hashref via
|
|
60
|
+
* `objectLiteralToPerlHashref`, or null when it isn't a plain object literal.
|
|
61
|
+
* Used for inline object-literal child props (carousel `opts`).
|
|
62
|
+
*/
|
|
63
|
+
export function objectLiteralExprToPerlHashref(
|
|
64
|
+
ctx: MojoSpreadContext,
|
|
65
|
+
expr: ParsedExpr | undefined,
|
|
66
|
+
): string | null {
|
|
67
|
+
if (!expr || expr.kind !== 'object-literal') return null
|
|
68
|
+
return objectLiteralToPerlHashref(ctx, expr)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Convert a static object literal into a Perl hashref string for a
|
|
73
|
+
* conditional spread. Only static string/identifier keys are allowed;
|
|
74
|
+
* values resolve via `convertExpressionToPerl`. Returns null for any
|
|
75
|
+
* computed/spread/dynamic key. Empty object → `{}`.
|
|
76
|
+
*/
|
|
77
|
+
export function objectLiteralToPerlHashref(
|
|
78
|
+
ctx: MojoSpreadContext,
|
|
79
|
+
obj: Extract<ParsedExpr, { kind: 'object-literal' }>,
|
|
80
|
+
): string | null {
|
|
81
|
+
const entries: string[] = []
|
|
82
|
+
for (const prop of obj.properties) {
|
|
83
|
+
// Shorthand `{ a }` was a `ShorthandPropertyAssignment` (not a
|
|
84
|
+
// `PropertyAssignment`), so the former parser rejected it — keep refusing.
|
|
85
|
+
if (prop.shorthand) return null
|
|
86
|
+
// A numeric key (`{ 1: x }`) was rejected by the former parser (only
|
|
87
|
+
// identifier / string-literal names were accepted); `keyKind`
|
|
88
|
+
// distinguishes it from a same-text string `'1'` key.
|
|
89
|
+
if (prop.keyKind === 'numeric') return null
|
|
90
|
+
const key = prop.key
|
|
91
|
+
const val = prop.value
|
|
92
|
+
const indexed = recordIndexAccessToPerl(ctx, val)
|
|
93
|
+
if (
|
|
94
|
+
indexed === null &&
|
|
95
|
+
val.kind === 'index-access' &&
|
|
96
|
+
!isLiteralIndex(val.index)
|
|
97
|
+
) {
|
|
98
|
+
// Variable-index record access (`sizeMap[size]`) that the
|
|
99
|
+
// static-inline path couldn't resolve — a non-scalar record
|
|
100
|
+
// value, or a non-const receiver. Since #1897 made variable
|
|
101
|
+
// indices parseable (`index-access`), the generic value lowering
|
|
102
|
+
// would now emit `$sizeMap->{$size}` against an UNBOUND module
|
|
103
|
+
// const instead of refusing. Record BF101 and bail so the whole
|
|
104
|
+
// spread surfaces the out-of-shape diagnostic, matching the
|
|
105
|
+
// pre-#1897 behaviour (the refusal then was a side effect of the
|
|
106
|
+
// value lowering). (A bound receiver — a signal getter like
|
|
107
|
+
// `selected()[index]` — is an attribute value, not a spread
|
|
108
|
+
// member, and never reaches here.)
|
|
109
|
+
ctx.errors.push({
|
|
110
|
+
code: 'BF101',
|
|
111
|
+
severity: 'error',
|
|
112
|
+
message: `Spread object value '${stringifyParsedExpr(val)}' indexes a record map whose values aren't scalar literals — it can't lower to an inline Perl hashref.`,
|
|
113
|
+
loc: { file: ctx.componentName + '.tsx', start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
|
|
114
|
+
suggestion: {
|
|
115
|
+
message: 'Index a record whose values are number/string literals, or move the spread into a `\'use client\'` component so hydration computes it.',
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
return null
|
|
119
|
+
}
|
|
120
|
+
const valPerl =
|
|
121
|
+
indexed !== null
|
|
122
|
+
? indexed
|
|
123
|
+
// Thread the carried `val` tree straight through as `preParsed` (#2018)
|
|
124
|
+
// — no stringify→re-parse round-trip.
|
|
125
|
+
: ctx.convertExpressionToPerl('', val)
|
|
126
|
+
entries.push(`'${key.replace(/'/g, "\\'")}' => ${valPerl}`)
|
|
127
|
+
}
|
|
128
|
+
return entries.length === 0 ? '{}' : `{ ${entries.join(', ')} }`
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** True when a parsed index is a numeric or string literal (`arr[0]`, `m['k']`). */
|
|
132
|
+
function isLiteralIndex(index: ParsedExpr): boolean {
|
|
133
|
+
return (
|
|
134
|
+
index.kind === 'literal' &&
|
|
135
|
+
(index.literalType === 'number' || index.literalType === 'string')
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Lower a spread-object VALUE of the form `IDENT[KEY]` where:
|
|
141
|
+
* - `IDENT` resolves via `localConstants` to a MODULE-scope object
|
|
142
|
+
* literal whose property values are all scalar (number/string)
|
|
143
|
+
* literals under static (string-literal or identifier) keys
|
|
144
|
+
* (a `Record<staticKeys, scalar>` map like `sizeMap`), AND
|
|
145
|
+
* - `KEY` is a bare identifier that is a prop.
|
|
146
|
+
* Emits an inline indexed Perl hashref:
|
|
147
|
+
* `{ 'sm' => 16, 'md' => 20, ... }->{$size}`
|
|
148
|
+
*
|
|
149
|
+
* Returns the Perl string when convertible, else `null` so the caller
|
|
150
|
+
* falls back to its normal value lowering (which records BF101 for an
|
|
151
|
+
* unsupported shape). Mirror of the Go adapter's `recordIndexAccessToGoMap`.
|
|
152
|
+
*/
|
|
153
|
+
export function recordIndexAccessToPerl(ctx: MojoSpreadContext, val: ParsedExpr): string | null {
|
|
154
|
+
// `parseRecordIndexAccess` (the shared single-source-of-truth parser) takes a
|
|
155
|
+
// `ts.Expression`. The only shape it accepts is `IDENT[KEY]` with identifier
|
|
156
|
+
// object and index, so rebuild exactly that node from the carried tree via
|
|
157
|
+
// `ts.factory` — no source-text re-parse needed. Any other shape can't match
|
|
158
|
+
// and short-circuits to `null` here.
|
|
159
|
+
if (
|
|
160
|
+
val.kind !== 'index-access' ||
|
|
161
|
+
val.object.kind !== 'identifier' ||
|
|
162
|
+
val.index.kind !== 'identifier'
|
|
163
|
+
) {
|
|
164
|
+
return null
|
|
165
|
+
}
|
|
166
|
+
const tsVal = ts.factory.createElementAccessExpression(
|
|
167
|
+
ts.factory.createIdentifier(val.object.name),
|
|
168
|
+
ts.factory.createIdentifier(val.index.name),
|
|
169
|
+
)
|
|
170
|
+
// Shared structural parse (single source of truth in `@barefootjs/jsx`);
|
|
171
|
+
// this wrapper only does the Perl-specific emit (single-quote escaping)
|
|
172
|
+
// from the structured result.
|
|
173
|
+
const parsed = parseRecordIndexAccess(tsVal, ctx.localConstants, ctx.propsParams)
|
|
174
|
+
if (!parsed) return null
|
|
175
|
+
const entries = parsed.entries.map(e => {
|
|
176
|
+
const mapVal =
|
|
177
|
+
e.value.kind === 'number' ? e.value.text : `'${e.value.text.replace(/'/g, "\\'")}'`
|
|
178
|
+
return `'${e.key.replace(/'/g, "\\'")}' => ${mapVal}`
|
|
179
|
+
})
|
|
180
|
+
return `{ ${entries.join(', ')} }->{$${parsed.indexPropName}}`
|
|
181
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String-type value helpers for the Mojolicious EP template adapter.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `mojo-adapter.ts` (domain-module refactor, issue #2018
|
|
5
|
+
* track D). Pure functions over analyzer type info / const-initializer text —
|
|
6
|
+
* no adapter instance state.
|
|
7
|
+
*
|
|
8
|
+
* SHARED CANDIDATE: `isStringTypeInfo` and `isBareStringLiteral` are
|
|
9
|
+
* byte-identical to the Xslate adapter's copies and adapter-agnostic —
|
|
10
|
+
* extraction candidates for a shared Perl-family codegen module (groundwork
|
|
11
|
+
* for the future Perl evaluator integration, issue #2018 track D).
|
|
12
|
+
*
|
|
13
|
+
* (#2018) The former `parsePureStringLiteral` (the file's only
|
|
14
|
+
* `ts.createSourceFile` re-parse) was removed: module-scope pure-string-const
|
|
15
|
+
* inlining is owned by the shared `collectModuleStringConsts` in
|
|
16
|
+
* `@barefootjs/jsx` (consumed via `moduleStringConsts`), so the adapter-local
|
|
17
|
+
* copy had no callers. Dropping it keeps the adapter free of emit-time source
|
|
18
|
+
* re-parsing without changing any output.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { TypeInfo } from '@barefootjs/jsx'
|
|
22
|
+
|
|
23
|
+
/** True when `type` is the `string` primitive. */
|
|
24
|
+
export function isStringTypeInfo(type: TypeInfo | undefined): boolean {
|
|
25
|
+
return type?.kind === 'primitive' && type.primitive === 'string'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** True when `initialValue` is a bare string-literal expression (`'x'` /
|
|
29
|
+
* `"x"`), used as a fallback for signals whose type wasn't inferred. */
|
|
30
|
+
export function isBareStringLiteral(initialValue: string | undefined): boolean {
|
|
31
|
+
if (!initialValue) return false
|
|
32
|
+
const v = initialValue.trim()
|
|
33
|
+
return (v.startsWith("'") && v.endsWith("'")) || (v.startsWith('"') && v.endsWith('"'))
|
|
34
|
+
}
|
package/src/test-render.ts
CHANGED
|
@@ -453,6 +453,7 @@ function buildChildDefaultsPerl(ir: ComponentIR): string {
|
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
455
|
for (const signal of ir.metadata.signals) {
|
|
456
|
+
if (signal.envReader) continue // env signal is the request reader, not a stashed value (#2057)
|
|
456
457
|
const value = evaluateSignalInit(signal.initialValue.trim(), undefined)
|
|
457
458
|
entries.push(`${signal.getter} => ${value !== null ? toPerlLiteral(value) : 'undef'}`)
|
|
458
459
|
}
|
|
@@ -599,6 +600,7 @@ function buildPerlProps(
|
|
|
599
600
|
// vars with `Global symbol "$x" requires explicit package name`. Same
|
|
600
601
|
// rule `buildChildDefaultsPerl` applies to child signals (#1897).
|
|
601
602
|
for (const signal of ir.metadata.signals) {
|
|
603
|
+
if (signal.envReader) continue // env signal bound below via search_params('') (#2057)
|
|
602
604
|
const value = evaluateSignalInit(signal.initialValue.trim(), props)
|
|
603
605
|
entries.push(`${signal.getter} => ${value !== null ? toPerlLiteral(value) : 'undef'}`)
|
|
604
606
|
}
|