From 557d06f392c7714f346c4e61f210ab9af6bba2f3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 21 Apr 2018 19:55:13 -0400 Subject: [PATCH] put methods on class body --- src/generators/Generator.ts | 6 +- src/generators/dom/index.ts | 56 +++++- src/shared/index.js | 2 + .../expected-bundle.js | 11 +- .../expected-v2.js | 72 ------- .../expected.js | 9 +- .../event-handlers-custom/expected-bundle.js | 12 +- .../samples/event-handlers-custom/expected.js | 12 +- .../method-arrow-function/expected-bundle.js | 169 +++++++++++++++++ .../samples/method-arrow-function/expected.js | 42 +++++ .../samples/method-arrow-function/input.html | 12 ++ .../samples/method-async/expected-bundle.js | 163 ++++++++++++++++ test/js/samples/method-async/expected.js | 36 ++++ test/js/samples/method-async/input.html | 8 + .../expected-bundle.js | 163 ++++++++++++++++ .../method-function-keyword/expected.js | 36 ++++ .../method-function-keyword/input.html | 9 + .../expected-bundle.js | 175 ++++++++++++++++++ .../expected.js | 48 +++++ .../method-non-function-expression/input.html | 16 ++ .../samples/setup-method/expected-bundle.js | 12 +- test/js/samples/setup-method/expected.js | 12 +- 22 files changed, 957 insertions(+), 124 deletions(-) delete mode 100644 test/js/samples/dev-warning-missing-data-computed/expected-v2.js create mode 100644 test/js/samples/method-arrow-function/expected-bundle.js create mode 100644 test/js/samples/method-arrow-function/expected.js create mode 100644 test/js/samples/method-arrow-function/input.html create mode 100644 test/js/samples/method-async/expected-bundle.js create mode 100644 test/js/samples/method-async/expected.js create mode 100644 test/js/samples/method-async/input.html create mode 100644 test/js/samples/method-function-keyword/expected-bundle.js create mode 100644 test/js/samples/method-function-keyword/expected.js create mode 100644 test/js/samples/method-function-keyword/input.html create mode 100644 test/js/samples/method-non-function-expression/expected-bundle.js create mode 100644 test/js/samples/method-non-function-expression/expected.js create mode 100644 test/js/samples/method-non-function-expression/input.html diff --git a/src/generators/Generator.ts b/src/generators/Generator.ts index a243cb96a0..a84ec430fd 100644 --- a/src/generators/Generator.ts +++ b/src/generators/Generator.ts @@ -610,8 +610,10 @@ export default class Generator { } if (templateProperties.methods && dom) { - addDeclaration('methods', templateProperties.methods.value); - + const indentationLevel = getIndentationLevel(source, templateProperties.methods.start); + if (indentationLevel) { + removeIndentation(code, templateProperties.methods.start, templateProperties.methods.end, indentationLevel, indentExclusionRanges); + } templateProperties.methods.value.properties.forEach(prop => { this.methods.add(prop.key.name); }); diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index caae873e81..bc658217a9 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -261,6 +261,36 @@ export default function dom( `; const classMethods = []; + const extraMethods = []; + + if (templateProperties.methods) { + templateProperties.methods.value.properties.forEach(prop => { + if (/FunctionExpression/.test(prop.value.type)) { + const { type, params, body, async, generator: isGenerator, start, end } = prop.value; + + const prefix = async ? `async ` : isGenerator ? `*` : ``; + const key = `${prefix}[✂${prop.key.start}-${prop.key.end}✂]`; + + if (type === 'ArrowFunctionExpression') { + const paramsSnippet = params.length > 0 + ? `[✂${params[0].start}-${params[params.length - 1].end}✂]` + : ''; + + let bodySnippet = `[✂${body.start}-${body.end}✂]`; + if (body.type !== 'BlockStatement') bodySnippet = `{ return ${bodySnippet}; }`; + + classMethods.push(`${key}(${paramsSnippet}) ${bodySnippet}`) + } else if (type === 'FunctionExpression') { + let c = start; + while (generator.source[c] !== '(') c += 1; + classMethods.push(`${key}[✂${c}-${end}✂]`); + } + } else { + extraMethods.push(`[✂${prop.start}-${prop.end}✂]`) + } + }); + } + if (computations.length) { classMethods.push(deindent` _recompute(changed, state) { @@ -268,6 +298,17 @@ export default function dom( }`); } + if (options.dev) { + const readonly = Array.from(generator.readonly); + if (readonly.length > 0) { + classMethods.push(deindent` + _checkReadOnly(newState) { + if (this._updatingReadonlyProperty) return; + ${readonly.map(prop => `if ('${prop}' in newState) throw new Error("${debugName}: Cannot set read-only property '${prop}'");`)} + }`); + } + } + if (generator.customElement) { const props = generator.props || Array.from(generator.expectedProperties); @@ -339,7 +380,7 @@ export default function dom( customElements.define("${generator.tag}", ${name}); `); } else { - // TODO put methods in class body + // TODO assign non-function-expression methods builder.addBlock(deindent` class ${name} extends @Component { constructor(options) { @@ -349,21 +390,16 @@ export default function dom( ${classMethods.length && classMethods.join('\n\n')} } - - ${templateProperties.methods && `@assign(${name}.prototype, %methods);`} `); } const immutable = templateProperties.immutable ? templateProperties.immutable.value.value : options.immutable; builder.addBlock(deindent` - ${options.dev && deindent` - ${name}.prototype._checkReadOnly = function _checkReadOnly(newState) { - ${Array.from(generator.readonly).map( - prop => - `if ('${prop}' in newState && !this._updatingReadonlyProperty) throw new Error("${debugName}: Cannot set read-only property '${prop}'");` - )} - }; + ${extraMethods.length > 0 && deindent` + @assign(${name}.prototype, { + ${extraMethods.join(',\n\n')} + }); `} ${templateProperties.setup && `%setup(${name});`} diff --git a/src/shared/index.js b/src/shared/index.js index 020a8f399c..cd13e37b00 100644 --- a/src/shared/index.js +++ b/src/shared/index.js @@ -142,6 +142,8 @@ export class ComponentDev extends Component { this._checkReadOnly(newState); super.set(newState); } + + _checkReadOnly() {} } export function _differsImmutable(a, b) { diff --git a/test/js/samples/dev-warning-missing-data-computed/expected-bundle.js b/test/js/samples/dev-warning-missing-data-computed/expected-bundle.js index 254fc74faa..1ed5fe4538 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected-bundle.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected-bundle.js @@ -161,6 +161,8 @@ class ComponentDev extends Component { this._checkReadOnly(newState); super.set(newState); } + + _checkReadOnly() {} } function _differsImmutable(a, b) { @@ -235,10 +237,11 @@ class SvelteComponent extends ComponentDev { if (this._differs(state.bar, (state.bar = bar(state)))) changed.bar = true; } } -} -SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { - if ('bar' in newState && !this._updatingReadonlyProperty) throw new Error(": Cannot set read-only property 'bar'"); -}; + _checkReadOnly(newState) { + if (this._updatingReadonlyProperty) return; + if ('bar' in newState) throw new Error(": Cannot set read-only property 'bar'"); + } +} export default SvelteComponent; diff --git a/test/js/samples/dev-warning-missing-data-computed/expected-v2.js b/test/js/samples/dev-warning-missing-data-computed/expected-v2.js deleted file mode 100644 index 52dee37250..0000000000 --- a/test/js/samples/dev-warning-missing-data-computed/expected-v2.js +++ /dev/null @@ -1,72 +0,0 @@ -/* generated by Svelte vX.Y.Z */ -import { appendNode, assign, createElement, createText, detachNode, init, insertNode, noop, protoDev } from "svelte/shared.js"; - -function bar({ foo }) { - return foo * 2; -} - -function create_main_fragment(component, state) { - var p, text_value = state.Math.max(0, state.foo), text, text_1, text_2; - - return { - c: function create() { - p = createElement("p"); - text = createText(text_value); - text_1 = createText("\n\t"); - text_2 = createText(state.bar); - }, - - m: function mount(target, anchor) { - insertNode(p, target, anchor); - appendNode(text, p); - appendNode(text_1, p); - appendNode(text_2, p); - }, - - p: function update(changed, state) { - if ((changed.Math || changed.foo) && text_value !== (text_value = state.Math.max(0, state.foo))) { - text.data = text_value; - } - - if (changed.bar) { - text_2.data = state.bar; - } - }, - - u: function unmount() { - detachNode(p); - }, - - d: noop - }; -} - -function SvelteComponent(options) { - this._debugName = ''; - if (!options || (!options.target && !options.root)) throw new Error("'target' is a required option"); - init(this, options); - this._state = assign({ Math : Math }, options.data); - this._recompute({ foo: 1 }, this._state); - if (!('foo' in this._state)) console.warn(" was created without expected data property 'foo'"); - - this._fragment = create_main_fragment(this, this._state); - - if (options.target) { - if (options.hydrate) throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); - this._fragment.c(); - this._mount(options.target, options.anchor); - } -} - -assign(SvelteComponent.prototype, protoDev); - -SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { - if ('bar' in newState && !this._updatingReadonlyProperty) throw new Error(": Cannot set read-only property 'bar'"); -}; - -SvelteComponent.prototype._recompute = function _recompute(changed, state) { - if (changed.foo) { - if (this._differs(state.bar, (state.bar = bar(state)))) changed.bar = true; - } -} -export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index 889873982b..99d6d4c43e 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected.js @@ -63,9 +63,10 @@ class SvelteComponent extends ComponentDev { if (this._differs(state.bar, (state.bar = bar(state)))) changed.bar = true; } } -} -SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { - if ('bar' in newState && !this._updatingReadonlyProperty) throw new Error(": Cannot set read-only property 'bar'"); -}; + _checkReadOnly(newState) { + if (this._updatingReadonlyProperty) return; + if ('bar' in newState) throw new Error(": Cannot set read-only property 'bar'"); + } +} export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/event-handlers-custom/expected-bundle.js b/test/js/samples/event-handlers-custom/expected-bundle.js index 42c74274e4..cac6cefdc1 100644 --- a/test/js/samples/event-handlers-custom/expected-bundle.js +++ b/test/js/samples/event-handlers-custom/expected-bundle.js @@ -142,12 +142,6 @@ function callAll(fns) { function foo( node, callback ) { // code goes here } -var methods = { - foo ( bar ) { - console.log( bar ); - } -}; - function create_main_fragment(component, state) { var button, foo_handler; @@ -193,8 +187,10 @@ class SvelteComponent extends Component { this._mount(options.target, options.anchor); } } -} -assign(SvelteComponent.prototype, methods); + foo( bar ) { + console.log( bar ); + } +} export default SvelteComponent; diff --git a/test/js/samples/event-handlers-custom/expected.js b/test/js/samples/event-handlers-custom/expected.js index 978532df69..e0b2a67cc5 100644 --- a/test/js/samples/event-handlers-custom/expected.js +++ b/test/js/samples/event-handlers-custom/expected.js @@ -5,12 +5,6 @@ function foo( node, callback ) { // code goes here }; -var methods = { - foo ( bar ) { - console.log( bar ); - } -}; - function create_main_fragment(component, state) { var button, foo_handler; @@ -56,7 +50,9 @@ class SvelteComponent extends Component { this._mount(options.target, options.anchor); } } -} -assign(SvelteComponent.prototype, methods); + foo( bar ) { + console.log( bar ); + } +} export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/method-arrow-function/expected-bundle.js b/test/js/samples/method-arrow-function/expected-bundle.js new file mode 100644 index 0000000000..5209210a7a --- /dev/null +++ b/test/js/samples/method-arrow-function/expected-bundle.js @@ -0,0 +1,169 @@ +function noop() {} + +function assign(tar, src) { + for (var k in src) tar[k] = src[k]; + return tar; +} + +function blankObject() { + return Object.create(null); +} + +class Base { + constructor() { + this._handlers = blankObject(); + } + + fire(eventName, data) { + const handlers = eventName in this._handlers && this._handlers[eventName].slice(); + if (!handlers) return; + + for (let i = 0; i < handlers.length; i += 1) { + const handler = handlers[i]; + + if (!handler.__calling) { + handler.__calling = true; + handler.call(this, data); + handler.__calling = false; + } + } + } + + get() { + return this._state; + } + + on(eventName, handler) { + const handlers = this._handlers[eventName] || (this._handlers[eventName] = []); + handlers.push(handler); + + return { + cancel: function() { + const index = handlers.indexOf(handler); + if (~index) handlers.splice(index, 1); + } + }; + } + + _differs(a, b) { + return _differsImmutable(a, b) || ((a && typeof a === 'object') || typeof a === 'function'); + } +} + +class Component extends Base { + constructor(options) { + super(); + this._init(options); + } + + destroy(detach) { + this.destroy = noop; + this.fire('destroy'); + this.set = this.get = noop; + + if (detach !== false) this._fragment.u(); + this._fragment.d(); + this._fragment = this._state = null; + } + + set(newState) { + this._set(assign({}, newState)); + if (this.root._lock) return; + this.root._lock = true; + callAll(this.root._beforecreate); + callAll(this.root._oncreate); + callAll(this.root._aftercreate); + this.root._lock = false; + } + + _init(options) { + this._bind = options._bind; + + this.options = options; + this.root = options.root || this; + this.store = this.root.store || options.store; + } + + _set(newState) { + const previous = this._state; + const changed = {}; + let dirty = false; + + for (var key in newState) { + if (this._differs(newState[key], previous[key])) changed[key] = dirty = 1; + } + + if (!dirty) return; + + this._state = assign(assign({}, previous), newState); + this._recompute(changed, this._state); + if (this._bind) this._bind(changed, this._state); + + if (this._fragment) { + this.fire("state", { changed, current: this._state, previous }); + this._fragment.p(changed, this._state); + this.fire("update", { changed, current: this._state, previous }); + } + } + + _mount(target, anchor) { + this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); + } + + _recompute() {} + + _unmount() { + if (this._fragment) this._fragment.u(); + } +} + +function _differsImmutable(a, b) { + return a != a ? b == b : a !== b; +} + +function callAll(fns) { + while (fns && fns.length) fns.shift()(); +} + +/* generated by Svelte vX.Y.Z */ + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } + + foo() { return console.log('foo'); } + + bar(x) { return console.log(x); } + + baz(x) { return console.log(x); } + + qux() { + return 42; + } +} + +export default SvelteComponent; diff --git a/test/js/samples/method-arrow-function/expected.js b/test/js/samples/method-arrow-function/expected.js new file mode 100644 index 0000000000..d0b138d8d3 --- /dev/null +++ b/test/js/samples/method-arrow-function/expected.js @@ -0,0 +1,42 @@ +/* generated by Svelte vX.Y.Z */ +import { Component, assign, noop } from "svelte/shared.js"; + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } + + foo() { return console.log('foo'); } + + bar(x) { return console.log(x); } + + baz(x) { return console.log(x); } + + qux() { + return 42; + } +} +export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/method-arrow-function/input.html b/test/js/samples/method-arrow-function/input.html new file mode 100644 index 0000000000..423eda40fc --- /dev/null +++ b/test/js/samples/method-arrow-function/input.html @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/test/js/samples/method-async/expected-bundle.js b/test/js/samples/method-async/expected-bundle.js new file mode 100644 index 0000000000..6c939e0257 --- /dev/null +++ b/test/js/samples/method-async/expected-bundle.js @@ -0,0 +1,163 @@ +function noop() {} + +function assign(tar, src) { + for (var k in src) tar[k] = src[k]; + return tar; +} + +function blankObject() { + return Object.create(null); +} + +class Base { + constructor() { + this._handlers = blankObject(); + } + + fire(eventName, data) { + const handlers = eventName in this._handlers && this._handlers[eventName].slice(); + if (!handlers) return; + + for (let i = 0; i < handlers.length; i += 1) { + const handler = handlers[i]; + + if (!handler.__calling) { + handler.__calling = true; + handler.call(this, data); + handler.__calling = false; + } + } + } + + get() { + return this._state; + } + + on(eventName, handler) { + const handlers = this._handlers[eventName] || (this._handlers[eventName] = []); + handlers.push(handler); + + return { + cancel: function() { + const index = handlers.indexOf(handler); + if (~index) handlers.splice(index, 1); + } + }; + } + + _differs(a, b) { + return _differsImmutable(a, b) || ((a && typeof a === 'object') || typeof a === 'function'); + } +} + +class Component extends Base { + constructor(options) { + super(); + this._init(options); + } + + destroy(detach) { + this.destroy = noop; + this.fire('destroy'); + this.set = this.get = noop; + + if (detach !== false) this._fragment.u(); + this._fragment.d(); + this._fragment = this._state = null; + } + + set(newState) { + this._set(assign({}, newState)); + if (this.root._lock) return; + this.root._lock = true; + callAll(this.root._beforecreate); + callAll(this.root._oncreate); + callAll(this.root._aftercreate); + this.root._lock = false; + } + + _init(options) { + this._bind = options._bind; + + this.options = options; + this.root = options.root || this; + this.store = this.root.store || options.store; + } + + _set(newState) { + const previous = this._state; + const changed = {}; + let dirty = false; + + for (var key in newState) { + if (this._differs(newState[key], previous[key])) changed[key] = dirty = 1; + } + + if (!dirty) return; + + this._state = assign(assign({}, previous), newState); + this._recompute(changed, this._state); + if (this._bind) this._bind(changed, this._state); + + if (this._fragment) { + this.fire("state", { changed, current: this._state, previous }); + this._fragment.p(changed, this._state); + this.fire("update", { changed, current: this._state, previous }); + } + } + + _mount(target, anchor) { + this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); + } + + _recompute() {} + + _unmount() { + if (this._fragment) this._fragment.u(); + } +} + +function _differsImmutable(a, b) { + return a != a ? b == b : a !== b; +} + +function callAll(fns) { + while (fns && fns.length) fns.shift()(); +} + +/* generated by Svelte vX.Y.Z */ + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } + + async foo() {} + + *bar() {} +} + +export default SvelteComponent; diff --git a/test/js/samples/method-async/expected.js b/test/js/samples/method-async/expected.js new file mode 100644 index 0000000000..3ec7ae454f --- /dev/null +++ b/test/js/samples/method-async/expected.js @@ -0,0 +1,36 @@ +/* generated by Svelte vX.Y.Z */ +import { Component, assign, noop } from "svelte/shared.js"; + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } + + async foo() {} + + *bar() {} +} +export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/method-async/input.html b/test/js/samples/method-async/input.html new file mode 100644 index 0000000000..4774378a02 --- /dev/null +++ b/test/js/samples/method-async/input.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/test/js/samples/method-function-keyword/expected-bundle.js b/test/js/samples/method-function-keyword/expected-bundle.js new file mode 100644 index 0000000000..2d8da4596a --- /dev/null +++ b/test/js/samples/method-function-keyword/expected-bundle.js @@ -0,0 +1,163 @@ +function noop() {} + +function assign(tar, src) { + for (var k in src) tar[k] = src[k]; + return tar; +} + +function blankObject() { + return Object.create(null); +} + +class Base { + constructor() { + this._handlers = blankObject(); + } + + fire(eventName, data) { + const handlers = eventName in this._handlers && this._handlers[eventName].slice(); + if (!handlers) return; + + for (let i = 0; i < handlers.length; i += 1) { + const handler = handlers[i]; + + if (!handler.__calling) { + handler.__calling = true; + handler.call(this, data); + handler.__calling = false; + } + } + } + + get() { + return this._state; + } + + on(eventName, handler) { + const handlers = this._handlers[eventName] || (this._handlers[eventName] = []); + handlers.push(handler); + + return { + cancel: function() { + const index = handlers.indexOf(handler); + if (~index) handlers.splice(index, 1); + } + }; + } + + _differs(a, b) { + return _differsImmutable(a, b) || ((a && typeof a === 'object') || typeof a === 'function'); + } +} + +class Component extends Base { + constructor(options) { + super(); + this._init(options); + } + + destroy(detach) { + this.destroy = noop; + this.fire('destroy'); + this.set = this.get = noop; + + if (detach !== false) this._fragment.u(); + this._fragment.d(); + this._fragment = this._state = null; + } + + set(newState) { + this._set(assign({}, newState)); + if (this.root._lock) return; + this.root._lock = true; + callAll(this.root._beforecreate); + callAll(this.root._oncreate); + callAll(this.root._aftercreate); + this.root._lock = false; + } + + _init(options) { + this._bind = options._bind; + + this.options = options; + this.root = options.root || this; + this.store = this.root.store || options.store; + } + + _set(newState) { + const previous = this._state; + const changed = {}; + let dirty = false; + + for (var key in newState) { + if (this._differs(newState[key], previous[key])) changed[key] = dirty = 1; + } + + if (!dirty) return; + + this._state = assign(assign({}, previous), newState); + this._recompute(changed, this._state); + if (this._bind) this._bind(changed, this._state); + + if (this._fragment) { + this.fire("state", { changed, current: this._state, previous }); + this._fragment.p(changed, this._state); + this.fire("update", { changed, current: this._state, previous }); + } + } + + _mount(target, anchor) { + this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); + } + + _recompute() {} + + _unmount() { + if (this._fragment) this._fragment.u(); + } +} + +function _differsImmutable(a, b) { + return a != a ? b == b : a !== b; +} + +function callAll(fns) { + while (fns && fns.length) fns.shift()(); +} + +/* generated by Svelte vX.Y.Z */ + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } + + foo() { + console.log('foo'); + } +} + +export default SvelteComponent; diff --git a/test/js/samples/method-function-keyword/expected.js b/test/js/samples/method-function-keyword/expected.js new file mode 100644 index 0000000000..8c4f982581 --- /dev/null +++ b/test/js/samples/method-function-keyword/expected.js @@ -0,0 +1,36 @@ +/* generated by Svelte vX.Y.Z */ +import { Component, assign, noop } from "svelte/shared.js"; + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } + + foo() { + console.log('foo'); + } +} +export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/method-function-keyword/input.html b/test/js/samples/method-function-keyword/input.html new file mode 100644 index 0000000000..0eee56773d --- /dev/null +++ b/test/js/samples/method-function-keyword/input.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/test/js/samples/method-non-function-expression/expected-bundle.js b/test/js/samples/method-non-function-expression/expected-bundle.js new file mode 100644 index 0000000000..1562de15d7 --- /dev/null +++ b/test/js/samples/method-non-function-expression/expected-bundle.js @@ -0,0 +1,175 @@ +function noop() {} + +function assign(tar, src) { + for (var k in src) tar[k] = src[k]; + return tar; +} + +function blankObject() { + return Object.create(null); +} + +class Base { + constructor() { + this._handlers = blankObject(); + } + + fire(eventName, data) { + const handlers = eventName in this._handlers && this._handlers[eventName].slice(); + if (!handlers) return; + + for (let i = 0; i < handlers.length; i += 1) { + const handler = handlers[i]; + + if (!handler.__calling) { + handler.__calling = true; + handler.call(this, data); + handler.__calling = false; + } + } + } + + get() { + return this._state; + } + + on(eventName, handler) { + const handlers = this._handlers[eventName] || (this._handlers[eventName] = []); + handlers.push(handler); + + return { + cancel: function() { + const index = handlers.indexOf(handler); + if (~index) handlers.splice(index, 1); + } + }; + } + + _differs(a, b) { + return _differsImmutable(a, b) || ((a && typeof a === 'object') || typeof a === 'function'); + } +} + +class Component extends Base { + constructor(options) { + super(); + this._init(options); + } + + destroy(detach) { + this.destroy = noop; + this.fire('destroy'); + this.set = this.get = noop; + + if (detach !== false) this._fragment.u(); + this._fragment.d(); + this._fragment = this._state = null; + } + + set(newState) { + this._set(assign({}, newState)); + if (this.root._lock) return; + this.root._lock = true; + callAll(this.root._beforecreate); + callAll(this.root._oncreate); + callAll(this.root._aftercreate); + this.root._lock = false; + } + + _init(options) { + this._bind = options._bind; + + this.options = options; + this.root = options.root || this; + this.store = this.root.store || options.store; + } + + _set(newState) { + const previous = this._state; + const changed = {}; + let dirty = false; + + for (var key in newState) { + if (this._differs(newState[key], previous[key])) changed[key] = dirty = 1; + } + + if (!dirty) return; + + this._state = assign(assign({}, previous), newState); + this._recompute(changed, this._state); + if (this._bind) this._bind(changed, this._state); + + if (this._fragment) { + this.fire("state", { changed, current: this._state, previous }); + this._fragment.p(changed, this._state); + this.fire("update", { changed, current: this._state, previous }); + } + } + + _mount(target, anchor) { + this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); + } + + _recompute() {} + + _unmount() { + if (this._fragment) this._fragment.u(); + } +} + +function _differsImmutable(a, b) { + return a != a ? b == b : a !== b; +} + +function callAll(fns) { + while (fns && fns.length) fns.shift()(); +} + +/* generated by Svelte vX.Y.Z */ + +function foo() { + console.log('foo'); +} + +function bar() { + console.log('bar'); +} + + + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } +} + +assign(SvelteComponent.prototype, { + foo, + + bar: [bar][0] +}); + +export default SvelteComponent; diff --git a/test/js/samples/method-non-function-expression/expected.js b/test/js/samples/method-non-function-expression/expected.js new file mode 100644 index 0000000000..6f2630061d --- /dev/null +++ b/test/js/samples/method-non-function-expression/expected.js @@ -0,0 +1,48 @@ +/* generated by Svelte vX.Y.Z */ +import { Component, assign, noop } from "svelte/shared.js"; + +function foo() { + console.log('foo'); +} + +function bar() { + console.log('bar'); +} + + + +function create_main_fragment(component, state) { + + return { + c: noop, + + m: noop, + + p: noop, + + u: noop, + + d: noop + }; +} + +class SvelteComponent extends Component { + constructor(options) { + super(options); + this._state = assign({}, options.data); + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } + } +} + +assign(SvelteComponent.prototype, { + foo, + + bar: [bar][0] +}); +export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/method-non-function-expression/input.html b/test/js/samples/method-non-function-expression/input.html new file mode 100644 index 0000000000..90bbd19293 --- /dev/null +++ b/test/js/samples/method-non-function-expression/input.html @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/test/js/samples/setup-method/expected-bundle.js b/test/js/samples/setup-method/expected-bundle.js index 607d633226..579d237136 100644 --- a/test/js/samples/setup-method/expected-bundle.js +++ b/test/js/samples/setup-method/expected-bundle.js @@ -127,12 +127,6 @@ function callAll(fns) { /* generated by Svelte vX.Y.Z */ -var methods = { - foo ( bar ) { - console.log( bar ); - } -}; - function setup(Component$$1) { Component$$1.SOME_CONSTANT = 42; Component$$1.factory = function (target) { @@ -170,9 +164,11 @@ class SvelteComponent extends Component { this._mount(options.target, options.anchor); } } -} -assign(SvelteComponent.prototype, methods); + foo( bar ) { + console.log( bar ); + } +} setup(SvelteComponent); diff --git a/test/js/samples/setup-method/expected.js b/test/js/samples/setup-method/expected.js index ed4ac240be..2aedc96133 100644 --- a/test/js/samples/setup-method/expected.js +++ b/test/js/samples/setup-method/expected.js @@ -1,12 +1,6 @@ /* generated by Svelte vX.Y.Z */ import { Component, assign, noop } from "svelte/shared.js"; -var methods = { - foo ( bar ) { - console.log( bar ); - } -}; - function setup(Component) { Component.SOME_CONSTANT = 42; Component.factory = function (target) { @@ -44,9 +38,11 @@ class SvelteComponent extends Component { this._mount(options.target, options.anchor); } } -} -assign(SvelteComponent.prototype, methods); + foo( bar ) { + console.log( bar ); + } +} setup(SvelteComponent); export default SvelteComponent; \ No newline at end of file