diff --git a/src/compile/Component.ts b/src/compile/Component.ts index f277ab4bb0..957f257826 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -711,6 +711,10 @@ export default class Component { } } + if (node.type === 'ExportNamedDeclaration' && node.declaration && node.declaration.type === 'FunctionDeclaration') { + top_level_function_declarations.set(node.declaration.id.name, node); + } + if (node.type === 'FunctionDeclaration') { top_level_function_declarations.set(node.id.name, node); } @@ -720,6 +724,10 @@ export default class Component { let walking = new Set(); const is_hoistable = fn_declaration => { + if (fn_declaration.type === 'ExportNamedDeclaration') { + fn_declaration = fn_declaration.declaration; + } + const instance_scope = this.instance_scope; let scope = this.instance_scope; let map = this.instance_scope_map; diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index d54d37f1e8..1d7046f32b 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -98,11 +98,19 @@ export default function dom( let dev_props_check; component.props.forEach(x => { - body.push(deindent` - get ${x.as}() { - return this.$$.get().${x.name}; - } - `); + if (component.imported_declarations.has(x.name) || component.hoistable_names.has(x.name)) { + body.push(deindent` + get ${x.as}() { + return ${x.name}; + } + `); + } else { + body.push(deindent` + get ${x.as}() { + return this.$$.get().${x.name}; + } + `); + } if (component.writable_declarations.has(x.as) && !renderer.readonly.has(x.as)) { body.push(deindent` @@ -181,18 +189,23 @@ export default function dom( ${component.fully_hoisted.length > 0 && component.fully_hoisted.join('\n\n')} `); - const declarations = component.declarations.filter(name => { - if (component.props.find(p => p.as === name)) return true; + const filtered_declarations = component.declarations.filter(name => { if (component.hoistable_names.has(name)) return false; if (component.imported_declarations.has(name)) return false; + if (component.props.find(p => p.as === name)) return true; return component.template_references.has(name); }); + const filtered_props = component.props.filter(prop => { + if (component.hoistable_names.has(prop.name)) return false; + if (component.imported_declarations.has(prop.name)) return false; + }); + const has_definition = ( component.javascript || - component.props.length > 0 || + filtered_props.length > 0 || component.partly_hoisted.length > 0 || - declarations.length > 0 + filtered_declarations.length > 0 ); const definition = has_definition @@ -203,13 +216,13 @@ export default function dom( builder.addBlock(deindent` function ${definition}(${args.join(', ')}) { ${component.javascript || ( - component.props.length > 0 && - `let { ${component.props.map(x => x.name === x.as ? x.as : `${x.as}: ${x.name}`).join(', ')} } = $$props;` + filtered_props.length > 0 && + `let { ${filtered_props.map(x => x.name === x.as ? x.as : `${x.as}: ${x.name}`).join(', ')} } = $$props;` )} ${component.partly_hoisted.length > 0 && component.partly_hoisted.join('\n\n')} - ${declarations.length > 0 && `$$self.$$.get = () => (${stringifyProps(declarations)});`} + ${filtered_declarations.length > 0 && `$$self.$$.get = () => (${stringifyProps(filtered_declarations)});`} ${set && `$$self.$$.set = ${set};`}