put methods on class body

pull/1359/head
Rich Harris 8 years ago
parent 56f00b8e77
commit 557d06f392

@ -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);
});

@ -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});`}

@ -142,6 +142,8 @@ export class ComponentDev extends Component {
this._checkReadOnly(newState);
super.set(newState);
}
_checkReadOnly() {}
}
export function _differsImmutable(a, b) {

@ -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("<SvelteComponent>: Cannot set read-only property 'bar'");
};
_checkReadOnly(newState) {
if (this._updatingReadonlyProperty) return;
if ('bar' in newState) throw new Error("<SvelteComponent>: Cannot set read-only property 'bar'");
}
}
export default SvelteComponent;

@ -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 = '<SvelteComponent>';
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("<SvelteComponent> 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("<SvelteComponent>: 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;

@ -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("<SvelteComponent>: Cannot set read-only property 'bar'");
};
_checkReadOnly(newState) {
if (this._updatingReadonlyProperty) return;
if ('bar' in newState) throw new Error("<SvelteComponent>: Cannot set read-only property 'bar'");
}
}
export default SvelteComponent;

@ -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;

@ -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;

@ -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;

@ -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;

@ -0,0 +1,12 @@
<script>
export default {
methods: {
foo: () => console.log('foo'),
bar: x => console.log(x),
baz: (x) => console.log(x),
qux: () => {
return 42;
}
}
};
</script>

@ -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;

@ -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;

@ -0,0 +1,8 @@
<script>
export default {
methods: {
async foo () {},
*bar () {}
}
};
</script>

@ -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;

@ -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;

@ -0,0 +1,9 @@
<script>
export default {
methods: {
foo: function() {
console.log('foo');
}
}
};
</script>

@ -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;

@ -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;

@ -0,0 +1,16 @@
<script>
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
}
export default {
methods: {
foo,
bar: [bar][0]
}
};
</script>

@ -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);

@ -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;
Loading…
Cancel
Save