pull/3539/head
Richard Harris 6 years ago
parent 3f2f1b1dbd
commit 9d60236f32

@ -68,8 +68,6 @@ export default class Component {
var_lookup: Map<string, Var> = new Map(); var_lookup: Map<string, Var> = new Map();
imports: ImportDeclaration[] = []; imports: ImportDeclaration[] = [];
module_javascript: string;
javascript: string;
hoistable_nodes: Set<Node> = new Set(); hoistable_nodes: Set<Node> = new Set();
node_for_declaration: Map<string, Node> = new Map(); node_for_declaration: Map<string, Node> = new Map();
@ -530,7 +528,10 @@ export default class Component {
} }
extract_javascript(script) { extract_javascript(script) {
const nodes_to_include = script.content.body.filter(node => { if (!script) return null;
return script.content.body.filter(node => {
if (!node) return false;
if (this.hoistable_nodes.has(node)) return false; if (this.hoistable_nodes.has(node)) return false;
if (this.reactive_declaration_nodes.has(node)) return false; if (this.reactive_declaration_nodes.has(node)) return false;
if (node.type === 'ImportDeclaration') return false; if (node.type === 'ImportDeclaration') return false;
@ -538,38 +539,6 @@ export default class Component {
return false; return false;
return true; return true;
}); });
return nodes_to_include;
if (nodes_to_include.length === 0) return null;
let a = script.content.start;
while (/\s/.test(this.source[a])) a += 1;
// let b = a;
// let result = '';
// script.content.body.forEach(node => {
// if (
// this.hoistable_nodes.has(node) ||
// this.reactive_declaration_nodes.has(node)
// ) {
// if (a !== b) result += `[✂${a}-${b}✂]`;
// a = node.end;
// }
// b = node.end;
// });
// while (/\s/.test(this.source[a - 1])) a -= 1;
// b = script.content.end;
// while (/\s/.test(this.source[b - 1])) b -= 1;
// if (a < b) result += `[✂${a}-${b}✂]`;
// return result || null;
} }
walk_module_js() { walk_module_js() {
@ -625,7 +594,6 @@ export default class Component {
this.extract_imports(script.content); this.extract_imports(script.content);
this.extract_exports(script.content); this.extract_exports(script.content);
this.module_javascript = this.extract_javascript(script);
} }
walk_instance_js_pre_template() { walk_instance_js_pre_template() {
@ -728,7 +696,6 @@ export default class Component {
this.hoist_instance_declarations(); this.hoist_instance_declarations();
this.extract_reactive_declarations(); this.extract_reactive_declarations();
this.extract_reactive_store_references(); this.extract_reactive_store_references();
this.javascript = this.extract_javascript(script);
} }
// TODO merge this with other walks that are independent // TODO merge this with other walks that are independent
@ -812,7 +779,7 @@ export default class Component {
const variable = this.var_lookup.get(name); const variable = this.var_lookup.get(name);
if (variable && (variable.subscribable && variable.reassigned)) { if (variable && (variable.subscribable && variable.reassigned)) {
return x`$$subscribe_${name}($$invalidate('${name}', ${value || name}))`; return x`${`$$subscribe_${name}`}($$invalidate('${name}', ${value || name}))`;
} }
if (name[0] === '$' && name[1] !== '$') { if (name[0] === '$' && name[1] !== '$') {
@ -850,7 +817,7 @@ export default class Component {
return Array.from(deps).map(n => x`$$invalidate('${n}', ${n})`); return Array.from(deps).map(n => x`$$invalidate('${n}', ${n})`);
} }
rewrite_props(_get_insert: (variable: Var) => string) { rewrite_props(get_insert: (variable: Var) => Node[]) {
// TODO // TODO
const component = this; const component = this;
@ -858,7 +825,7 @@ export default class Component {
let scope = instance_scope; let scope = instance_scope;
walk(this.ast.instance.content, { walk(this.ast.instance.content, {
enter(node) { enter(node, parent, key, index) {
if (/Function/.test(node.type)) { if (/Function/.test(node.type)) {
return this.skip(); return this.skip();
} }
@ -896,9 +863,11 @@ export default class Component {
const variable = component.var_lookup.get(name); const variable = component.var_lookup.get(name);
if (variable.export_name) { if (variable.export_name) {
// const insert = variable.subscribable const insert = variable.subscribable
// ? get_insert(variable) ? get_insert(variable)
// : null; : null;
parent[key].splice(index + 1, 0, insert);
declarator.id = { declarator.id = {
type: 'ObjectPattern', type: 'ObjectPattern',
@ -920,6 +889,9 @@ export default class Component {
}; };
declarator.init = x`$$props`; declarator.init = x`$$props`;
} else if (variable.subscribable) {
const insert = get_insert(variable);
parent[key].splice(index + 1, 0, ...insert);
} }
}); });
} }

@ -163,7 +163,7 @@ export default function dom(
const { ctx } = this.$$; const { ctx } = this.$$;
const props = ${options.customElement ? `this.attributes` : `options.props || {}`}; const props = ${options.customElement ? `this.attributes` : `options.props || {}`};
${expected.map(prop => b` ${expected.map(prop => b`
if (ctx.${prop.name} === undefined && !('${prop.export_name}' in props)) { if (#ctx.${prop.name} === undefined && !('${prop.export_name}' in props)) {
@_console.warn("<${component.tag}> was created without expected prop '${prop.export_name}'"); @_console.warn("<${component.tag}> was created without expected prop '${prop.export_name}'");
}`)} }`)}
`; `;
@ -182,7 +182,7 @@ export default function dom(
const writable_vars = component.vars.filter(variable => !variable.module && variable.writable); const writable_vars = component.vars.filter(variable => !variable.module && variable.writable);
inject_state = (uses_props || writable_vars.length > 0) ? x` inject_state = (uses_props || writable_vars.length > 0) ? x`
${$$props} => { ${$$props} => {
${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)} ${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)}
${writable_vars.map(prop => b` ${writable_vars.map(prop => b`
if ('${prop.name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.name}`)}; if ('${prop.name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.name}`)};
`)} `)}
@ -226,18 +226,17 @@ export default function dom(
component.rewrite_props(({ name, reassigned }) => { component.rewrite_props(({ name, reassigned }) => {
const value = `$${name}`; const value = `$${name}`;
const callback = `$value => { ${value} = $$value; $$invalidate('${value}', ${value}) }`;
if (reassigned) { if (reassigned) {
return `$$subscribe_${name}()`; return b`${`$$subscribe_${name}`}()`;
} }
const component_subscribe = component.helper('component_subscribe'); const component_subscribe = component.helper('component_subscribe');
const callback = x`$$value => { ${value} = $$value; $$invalidate('${value}', ${value}) }`;
let insert = `${component_subscribe}($$self, ${name}, $${callback})`; let insert = b`${component_subscribe}($$self, ${name}, $${callback})`;
if (component.compile_options.dev) { if (component.compile_options.dev) {
const validate_store = component.helper('validate_store'); const validate_store = component.helper('validate_store');
insert = `${validate_store}(${name}, '${name}'); ${insert}`; insert = b`${validate_store}(${name}, '${name}'); ${insert}`;
} }
return insert; return insert;
@ -254,7 +253,7 @@ export default function dom(
${block.get_contents()} ${block.get_contents()}
} }
${component.module_javascript} ${component.extract_javascript(component.ast.module)}
${component.fully_hoisted} ${component.fully_hoisted}
`); `);
@ -283,8 +282,10 @@ export default function dom(
filtered_declarations.push(p`$$binding_groups`); filtered_declarations.push(p`$$binding_groups`);
} }
const instance_javascript = component.extract_javascript(component.ast.instance);
const has_definition = ( const has_definition = (
component.javascript || instance_javascript ||
filtered_props.length > 0 || filtered_props.length > 0 ||
uses_props || uses_props ||
component.partly_hoisted.length > 0 || component.partly_hoisted.length > 0 ||
@ -316,7 +317,7 @@ export default function dom(
const variable = component.var_lookup.get(store.name.slice(1)); const variable = component.var_lookup.get(store.name.slice(1));
return variable && variable.reassigned; return variable && variable.reassigned;
}) })
.map(({ name }) => `$$self.$$.on_destroy.push(() => $$unsubscribe_${name.slice(1)}());`); .map(({ name }) => b`$$self.$$.on_destroy.push(() => ${`$$unsubscribe_${name.slice(1)}`}());`);
if (has_definition) { if (has_definition) {
const reactive_declarations: (Node | Node[]) = []; const reactive_declarations: (Node | Node[]) = [];
@ -355,7 +356,9 @@ 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 b`let ${$name}, $$unsubscribe_${name} = @noop, $$subscribe_${name} = () => ($$unsubscribe_${name}(), $$unsubscribe_${name} = @subscribe(${name}, $$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }), ${name})`; const unsubscribe = `$$unsubscribe_${name}`;
const subscribe = `$$subscribe_${name}`;
return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }), ${name})`;
} }
return b`let ${$name};`; return b`let ${$name};`;
@ -396,7 +399,7 @@ export default function dom(
${resubscribable_reactive_store_unsubscribers} ${resubscribable_reactive_store_unsubscribers}
${component.javascript} ${instance_javascript}
${unknown_props_check} ${unknown_props_check}

@ -529,7 +529,7 @@ export default class EachBlockWrapper extends Wrapper {
`; `;
} else { } else {
remove_old_blocks = b` remove_old_blocks = b`
for (${this.block.has_update_method ? `` : `#i = ${data_length}`}; #i < ${this.block.has_update_method ? view_length : '#old_length'}; #i += 1) { for (${this.block.has_update_method ? `` : x`#i = ${data_length}`}; #i < ${this.block.has_update_method ? view_length : '#old_length'}; #i += 1) {
${iterations}[#i].d(1); ${iterations}[#i].d(1);
} }
${!fixed_length && b`${view_length} = ${data_length};`} ${!fixed_length && b`${view_length} = ${data_length};`}

@ -41,24 +41,24 @@ export default function ssr(
// TODO remove this, just use component.vars everywhere // TODO remove this, just use component.vars everywhere
const props = component.vars.filter(variable => !variable.module && variable.export_name); const props = component.vars.filter(variable => !variable.module && variable.export_name);
if (component.javascript) {
component.rewrite_props(({ name }) => { component.rewrite_props(({ name }) => {
const value = `$${name}`; const value = `$${name}`;
const get_store_value = component.helper('get_store_value'); const get_store_value = component.helper('get_store_value');
let insert = `${value} = ${get_store_value}(${name})`; let insert = b`${value} = ${get_store_value}(${name})`;
if (component.compile_options.dev) { if (component.compile_options.dev) {
const validate_store = component.helper('validate_store'); const validate_store = component.helper('validate_store');
insert = `${validate_store}(${name}, '${name}'); ${insert}`; insert = b`${validate_store}(${name}, '${name}'); ${insert}`;
} }
return insert; return insert;
}); });
}
const instance_javascript = component.extract_javascript(component.ast.instance);
// TODO only do this for props with a default value // TODO only do this for props with a default value
const parent_bindings = component.javascript const parent_bindings = instance_javascript
? props.map(prop => { ? props.map(prop => {
return `if ($$props.${prop.export_name} === void 0 && $$bindings.${prop.export_name} && ${prop.name} !== void 0) $$bindings.${prop.export_name}(${prop.name});`; return `if ($$props.${prop.export_name} === void 0 && $$bindings.${prop.export_name} && ${prop.name} !== void 0) $$bindings.${prop.export_name}(${prop.name});`;
}) })
@ -129,7 +129,7 @@ export default function ssr(
return name; return name;
}) })
.join(', ')};`, .join(', ')};`,
component.javascript, instance_javascript,
parent_bindings.join('\n'), parent_bindings.join('\n'),
css.code && `$$result.css.add(#css);`, css.code && `$$result.css.add(#css);`,
main main
@ -142,7 +142,7 @@ export default function ssr(
map: ${css.map ? stringify(css.map.toString()) : 'null'} map: ${css.map ? stringify(css.map.toString()) : 'null'}
};`} };`}
${component.module_javascript} ${component.extract_javascript(component.ast.module)}
${component.fully_hoisted} ${component.fully_hoisted}

@ -30,21 +30,9 @@ export function invalidate(component: Component, scope: Scope, node: Node, names
if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) { if (node.type === 'AssignmentExpression' && node.operator === '=' && nodes_match(node.left, node.right) && tail.length === 0) {
return component.invalidate(head); return component.invalidate(head);
} else { } else {
let callee = head[0] === '$' ? `@set_store_value` : `$$invalidate`;
// TODO stores const variable = component.var_lookup.get(head);
// if (head[0] === '$') {
// code.prependRight(node.start, `${component.helper('set_store_value')}(${head.slice(1)}, `);
// } else {
// let prefix = `$$invalidate`;
// const variable = component.var_lookup.get(head);
// if (variable.subscribable && variable.reassigned) {
// prefix = `$$subscribe_${head}($$invalidate`;
// suffix += `)`;
// }
// code.prependRight(node.start, `${prefix}('${head}', `);
// }
const extra_args = tail.map(name => component.invalidate(name)); const extra_args = tail.map(name => component.invalidate(name));
@ -61,7 +49,14 @@ export function invalidate(component: Component, scope: Scope, node: Node, names
}); });
} }
return x`$$invalidate("${head}", ${node}, ${extra_args})`; let invalidate = x`${callee}("${head}", ${node}, ${extra_args})`;
if (variable.subscribable && variable.reassigned) {
const subscribe = `$$subscribe_${head}`;
invalidate = x`${subscribe}(${invalidate})}`;
}
return invalidate;
} }
} }

Loading…
Cancel
Save