From 697e7335d16098279ff669c0d5beae857616a9be Mon Sep 17 00:00:00 2001 From: daszgfz Date: Tue, 26 Nov 2019 15:53:17 -0500 Subject: [PATCH] try 1 --- src/compiler/compile/Component.ts | 19 +++++-- .../action-custom-event-handler/expected.js | 15 +++--- test/js/samples/action/expected.js | 30 ++++++----- test/js/samples/hoisted-function/expected.js | 50 +++++++++++++++++++ test/js/samples/hoisted-function/input.svelte | 11 ++++ test/js/samples/hoisted-function/utils.js | 3 ++ 6 files changed, 105 insertions(+), 23 deletions(-) create mode 100644 test/js/samples/hoisted-function/expected.js create mode 100644 test/js/samples/hoisted-function/input.svelte create mode 100644 test/js/samples/hoisted-function/utils.js diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index cd97c8dd8e..bde0d86487 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -63,6 +63,8 @@ export default class Component { imports: ImportDeclaration[] = []; + function_args: Set = new Set(); + hoistable_nodes: Set = new Set(); node_for_declaration: Map = new Map(); partly_hoisted: Array<(Node | Node[])> = []; @@ -699,7 +701,7 @@ export default class Component { const component = this; const { content } = script; - const { instance_scope, instance_scope_map: map } = this; + const { function_args, instance_scope, instance_scope_map: map } = this; let scope = instance_scope; @@ -716,6 +718,14 @@ export default class Component { scope = map.get(node); } + if (node.type === 'CallExpression') { + node.arguments.forEach(arg => { + if (arg.type == 'Identifier') { + function_args.add(arg.name); + } + }) + } + if (node.type === 'ImportDeclaration') { component.extract_imports(node); // TODO: to use actual remove @@ -1054,6 +1064,7 @@ export default class Component { const instance_scope = this.instance_scope; let scope = this.instance_scope; const map = this.instance_scope_map; + const function_args = this.function_args; let hoistable = true; @@ -1071,8 +1082,10 @@ export default class Component { if (is_reference(node as Node, parent as Node)) { const { name } = flatten_reference(node); const owner = scope.find_owner(name); - - if (injected_reactive_declaration_vars.has(name)) { + + if (function_args.has(name)) { + hoistable = false; + } else if (injected_reactive_declaration_vars.has(name)) { hoistable = false; } else if (name[0] === '$' && !owner) { hoistable = false; diff --git a/test/js/samples/action-custom-event-handler/expected.js b/test/js/samples/action-custom-event-handler/expected.js index 6c3a2a5b0b..031bb3fcb9 100644 --- a/test/js/samples/action-custom-event-handler/expected.js +++ b/test/js/samples/action-custom-event-handler/expected.js @@ -21,10 +21,10 @@ function create_fragment(ctx) { }, m(target, anchor) { insert(target, button, anchor); - foo_action = foo.call(null, button, /*foo_function*/ ctx[1]) || ({}); + foo_action = foo.call(null, button, /*foo_function*/ ctx[2]) || ({}); }, p(ctx, [dirty]) { - if (is_function(foo_action.update) && dirty & /*bar*/ 1) foo_action.update.call(null, /*foo_function*/ ctx[1]); + if (is_function(foo_action.update) && dirty & /*bar*/ 1) foo_action.update.call(null, /*foo_function*/ ctx[2]); }, i: noop, o: noop, @@ -35,23 +35,24 @@ function create_fragment(ctx) { }; } -function handleFoo(bar) { - console.log(bar); -} - function foo(node, callback) { } function instance($$self, $$props, $$invalidate) { let { bar } = $$props; + + function handleFoo(bar) { + console.log(bar); + } + const foo_function = () => handleFoo(bar); $$self.$set = $$props => { if ("bar" in $$props) $$invalidate(0, bar = $$props.bar); }; - return [bar, foo_function]; + return [bar, handleFoo, foo_function]; } class Component extends SvelteComponent { diff --git a/test/js/samples/action/expected.js b/test/js/samples/action/expected.js index 78fc4855c6..6069ec3fb6 100644 --- a/test/js/samples/action/expected.js +++ b/test/js/samples/action/expected.js @@ -23,7 +23,7 @@ function create_fragment(ctx) { }, m(target, anchor) { insert(target, a, anchor); - link_action = link.call(null, a) || ({}); + link_action = /*link*/ ctx[0].call(null, a) || ({}); }, p: noop, i: noop, @@ -35,25 +35,29 @@ function create_fragment(ctx) { }; } -function link(node) { - function onClick(event) { - event.preventDefault(); - history.pushState(null, null, event.target.href); - } +function instance($$self) { + function link(node) { + function onClick(event) { + event.preventDefault(); + history.pushState(null, null, event.target.href); + } - node.addEventListener("click", onClick); + node.addEventListener("click", onClick); - return { - destroy() { - node.removeEventListener("click", onClick); - } - }; + return { + destroy() { + node.removeEventListener("click", onClick); + } + }; + } + + return [link]; } class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, null, create_fragment, safe_not_equal, {}); + init(this, options, instance, create_fragment, safe_not_equal, {}); } } diff --git a/test/js/samples/hoisted-function/expected.js b/test/js/samples/hoisted-function/expected.js new file mode 100644 index 0000000000..f008b66352 --- /dev/null +++ b/test/js/samples/hoisted-function/expected.js @@ -0,0 +1,50 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + detach, + element, + init, + insert, + noop, + safe_not_equal +} from "svelte/internal"; + +import { bar } from "./utils.js"; + +function create_fragment(ctx) { + let p; + + return { + c() { + p = element("p"); + p.textContent = `You'll be pleased to know the answer is ${/*foo*/ ctx[0]()}.`; + }, + m(target, anchor) { + insert(target, p, anchor); + }, + p: noop, + i: noop, + o: noop, + d(detaching) { + if (detaching) detach(p); + } + }; +} + +function instance($$self) { + function foo() { + return 42; + } + + bar(foo); + return [foo]; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, {}); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/hoisted-function/input.svelte b/test/js/samples/hoisted-function/input.svelte new file mode 100644 index 0000000000..1bc6f26a4d --- /dev/null +++ b/test/js/samples/hoisted-function/input.svelte @@ -0,0 +1,11 @@ + + +

You'll be pleased to know the answer is {foo()}.

\ No newline at end of file diff --git a/test/js/samples/hoisted-function/utils.js b/test/js/samples/hoisted-function/utils.js new file mode 100644 index 0000000000..1f4194808f --- /dev/null +++ b/test/js/samples/hoisted-function/utils.js @@ -0,0 +1,3 @@ +export function bar(fn) { + console.log(`I'm safe but you'd never know, ${fn}!`); +} \ No newline at end of file