pull/3539/head
Richard Harris 6 years ago
parent e12a30ae50
commit 9e1bc908d3

@ -201,7 +201,7 @@ export default class Element extends Node {
this.scope = scope.child(); this.scope = scope.child();
this.lets.forEach(l => { this.lets.forEach(l => {
const dependencies = new Set([l.name]); const dependencies = new Set([l.name.name]);
l.names.forEach(name => { l.names.forEach(name => {
this.scope.add(name, dependencies, this); this.scope.add(name, dependencies, this);

@ -90,7 +90,7 @@ export default class InlineComponent extends Node {
this.scope = scope.child(); this.scope = scope.child();
this.lets.forEach(l => { this.lets.forEach(l => {
const dependencies = new Set([l.name]); const dependencies = new Set([l.name.name]);
l.names.forEach(name => { l.names.forEach(name => {
this.scope.add(name, dependencies, this); this.scope.add(name, dependencies, this);

@ -1,20 +1,21 @@
import Node from './shared/Node'; import Node from './shared/Node';
import Component from '../Component'; import Component from '../Component';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import { Identifier } from 'estree';
const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']); const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']);
export default class Let extends Node { export default class Let extends Node {
type: 'Let'; type: 'Let';
name: string; name: Identifier;
value: string; value: Identifier;
names: string[] = []; names: string[] = [];
constructor(component: Component, parent, scope, info) { constructor(component: Component, parent, scope, info) {
super(component, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = { type: 'Identifier', name: info.name };
this.value = info.expression && `[✂${info.expression.start}-${info.expression.end}✂]`; this.value = info.expression.node;
if (info.expression) { if (info.expression) {
walk(info.expression, { walk(info.expression, {
@ -32,7 +33,7 @@ export default class Let extends Node {
} }
}); });
} else { } else {
this.names.push(this.name); this.names.push(this.name.name);
} }
} }
} }

@ -244,9 +244,9 @@ export default function dom(
}); });
} }
const args = ['$$self']; const args = [x`$$self`];
if (props.length > 0 || component.has_reactive_assignments || component.slots.size > 0) { if (props.length > 0 || component.has_reactive_assignments || component.slots.size > 0) {
args.push('$$props', '$$invalidate'); args.push(x`$$props`, x`$$invalidate`);
} }
body.push(b` body.push(b`
@ -355,10 +355,10 @@ export default function dom(
const store = component.var_lookup.get(name); const store = component.var_lookup.get(name);
if (store && store.reassigned) { if (store && store.reassigned) {
return `${$name}, $$unsubscribe_${name} = @noop, $$subscribe_${name} = () => ($$unsubscribe_${name}(), $$unsubscribe_${name} = @subscribe(${name}, $$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }), ${name})`; return b`let ${$name}, $$unsubscribe_${name} = @noop, $$subscribe_${name} = () => ($$unsubscribe_${name}(), $$unsubscribe_${name} = @subscribe(${name}, $$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }), ${name})`;
} }
return $name; return b`let ${$name};`;
}); });
let unknown_props_check; let unknown_props_check;
@ -389,8 +389,8 @@ export default function dom(
}; };
body.push(b` body.push(b`
function ${definition}(${args.join(', ')}) { function ${definition}(${args}) {
${reactive_store_declarations.length > 0 && `let ${reactive_store_declarations.join(', ')};`} ${reactive_store_declarations}
${reactive_store_subscriptions} ${reactive_store_subscriptions}
@ -400,7 +400,7 @@ export default function dom(
${unknown_props_check} ${unknown_props_check}
${component.slots.size && x`let { $$slots = {}, $$scope } = $$props;`} ${component.slots.size && b`let { $$slots = {}, $$scope } = $$props;`}
${renderer.binding_groups.length > 0 && `const $$binding_groups = [${renderer.binding_groups.map(_ => `[]`).join(', ')}];`} ${renderer.binding_groups.length > 0 && `const $$binding_groups = [${renderer.binding_groups.map(_ => `[]`).join(', ')}];`}

@ -19,7 +19,7 @@ import { Node, Identifier, Expression } from 'estree';
export default class InlineComponentWrapper extends Wrapper { export default class InlineComponentWrapper extends Wrapper {
var: Identifier; var: Identifier;
slots: Map<string, { block: Block; scope: TemplateScope; fn?: string }> = new Map(); slots: Map<string, { block: Block; scope: TemplateScope; fn?: Node }> = new Map();
node: InlineComponent; node: InlineComponent;
fragment: FragmentWrapper; fragment: FragmentWrapper;

@ -3,14 +3,13 @@ import Renderer from '../Renderer';
import Block from '../Block'; import Block from '../Block';
import Slot from '../../nodes/Slot'; import Slot from '../../nodes/Slot';
import FragmentWrapper from './Fragment'; import FragmentWrapper from './Fragment';
import { b } from 'code-red'; import { b, p, x } from 'code-red';
import { sanitize } from '../../../utils/names'; import { sanitize } from '../../../utils/names';
import add_to_set from '../../utils/add_to_set'; import add_to_set from '../../utils/add_to_set';
import get_slot_data from '../../utils/get_slot_data'; import get_slot_data from '../../utils/get_slot_data';
import { stringify_props } from '../../utils/stringify_props';
import Expression from '../../nodes/shared/Expression'; import Expression from '../../nodes/shared/Expression';
import is_dynamic from './shared/is_dynamic'; import is_dynamic from './shared/is_dynamic';
import { Identifier } from 'estree'; import { Identifier, ObjectExpression } from 'estree';
import { changed } from './shared/changed'; import { changed } from './shared/changed';
export default class SlotWrapper extends Wrapper { export default class SlotWrapper extends Wrapper {
@ -67,8 +66,8 @@ export default class SlotWrapper extends Wrapper {
get_slot_changes = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_changes`); get_slot_changes = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_changes`);
get_slot_context = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_context`); get_slot_context = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_context`);
const context_props = get_slot_data(this.node.values, false); const context = get_slot_data(this.node.values, false);
const changes_props = []; const changes = x`{}` as ObjectExpression;
const dependencies = new Set(); const dependencies = new Set();
@ -92,15 +91,22 @@ export default class SlotWrapper extends Wrapper {
}); });
if (dynamic_dependencies.length > 0) { if (dynamic_dependencies.length > 0) {
changes_props.push(`${attribute.name}: ${dynamic_dependencies.join(' || ')}`); const expression = dynamic_dependencies
.map(name => ({ type: 'Identifier', name } as any))
.reduce((lhs, rhs) => x`${lhs} || ${rhs}`);
changes.properties.push(p`${attribute.name}: ${expression}`);
} }
}); });
const arg = dependencies.size > 0 ? `{ ${Array.from(dependencies).join(', ')} }` : ''; const arg = dependencies.size > 0 && {
type: 'ObjectPattern',
properties: Array.from(dependencies).map(name => p`${name}`)
};
renderer.blocks.push(b` renderer.blocks.push(b`
const ${get_slot_changes} = (${arg}) => (${stringify_props(changes_props)}); const ${get_slot_changes} = (${arg}) => (${changes});
const ${get_slot_context} = (${arg}) => (${stringify_props(context_props)}); const ${get_slot_context} = (${arg}) => (${context});
`); `);
} else { } else {
get_slot_changes = 'null'; get_slot_changes = 'null';
@ -167,7 +173,7 @@ export default class SlotWrapper extends Wrapper {
block.chunks.update.push(b` block.chunks.update.push(b`
if (${slot} && ${slot}.p && ${changed(dynamic_dependencies)}) { if (${slot} && ${slot}.p && ${changed(dynamic_dependencies)}) {
${slot}.p( ${slot}.p(
@get_slot_changes(${slot_definition}, #ctx, changed, ${get_slot_changes}), @get_slot_changes(${slot_definition}, #ctx, #changed, ${get_slot_changes}),
@get_slot_context(${slot_definition}, #ctx, ${get_slot_context}) @get_slot_context(${slot_definition}, #ctx, ${get_slot_context})
); );
} }

@ -1,9 +1,20 @@
import Let from '../../../nodes/Let'; import Let from '../../../nodes/Let';
import { x } from 'code-red';
export function get_context_merger(lets: Let[]) { export function get_context_merger(lets: Let[]) {
if (lets.length === 0) return null; if (lets.length === 0) return null;
const input = lets.map(l => l.value ? `${l.name}: ${l.value}` : l.name).join(', '); console.log(lets);
const input = {
type: 'ObjectPattern',
properties: lets.map(l => ({
type: 'Property',
kind: 'init',
key: l.name,
value: l.value || l.name
}))
};
const names = new Set(); const names = new Set();
lets.forEach(l => { lets.forEach(l => {
@ -12,7 +23,19 @@ export function get_context_merger(lets: Let[]) {
}); });
}); });
const output = Array.from(names).join(', '); const output = {
type: 'ObjectExpression',
properties: Array.from(names).map(name => {
const id = { type: 'Identifier', name };
return {
type: 'Property',
kind: 'init',
key: id,
value: id
};
})
};
return `({ ${input} }) => ({ ${output} })`; return x`(${input}) => (${output})`;
} }

@ -8,9 +8,7 @@ export default function(node: Slot, renderer: Renderer, options: RenderOptions)
const slot_data = get_slot_data(node.values, true); const slot_data = get_slot_data(node.values, true);
const arg = slot_data.length > 0 ? `{ ${slot_data.join(', ')} }` : '{}'; renderer.append(`\${$$slots${prop} ? $$slots${prop}(${slot_data}) : \``);
renderer.append(`\${$$slots${prop} ? $$slots${prop}(${arg}) : \``);
renderer.render(node.children, options); renderer.render(node.children, options);

@ -1,19 +1,43 @@
import { snip } from './snip';
import { stringify_attribute } from './stringify_attribute';
import Attribute from '../nodes/Attribute'; import Attribute from '../nodes/Attribute';
import { p, x } from 'code-red';
import { string_literal } from './stringify';
export default function get_slot_data(values: Map<string, Attribute>, is_ssr: boolean) { export default function get_slot_data(values: Map<string, Attribute>, is_ssr: boolean) {
return Array.from(values.values()) return {
.filter(attribute => attribute.name !== 'name') type: 'ObjectExpression',
.map(attribute => { properties: Array.from(values.values())
const value = attribute.is_true .filter(attribute => attribute.name !== 'name')
? 'true' .map(attribute => {
: attribute.chunks.length === 0 if (is_ssr) {
? '""' throw new Error(`TODO SSR`);
: attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text' }
? snip(attribute.chunks[0])
: '`' + stringify_attribute(attribute, is_ssr) + '`'; const value = get_value(attribute);
return `${attribute.name}: ${value}`; // const value = attribute.is_true
}); // ? x`true`
// : attribute.chunks.length === 0
// ? x`""`
// : attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text'
// ? snip(attribute.chunks[0])
// : '`' + stringify_attribute(attribute, is_ssr) + '`';
return p`${attribute.name}: ${value}`;
})
}
}
function get_value(attribute: Attribute) {
if (attribute.is_true) return x`true`;
if (attribute.chunks.length === 0) return x`""`;
let value = attribute.chunks
.map(chunk => chunk.type === 'Text' ? string_literal(chunk.data) : chunk.node)
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`);
if (attribute.chunks.length > 1 && attribute.chunks[0].type !== 'Text') {
value = x`"" + ${value}`;
}
return value;
} }
Loading…
Cancel
Save