unpack_destructuring gives nodes and property name instead of declaration function

pull/8386/head
Nguyen Tran 4 years ago
parent 8e3d500f84
commit 404893d33a

@ -1,20 +1,19 @@
import { b, x } from 'code-red'; import { x } from 'code-red';
import { Node, Identifier, Expression as ESTreeExpression } from 'estree'; import { Node, Identifier, Expression, PrivateIdentifier } from 'estree';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import is_reference, { NodeWithPropertyDefinition } from 'is-reference'; import is_reference, { NodeWithPropertyDefinition } from 'is-reference';
import { clone } from '../../../utils/clone'; import { clone } from '../../../utils/clone';
import Component from '../../Component'; import Component from '../../Component';
import Block from '../../render_dom/Block';
import flatten_reference from '../../utils/flatten_reference'; import flatten_reference from '../../utils/flatten_reference';
import { INode } from '../interfaces'; import { INode } from '../interfaces';
import Expression from './Expression';
import TemplateScope from './TemplateScope'; import TemplateScope from './TemplateScope';
export type Context = DestructuredVariable | ComputedProperty; export type Context = DestructuredVariable | ComputedProperty;
interface ComputedProperty { interface ComputedProperty {
type: 'ComputedProperty'; type: 'ComputedProperty';
declaration: (block: Block, scope: TemplateScope, ctx: string) => Node[]; property_name: string;
key: Expression | PrivateIdentifier;
} }
interface DestructuredVariable { interface DestructuredVariable {
@ -140,19 +139,18 @@ export function unpack_destructuring({
let new_modifier: (node: Node) => Node; let new_modifier: (node: Node) => Node;
if (property.computed) { if (property.computed) {
// TODO: If the property is computed, ie, { [computed_key]: prop }, the computed_key can be any type of expression. // e.g { [computedProperty]: ... }
const computed_property = `#computed_property_${number_of_computed_props}`; const property_name = `#computed_property_${number_of_computed_props}`;
new_modifier = (node) => x`${modifier(node)}[${computed_property}]`;
used_properties.push(x`${computed_property}`);
number_of_computed_props += 1; number_of_computed_props += 1;
contexts.push({ contexts.push({
type: 'ComputedProperty', type: 'ComputedProperty',
declaration: (block, scope, ctx) => { property_name,
const computed_expression = new Expression(component, owner, scope, key); key
return b`const ${computed_property} = ${computed_expression.manipulate(block, ctx)}`;
}
}); });
new_modifier = (node) => x`${modifier(node)}[${property_name}]`;
used_properties.push(x`${property_name}`);
} else if (key.type === 'Identifier') { } else if (key.type === 'Identifier') {
// e.g. { someProperty: ... } // e.g. { someProperty: ... }
const property_name = key.name; const property_name = key.name;
@ -210,7 +208,7 @@ export function unpack_destructuring({
function update_reference( function update_reference(
contexts: Context[], contexts: Context[],
n: number, n: number,
expression: ESTreeExpression, expression: Expression,
to_ctx: (name: string) => Node to_ctx: (name: string) => Node
): Node { ): Node {
const find_from_context = (node: Identifier) => { const find_from_context = (node: Identifier) => {
@ -231,7 +229,7 @@ function update_reference(
} }
// NOTE: avoid unnecessary deep clone? // NOTE: avoid unnecessary deep clone?
expression = clone(expression) as ESTreeExpression; expression = clone(expression) as Expression;
walk(expression, { walk(expression, {
enter(node, parent: Node) { enter(node, parent: Node) {
if ( if (

@ -11,6 +11,7 @@ import CatchBlock from '../../nodes/CatchBlock';
import { Context } from '../../nodes/shared/Context'; import { Context } from '../../nodes/shared/Context';
import { Identifier, Literal, Node } from 'estree'; import { Identifier, Literal, Node } from 'estree';
import { add_const_tags, add_const_tags_context } from './shared/add_const_tags'; import { add_const_tags, add_const_tags_context } from './shared/add_const_tags';
import Expression from '../../nodes/shared/Expression';
type Status = 'pending' | 'then' | 'catch'; type Status = 'pending' | 'then' | 'catch';
@ -101,7 +102,8 @@ class AwaitBlockBranch extends Wrapper {
const props = this.is_destructured ? this.value_contexts.map(prop => { const props = this.is_destructured ? this.value_contexts.map(prop => {
const to_ctx = name => this.renderer.reference(name); const to_ctx = name => this.renderer.reference(name);
if (prop.type === 'ComputedProperty') { if (prop.type === 'ComputedProperty') {
return prop.declaration(this.block, this.has_consts(this.node) ? this.node.scope : null, '#ctx'); const expression = new Expression(this.renderer.component, this.node, this.has_consts(this.node) ? this.node.scope : null, prop.key);
return b`const ${prop.property_name} = ${expression.manipulate(this.block, 'ctx')};`;
} else { } else {
return b`#ctx[${this.block.renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`#ctx[${this.value_index}]`), to_ctx)};`; return b`#ctx[${this.block.renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`#ctx[${this.value_index}]`), to_ctx)};`;
} }

@ -9,6 +9,7 @@ import ElseBlock from '../../nodes/ElseBlock';
import { Identifier, Node } from 'estree'; import { Identifier, Node } from 'estree';
import get_object from '../../utils/get_object'; import get_object from '../../utils/get_object';
import { add_const_tags, add_const_tags_context } from './shared/add_const_tags'; import { add_const_tags, add_const_tags_context } from './shared/add_const_tags';
import Expression from '../../nodes/shared/Expression';
export class ElseBlockWrapper extends Wrapper { export class ElseBlockWrapper extends Wrapper {
node: ElseBlock; node: ElseBlock;
@ -369,7 +370,8 @@ export default class EachBlockWrapper extends Wrapper {
if (prop.type === 'DestructuredVariable') { if (prop.type === 'DestructuredVariable') {
return b`child_ctx[${renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`list[i]`), to_ctx)};`; return b`child_ctx[${renderer.context_lookup.get(prop.key.name).index}] = ${prop.default_modifier(prop.modifier(x`list[i]`), to_ctx)};`;
} else { } else {
return prop.declaration(block, this.node.scope, 'child_ctx'); const expression = new Expression(this.renderer.component, this.node, this.node.scope, prop.key);
return b`const ${prop.property_name} = ${expression.manipulate(block, 'child_ctx')};`;
} }
}); });

@ -2,6 +2,7 @@ import ConstTag from '../../../nodes/ConstTag';
import Block from '../../Block'; import Block from '../../Block';
import { b, Node, x } from 'code-red'; import { b, Node, x } from 'code-red';
import Renderer from '../../Renderer'; import Renderer from '../../Renderer';
import Expression from '../../../nodes/shared/Expression';
export function add_const_tags(block: Block, const_tags: ConstTag[], ctx: string) { export function add_const_tags(block: Block, const_tags: ConstTag[], ctx: string) {
const const_tags_props = []; const const_tags_props = [];
@ -14,7 +15,8 @@ export function add_const_tags(block: Block, const_tags: ConstTag[], ctx: string
if (context.type === 'DestructuredVariable') { if (context.type === 'DestructuredVariable') {
const_tags_props.push(b`${ctx}[${block.renderer.context_lookup.get(context.key.name).index}] = ${context.default_modifier(context.modifier({ type: 'Identifier', name }), to_ctx)}`); const_tags_props.push(b`${ctx}[${block.renderer.context_lookup.get(context.key.name).index}] = ${context.default_modifier(context.modifier({ type: 'Identifier', name }), to_ctx)}`);
} else { } else {
const_tags_props.push(context.declaration(block, const_tag.scope, ctx)); const expression = new Expression(block.renderer.component, const_tag, const_tag.scope, context.key);
const_tags_props.push(b`const ${context.property_name} = ${expression.manipulate(block, ctx)}`);
} }
}); });
}); });

Loading…
Cancel
Save