Skip to content

Commit 7342570

Browse files
authored
deconflict conextual action variable (#5839)
1 parent 5949c4a commit 7342570

File tree

8 files changed

+63
-19
lines changed

8 files changed

+63
-19
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Rework SSR store handling to subscribe and unsubscribe as in DOM mode ([#3375](https://github.com/sveltejs/svelte/issues/3375), [#3582](https://github.com/sveltejs/svelte/issues/3582), [#3636](https://github.com/sveltejs/svelte/issues/3636))
66
* Fix error when removing elements that are already transitioning out ([#5789](https://github.com/sveltejs/svelte/issues/5789), [#5808](https://github.com/sveltejs/svelte/issues/5808))
77
* Fix duplicate content race condition with `{#await}` blocks and out transitions ([#5815](https://github.com/sveltejs/svelte/issues/5815))
8+
* Deconflict variable names used for contextual actions ([#5839](https://github.com/sveltejs/svelte/issues/5839))
89

910
## 3.31.1
1011

src/compiler/compile/nodes/Action.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ import Node from './shared/Node';
22
import Expression from './shared/Expression';
33
import Component from '../Component';
44
import TemplateScope from './shared/TemplateScope';
5-
import { TemplateNode } from '../../interfaces';
5+
import { Directive } from '../../interfaces';
66

77
export default class Action extends Node {
88
type: 'Action';
99
name: string;
1010
expression: Expression;
1111
uses_context: boolean;
12+
template_scope: TemplateScope;
1213

13-
constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) {
14+
constructor(component: Component, parent: Node, scope: TemplateScope, info: Directive) {
1415
super(component, parent, scope, info);
1516

1617
const object = info.name.split('.')[0];
@@ -23,6 +24,8 @@ export default class Action extends Node {
2324
? new Expression(component, this, scope, info.expression)
2425
: null;
2526

27+
this.template_scope = scope;
28+
2629
this.uses_context = this.expression && this.expression.uses_context;
2730
}
2831
}

src/compiler/compile/nodes/shared/Expression.ts

+1-15
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Node, FunctionExpression, Identifier } from 'estree';
1414
import { INode } from '../interfaces';
1515
import { is_reserved_keyword } from '../../utils/reserved_keywords';
1616
import replace_object from '../../utils/replace_object';
17+
import is_contextual from './is_contextual';
1718
import EachBlock from '../EachBlock';
1819

1920
type Owner = INode;
@@ -409,18 +410,3 @@ function get_function_name(_node, parent) {
409410

410411
return 'func';
411412
}
412-
413-
function is_contextual(component: Component, scope: TemplateScope, name: string) {
414-
if (is_reserved_keyword(name)) return true;
415-
416-
// if it's a name below root scope, it's contextual
417-
if (!scope.is_top_level(name)) return true;
418-
419-
const variable = component.var_lookup.get(name);
420-
421-
// hoistables, module declarations, and imports are non-contextual
422-
if (!variable || variable.hoistable) return false;
423-
424-
// assume contextual
425-
return true;
426-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Component from '../../Component';
2+
import TemplateScope from './TemplateScope';
3+
import { is_reserved_keyword } from '../../utils/reserved_keywords';
4+
5+
export default function is_contextual(component: Component, scope: TemplateScope, name: string) {
6+
if (is_reserved_keyword(name)) return true;
7+
8+
// if it's a name below root scope, it's contextual
9+
if (!scope.is_top_level(name)) return true;
10+
11+
const variable = component.var_lookup.get(name);
12+
13+
// hoistables, module declarations, and imports are non-contextual
14+
if (!variable || variable.hoistable) return false;
15+
16+
// assume contextual
17+
return true;
18+
}

src/compiler/compile/render_dom/wrappers/shared/add_actions.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { b, x } from 'code-red';
22
import Block from '../../Block';
33
import Action from '../../../nodes/Action';
4+
import is_contextual from '../../../nodes/shared/is_contextual';
45

56
export default function add_actions(
67
block: Block,
@@ -11,7 +12,7 @@ export default function add_actions(
1112
}
1213

1314
export function add_action(block: Block, target: string, action: Action) {
14-
const { expression } = action;
15+
const { expression, template_scope } = action;
1516
let snippet;
1617
let dependencies;
1718

@@ -28,7 +29,9 @@ export function add_action(block: Block, target: string, action: Action) {
2829

2930
const [obj, ...properties] = action.name.split('.');
3031

31-
const fn = block.renderer.reference(obj);
32+
const fn = is_contextual(action.component, template_scope, obj)
33+
? block.renderer.reference(obj)
34+
: obj;
3235

3336
if (properties.length) {
3437
const member_expression = properties.reduce((lhs, rhs) => x`${lhs}.${rhs}`, fn);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
let result;
2+
3+
export default {
4+
before_test() {
5+
result = [];
6+
},
7+
props: {
8+
collect: (str) => result.push(str)
9+
},
10+
test({ assert }) {
11+
assert.deepEqual(result, ['each_action', 'import_action']);
12+
}
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
import action from './util.js';
3+
export let collect;
4+
5+
function each_action(_, fn) {
6+
fn('each_action');
7+
}
8+
const array = [each_action];
9+
</script>
10+
11+
<div use:action={collect} />
12+
13+
<ul>
14+
{#each array as action}
15+
<div use:action={collect} />
16+
{/each}
17+
</ul>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function (_, fn) {
2+
fn('import_action');
3+
}

0 commit comments

Comments
 (0)