fix: declared non nullable aliases in different section

This commit is contained in:
dpiercey 2026-01-21 15:52:08 -07:00 committed by Dylan Piercey
parent 255769d102
commit e31adc0511
13 changed files with 232 additions and 4 deletions

View File

@ -0,0 +1,6 @@
---
"@marko/runtime-tags": patch
"marko": patch
---
Fix aliases in another section incorrectly causing a binding to be seen as declared / non nullable.

View File

@ -0,0 +1,13 @@
{
"vars": {
"props": {
"$_": "_",
"$init": "t",
"$$if_content__value_class": "r",
"$$if_content__text": "s",
"$$if_content__setup": "a",
"$$Child_content__if": "o",
"$$Child_content__setup": "e"
}
}
}

View File

@ -0,0 +1,14 @@
# Render
```html
<!---->
<div>
<!---->
<!---->
</div>
<!---->
```
# Mutations
```
INSERT #comment0, div, #comment1
```

View File

@ -0,0 +1,20 @@
// size: 300 (min) 184 (brotli)
_._script("a0", ($scope) => _._attrs_script($scope, "a"));
const $if_content__value_class = _._closure_get(
2,
($scope) => _._attr_class($scope.a, $scope._._.c),
($scope) => $scope._._,
),
$if_content__text = _._closure_get(
3,
($scope) => _._text($scope.b, $scope._._.d),
($scope) => $scope._._,
),
$if_content__setup = ($scope) => {
($if_content__value_class($scope), $if_content__text($scope));
},
$Child_content__if = _._if(0, "<span> </span>", " D l", $if_content__setup),
$Child_content__setup = _._closure_get(1, ($scope) =>
$Child_content__if($scope, $scope._.b ? 0 : 1),
);
(_._content_resume("a1", "<!><!><!>", "b%c", $Child_content__setup), init());

View File

@ -0,0 +1,34 @@
const $Child_content2__walks = /* get, over(1) */" b",
$Child_content2__template = "<div></div>";
export const $template = `<!>${$Child_content2__template}<!>`;
export const $walks = /* over(1), <Child>, over(1) */`b/${$Child_content2__walks}&b`;
import * as _ from "@marko/runtime-tags/debug/dom";
const $Child_content2__input__script = _._script("__tests__/template.marko_3_input", $scope => _._attrs_script($scope, "#div/0"));
const $Child_content2__input = /* @__PURE__ */_._const("input", $scope => {
_._attrs_content($scope, "#div/0", $scope.input);
$Child_content2__input__script($scope);
});
const $Child_content2__$params = ($scope, $params2) => $Child_content2__input($scope, $params2[0]);
const $if_content__value_class = /* @__PURE__ */_._closure_get("value_class", $scope => _._attr_class($scope["#span/0"], $scope._._.value_class), $scope => $scope._._);
const $if_content__text = /* @__PURE__ */_._closure_get("text", $scope => _._text($scope["#text/1"], $scope._._.text), $scope => $scope._._);
const $if_content__setup = $scope => {
$if_content__value_class($scope);
$if_content__text($scope);
};
const $Child_content__if = /* @__PURE__ */_._if("#text/0", "<span> </span>", /* get, next(1), get, out(1) */" D l", $if_content__setup);
const $Child_content__value = /* @__PURE__ */_._closure_get("value", $scope => $Child_content__if($scope, $scope._.value ? 0 : 1));
const $Child_content__setup = $Child_content__value;
const $Child_content = _._content_resume("__tests__/template.marko_1_content", "<!><!><!>", /* over(1), replace, over(2) */"b%c", $Child_content__setup);
const $value = /* @__PURE__ */_._const("value", $scope => {
$value_class($scope, $scope.value?.class);
$text($scope, $scope.value?.text);
});
const $value_class = /* @__PURE__ */_._const("value_class");
const $text = /* @__PURE__ */_._const("text");
export function $setup($scope) {
$Child_content2__input($scope["#childScope/0"], {
content: $Child_content($scope)
});
$value($scope, undefined);
}
export default /* @__PURE__ */_._template("__tests__/template.marko", $template, $walks, $setup);

View File

