add more test case, supporting deep destructuring and array destructuring

pull/7526/head
tanhauhau 4 years ago
parent 2562687ce7
commit 976213d4a1

@ -23,6 +23,8 @@ export default class AwaitBlock extends Node {
then: ThenBlock; then: ThenBlock;
catch: CatchBlock; catch: CatchBlock;
context_rest_properties: Map<string, ESTreeNode> = new Map();
constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) { constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) {
super(component, parent, scope, info); super(component, parent, scope, info);
@ -33,12 +35,12 @@ export default class AwaitBlock extends Node {
if (this.then_node) { if (this.then_node) {
this.then_contexts = []; this.then_contexts = [];
unpack_destructuring({ contexts: this.then_contexts, node: info.value, scope, component }); unpack_destructuring({ contexts: this.then_contexts, node: info.value, scope, component, context_rest_properties: this.context_rest_properties });
} }
if (this.catch_node) { if (this.catch_node) {
this.catch_contexts = []; this.catch_contexts = [];
unpack_destructuring({ contexts: this.catch_contexts, node: info.error, scope, component }); unpack_destructuring({ contexts: this.catch_contexts, node: info.error, scope, component, context_rest_properties: this.context_rest_properties });
} }
this.pending = new PendingBlock(component, this, scope, info.pending); this.pending = new PendingBlock(component, this, scope, info.pending);

@ -10,6 +10,7 @@ import { extract_identifiers } from 'periscopic';
import is_reference, { NodeWithPropertyDefinition } from 'is-reference'; import is_reference, { NodeWithPropertyDefinition } from 'is-reference';
import get_object from '../utils/get_object'; import get_object from '../utils/get_object';
import compiler_errors from '../compiler_errors'; import compiler_errors from '../compiler_errors';
import { Node as ESTreeNode } from 'estree';
const allowed_parents = new Set(['EachBlock', 'CatchBlock', 'ThenBlock', 'InlineComponent', 'SlotTemplate', 'IfBlock', 'ElseBlock']); const allowed_parents = new Set(['EachBlock', 'CatchBlock', 'ThenBlock', 'InlineComponent', 'SlotTemplate', 'IfBlock', 'ElseBlock']);
@ -19,6 +20,7 @@ export default class ConstTag extends Node {
contexts: Context[] = []; contexts: Context[] = [];
node: ConstTagType; node: ConstTagType;
scope: TemplateScope; scope: TemplateScope;
context_rest_properties: Map<string, ESTreeNode> = new Map();
assignees: Set<string> = new Set(); assignees: Set<string> = new Set();
dependencies: Set<string> = new Set(); dependencies: Set<string> = new Set();
@ -58,7 +60,8 @@ export default class ConstTag extends Node {
contexts: this.contexts, contexts: this.contexts,
node: this.node.expression.left, node: this.node.expression.left,
scope: this.scope, scope: this.scope,
component: this.component component: this.component,
context_rest_properties: this.context_rest_properties
}); });
this.expression = new Expression(this.component, this, this.scope, this.node.expression.right); this.expression = new Expression(this.component, this, this.scope, this.node.expression.right);
this.contexts.forEach(context => { this.contexts.forEach(context => {

@ -5,7 +5,7 @@ import AbstractBlock from './shared/AbstractBlock';
import Element from './Element'; import Element from './Element';
import ConstTag from './ConstTag'; import ConstTag from './ConstTag';
import { Context, unpack_destructuring } from './shared/Context'; import { Context, unpack_destructuring } from './shared/Context';
import { Node, Identifier } from 'estree'; import { Node } from 'estree';
import Component from '../Component'; import Component from '../Component';
import { TemplateNode } from '../../interfaces'; import { TemplateNode } from '../../interfaces';
import compiler_errors from '../compiler_errors'; import compiler_errors from '../compiler_errors';
@ -42,15 +42,8 @@ export default class EachBlock extends AbstractBlock {
this.scope = scope.child(); this.scope = scope.child();
this.context_rest_properties = new Map(); this.context_rest_properties = new Map();
this.contexts = []; this.contexts = [];
unpack_destructuring({ contexts: this.contexts, node: info.context, scope, component }); unpack_destructuring({ contexts: this.contexts, node: info.context, scope, component, context_rest_properties: this.context_rest_properties });
if (this.context_node.type === 'ObjectPattern') {
this.context_node.properties.forEach(i => {
if (i.type === 'RestElement') {
this.context_rest_properties.set((i.argument as Identifier).name, i);
}
});
}
this.contexts.forEach(context => { this.contexts.forEach(context => {
this.scope.add(context.key.name, this.expression.dependencies, this); this.scope.add(context.key.name, this.expression.dependencies, this);
}); });

@ -20,7 +20,8 @@ export function unpack_destructuring({
modifier = (node) => node, modifier = (node) => node,
default_modifier = (node) => node, default_modifier = (node) => node,
scope, scope,
component component,
context_rest_properties
}: { }: {
contexts: Context[]; contexts: Context[];
node: Node; node: Node;
@ -28,6 +29,7 @@ export function unpack_destructuring({
default_modifier?: Context['default_modifier']; default_modifier?: Context['default_modifier'];
scope: TemplateScope; scope: TemplateScope;
component: Component; component: Component;
context_rest_properties: Map<string, Node>;
}) { }) {
if (!node) return; if (!node) return;
@ -43,6 +45,7 @@ export function unpack_destructuring({
modifier, modifier,
default_modifier default_modifier
}); });
context_rest_properties.set((node.argument as Identifier).name, node);
} else if (node.type === 'ArrayPattern') { } else if (node.type === 'ArrayPattern') {
node.elements.forEach((element, i) => { node.elements.forEach((element, i) => {
if (element && element.type === 'RestElement') { if (element && element.type === 'RestElement') {
@ -52,8 +55,10 @@ export function unpack_destructuring({
modifier: (node) => x`${modifier(node)}.slice(${i})` as Node, modifier: (node) => x`${modifier(node)}.slice(${i})` as Node,
default_modifier, default_modifier,
scope, scope,
component component,
context_rest_properties
}); });
context_rest_properties.set((element.argument as Identifier).name, element);
} else if (element && element.type === 'AssignmentPattern') { } else if (element && element.type === 'AssignmentPattern') {
const n = contexts.length; const n = contexts.length;
mark_referenced(element.right, scope, component); mark_referenced(element.right, scope, component);
@ -70,7 +75,8 @@ export function unpack_destructuring({
to_ctx to_ctx
)}` as Node, )}` as Node,
scope, scope,
component component,
context_rest_properties
}); });
} else { } else {
unpack_destructuring({ unpack_destructuring({
@ -79,7 +85,8 @@ export function unpack_destructuring({
modifier: (node) => x`${modifier(node)}[${i}]` as Node, modifier: (node) => x`${modifier(node)}[${i}]` as Node,
default_modifier, default_modifier,
scope, scope,
component component,
context_rest_properties
}); });
} }
}); });
@ -97,8 +104,10 @@ export function unpack_destructuring({
)}, [${used_properties}])` as Node, )}, [${used_properties}])` as Node,
default_modifier, default_modifier,
scope, scope,
component component,
context_rest_properties
}); });
context_rest_properties.set((property.argument as Identifier).name, property);
} else { } else {
const key = property.key as Identifier; const key = property.key as Identifier;
const value = property.value; const value = property.value;
@ -121,7 +130,8 @@ export function unpack_destructuring({
to_ctx to_ctx
)}` as Node, )}` as Node,
scope, scope,
component component,
context_rest_properties
}); });
} else { } else {
unpack_destructuring({ unpack_destructuring({
@ -130,7 +140,8 @@ export function unpack_destructuring({
modifier: (node) => x`${modifier(node)}.${key.name}` as Node, modifier: (node) => x`${modifier(node)}.${key.name}` as Node,
default_modifier, default_modifier,
scope, scope,
component component,
context_rest_properties
}); });
} }
} }

