pull/4548/head
Tan Li Hau 6 years ago
parent 968dc8d58e
commit 485d1b0d9e

@ -7,7 +7,7 @@ import { Pattern } from 'estree';
import Component from '../Component'; import Component from '../Component';
import TemplateScope from './shared/TemplateScope'; import TemplateScope from './shared/TemplateScope';
import { TemplateNode } from '../../interfaces'; import { TemplateNode } from '../../interfaces';
import get_object from '../utils/get_object'; import traverse_destructure_pattern from '../utils/traverse_destructure_pattern';
export default class AwaitBlock extends Node { export default class AwaitBlock extends Node {
type: 'AwaitBlock'; type: 'AwaitBlock';
@ -40,38 +40,8 @@ export class DestructurePattern {
constructor(pattern: Pattern) { constructor(pattern: Pattern) {
this.pattern = pattern; this.pattern = pattern;
this.expressions = get_context_from_expression(this.pattern, []); this.expressions = [];
traverse_destructure_pattern(pattern, (node) => this.expressions.push(node.name));
this.identifier_name = this.pattern.type === 'Identifier' ? this.pattern.name : undefined; this.identifier_name = this.pattern.type === 'Identifier' ? this.pattern.name : undefined;
} }
} }
function get_context_from_expression(node: Pattern, result: string[]): string[] {
switch (node.type) {
case 'Identifier':
result.push(node.name);
return result;
case 'ArrayPattern':
for (const element of node.elements) {
get_context_from_expression(element, result);
}
return result;
case 'ObjectPattern':
for (const property of node.properties) {
if (property.type === 'Property') {
get_context_from_expression(property.value, result);
} else {
get_context_from_expression(property, result);
}
}
return result;
case 'MemberExpression':
get_context_from_expression(get_object(node), result);
return result;
case 'RestElement':
get_context_from_expression(node.argument, result);
return result;
case 'AssignmentPattern':
get_context_from_expression(node.left, result);
return result;
}
}

@ -8,7 +8,8 @@ import FragmentWrapper from './Fragment';
import PendingBlock from '../../nodes/PendingBlock'; import PendingBlock from '../../nodes/PendingBlock';
import ThenBlock from '../../nodes/ThenBlock'; import ThenBlock from '../../nodes/ThenBlock';
import CatchBlock from '../../nodes/CatchBlock'; import CatchBlock from '../../nodes/CatchBlock';
import { Identifier, Pattern } from 'estree'; import { Identifier } from 'estree';
import traverse_destructure_pattern from '../../utils/traverse_destructure_pattern';
class AwaitBlockBranch extends Wrapper { class AwaitBlockBranch extends Wrapper {
node: PendingBlock | ThenBlock | CatchBlock; node: PendingBlock | ThenBlock | CatchBlock;
@ -53,7 +54,10 @@ class AwaitBlockBranch extends Wrapper {
render_destructure(block: Block, value, node, index) { render_destructure(block: Block, value, node, index) {
if (value && node.pattern.type !== 'Identifier') { if (value && node.pattern.type !== 'Identifier') {
replace_context(block, node.pattern); traverse_destructure_pattern(node.pattern, (node, parent, index) => {
parent[index] = x`#ctx[${block.renderer.context_lookup.get(node.name).index}]`;
});
this.block.chunks.declarations.push(b`(${node.pattern} = #ctx[${index}])`); this.block.chunks.declarations.push(b`(${node.pattern} = #ctx[${index}])`);
if (this.block.has_update_method) { if (this.block.has_update_method) {
this.block.chunks.update.push(b`(${node.pattern} = #ctx[${index}])`); this.block.chunks.update.push(b`(${node.pattern} = #ctx[${index}])`);
@ -271,52 +275,3 @@ export default class AwaitBlockWrapper extends Wrapper {
this.catch.render_destructure(block, this.error, this.node.error, error_index); this.catch.render_destructure(block, this.error, this.node.error, error_index);
} }
} }
function replace_context(block: Block, pattern: Pattern) {
if (pattern.type === 'ObjectPattern') {
for (const property of pattern.properties) {
if (property.type === 'Property') {
if (property.value.type === 'Identifier') {
// @ts-ignore
property.value = x`#ctx[${block.renderer.context_lookup.get(property.value.name).index}]`;
} else {
replace_context(block, property.value);
}
} else {
// @ts-ignore
replace_context(block, property);
}
}
} else if (pattern.type === 'ArrayPattern') {
for (let i=0; i<pattern.elements.length; i++) {
const element = pattern.elements[i];
if (element.type === 'Identifier') {
// @ts-ignore
pattern.elements[i] = x`#ctx[${block.renderer.context_lookup.get(element.name).index}]`;
} else {
replace_context(block, element);
}
}
} else if (pattern.type === 'RestElement') {
if (pattern.argument.type === 'Identifier') {
// @ts-ignore
pattern.argument = x`#ctx[${block.renderer.context_lookup.get(pattern.argument.name).index}]`;
} else {
replace_context(block, pattern.argument);
}
} else if (pattern.type === 'AssignmentPattern') {
if (pattern.left.type === 'Identifier') {
// @ts-ignore
pattern.left = x`#ctx[${block.renderer.context_lookup.get(pattern.left.name).index}]`;
} else {
replace_context(block, pattern.left);
}
} else if (pattern.type === 'MemberExpression') {
if (pattern.object.type === 'Identifier') {
pattern.object = x`#ctx[${block.renderer.context_lookup.get(pattern.object.name).index}]`;
} else {
// @ts-ignore
replace_context(block, pattern.object);
}
}
}

@ -0,0 +1,35 @@
import { Pattern, Identifier, RestElement } from "estree";
import { Node } from "acorn";
export default function traverse_destructure_pattern(
node: Pattern,
callback: (node: Identifier, parent: Node, key: string | number) => void
) {
function traverse(node: Pattern, parent, key) {
switch (node.type) {
case "Identifier":
return callback(node, parent, key);
case "ArrayPattern":
for (let i = 0; i < node.elements.length; i++) {
const element = node.elements[i];
traverse(element, node.elements, i);
}
break;
case "ObjectPattern":
for (let i = 0; i < node.properties.length; i++) {
const property = node.properties[i];
if (property.type === "Property") {
traverse(property.value, property, "value");
} else {
traverse((property as any) as RestElement, node.properties, i);
}
}
break;
case "RestElement":
return traverse(node.argument, node, 'argument');
case "AssignmentPattern":
return traverse(node.left, node, 'left');
}
}
traverse(node, null, null);
}

@ -92,7 +92,7 @@ export class Parser {
}, err.pos); }, err.pos);
} }
error({ code, message }: { code: string; message: string }, index = this.index): never { error({ code, message }: { code: string; message: string }, index = this.index) {
error(message, { error(message, {
name: 'ParseError', name: 'ParseError',
code, code,

Loading…
Cancel
Save