@ -0,0 +1,47 @@
import * as _ from "@marko/runtime-tags/debug/html";
export default _._template("__tests__/template.marko", input => {
const $scope0_id = _._scope_id();
const value = undefined;
const Child = {
content: _._content("__tests__/template.marko_3_content", input => {
const $scope3_id = _._scope_id();
_._html("<div");
_._attrs_content(input, "#div/0", $scope3_id, "div");
_._html(`</div>${_._el_resume($scope3_id, "#div/0")}`);
_._script($scope3_id, "__tests__/template.marko_3_input");
_._scope($scope3_id, {
input
}, "__tests__/template.marko", "2:2", {
input: "2:15"
});
})
};
Child.content({
content: _._content_resume("__tests__/template.marko_1_content", () => {
const $scope1_id = _._scope_id();
if (value) {
const $scope2_id = _._scope_id();
const {
text
} = value;
_._html(`<span${_._attr_class(value.class)}>${_._escape(text)}</span>`);
_._scope($scope2_id, {
_: _._scope_with_id($scope1_id)
}, "__tests__/template.marko", "7:4");
}
_._scope($scope1_id, {
_: _._scope_with_id($scope0_id)
}, "__tests__/template.marko", "6:2");
_._resume_branch($scope1_id);
}, $scope0_id)
});
_._scope($scope0_id, {
value,
value_class: value?.class,
text: value?.text
}, "__tests__/template.marko", 0, {
value: "1:8",
value_class: ["value.class", "1:8"],
text: "8:16"
});
});

View File

@ -0,0 +1,26 @@
# Render
```html
<html>
<head />
<body>
<div />
<!--M_*2 #div/0-->
<script>
WALKER_RUNTIME("M")("_");
M._.r = [_ =&gt; (_.d = [0, _.a = {},
{
"BranchScopes:#div/0": _.c = {
_: _.a
},
"ConditionalRenderer:#div/0": "__tests__/template.marko_1_content",
input: _.b = {}
}, _.c], _.b.content = _._[
"__tests__/template.marko_1_content"
](_.a), _.d),
"__tests__/template.marko_3_input 2"
];
M._.w()
</script>
</body>
</html>
```

View File

@ -0,0 +1,4 @@
# Render End
```html
<div />
```

View File

@ -0,0 +1,42 @@
# Write
```html
<div></div><!--M_*2 #div/0--><script>WALKER_RUNTIME("M")("_");M._.r=[_=>(_.d=[0,_.a={},{"BranchScopes:#div/0":_.c={_:_.a},"ConditionalRenderer:#div/0":"__tests__/template.marko_1_content",input:_.b={}},_.c],_.b.content=_._["__tests__/template.marko_1_content"](_.a),_.d),"__tests__/template.marko_3_input 2"];M._.w()</script>
```
# Render End
```html
<html>
<head />
<body>
<div />
<!--M_*2 #div/0-->
<script>
WALKER_RUNTIME("M")("_");
M._.r = [_ =&gt; (_.d = [0, _.a = {},
{
"BranchScopes:#div/0": _.c = {
_: _.a
},
"ConditionalRenderer:#div/0": "__tests__/template.marko_1_content",
input: _.b = {}
}, _.c], _.b.content = _._[
"__tests__/template.marko_1_content"
](_.a), _.d),
"__tests__/template.marko_3_input 2"
];
M._.w()
</script>
</body>
</html>
```
# Mutations
```
INSERT html
INSERT html/head
INSERT html/body
INSERT html/body/div
INSERT html/body/#comment
INSERT html/body/script
INSERT html/body/script/#text
```

View File

@ -0,0 +1,11 @@
<const/value=undefined>
<define/Child|input|>
<div ...input/>
</define>
<Child>
<if=value>
<const/{ text }=value>
<span class=value.class>${text}</span>
</if>
</>

View File

@ -160,14 +160,16 @@ const [getNextBindingId, setNextBindingId] = createProgramState(() => 0);
export function createBinding(
name: string,
type: Binding["type"],
section: Section,
refSection: Section,
upstreamAlias?: Binding["upstreamAlias"],
property?: string,
excludeProperties?: Opt<string>,
loc: t.SourceLocation | null = null,
declared = false,
refDeclared = false,
): Binding {
const id = getNextBindingId();
const section = upstreamAlias ? upstreamAlias.section : refSection;
const declared = refDeclared && refSection === section;
const binding: Binding = {
id,
name,
@ -291,6 +293,7 @@ export function trackVarReferences(
) {
const tagVar = tag.node.var;
if (tagVar) {
const section = getOrCreateSection(tag);
let canonicalUpstreamAlias =
upstreamAlias && getCanonicalBinding(upstreamAlias);
if (canonicalUpstreamAlias) {
@ -302,7 +305,7 @@ export function trackVarReferences(
tagVar,
canonicalUpstreamAlias.type,
tag.scope,
canonicalUpstreamAlias.section,
section,
canonicalUpstreamAlias,
undefined,
excludeProperties,
@ -314,7 +317,7 @@ export function trackVarReferences(
tagVar,
type,
tag.scope,
getOrCreateSection(tag),
section,
undefined,
undefined,
undefined,