@ -0,0 +1,11 @@
<script>
let objArray = [
[1, 2, 3, "4"],
[5, 6, 7, "8"],
];
</script>
{#each objArray as [id, ...rest] (id)}
<input bind:value={rest[0]} type="text" placeholder={rest[2]} />
<br />
{/each}

@ -0,0 +1,9 @@
[
{
"code": "invalid-rest-eachblock-binding",
"message": "...rest operator will create a new object and binding propogation with original object will not work",
"pos": 102,
"start": { "line": 8, "column": 24, "character": 102 },
"end": { "line": 8, "column": 31, "character": 109 }
}
]

@ -0,0 +1,8 @@
<script>
let objArray = [{ bar: {foo: '1', id: 0, innerValue: "test"} }, { bar: {foo: '2', id:1, innerValue: "Somethin"} }]
</script>
{#each objArray as { bar: { id, ...rest } } (id)}
<input bind:value={rest.innerValue} type="text" placeholder={rest.foo}/>
<br/>
{/each}

@ -0,0 +1,9 @@
[
{
"code": "invalid-rest-eachblock-binding",
"message": "...rest operator will create a new object and binding propogation with original object will not work",
"pos": 168,
"start": { "line": 5, "column": 32, "character": 168 },
"end": { "line": 5, "column": 39, "character": 175 }
}
]
Loading…
Cancel
Save