diff --git a/src/compile/nodes/DebugTag.ts b/src/compile/nodes/DebugTag.ts index 11f8812398..5a273bdf71 100644 --- a/src/compile/nodes/DebugTag.ts +++ b/src/compile/nodes/DebugTag.ts @@ -7,10 +7,13 @@ import addToSet from '../../utils/addToSet'; export default class DebugTag extends Node { expressions: Expression[]; + shouldSkip: boolean; constructor(compiler, parent, scope, info) { super(compiler, parent, scope, info); + this.shouldSkip = !compiler.options.dev; + this.expressions = info.identifiers.map(node => { return new Expression(compiler, parent, scope, node); }); @@ -21,6 +24,8 @@ export default class DebugTag extends Node { parentNode: string, parentNodes: string, ) { + if (this.shouldSkip) return; + // Debug all if (this.expressions.length === 0) { block.builders.create.addLine('debugger;'); diff --git a/test/js/samples/debug-empty/_config.js b/test/js/samples/debug-empty/_config.js new file mode 100644 index 0000000000..b1f2518e8a --- /dev/null +++ b/test/js/samples/debug-empty/_config.js @@ -0,0 +1,5 @@ +export default { + options: { + dev: true + } +}; \ No newline at end of file diff --git a/test/js/samples/debug-empty/expected-bundle.js b/test/js/samples/debug-empty/expected-bundle.js index 93c50eed56..36f2b87a80 100644 --- a/test/js/samples/debug-empty/expected-bundle.js +++ b/test/js/samples/debug-empty/expected-bundle.js @@ -5,6 +5,12 @@ function assign(tar, src) { return tar; } +function addLoc(element, file, line, column, char) { + element.__svelte_meta = { + loc: { file, line, column, char } + }; +} + function append(target, node) { target.appendChild(node); } @@ -43,6 +49,13 @@ function destroy(detach) { this._state = {}; } +function destroyDev(detach) { + destroy.call(this, detach); + this.destroy = function() { + console.warn('Component was already destroyed'); + }; +} + function _differs(a, b) { return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); } @@ -122,6 +135,17 @@ function _set(newState) { } } +function setDev(newState) { + if (typeof newState !== 'object') { + throw new Error( + this._debugName + '.set was called without an object of data key-values to update.' + ); + } + + this._checkReadOnly(newState); + set.call(this, newState); +} + function callAll(fns) { while (fns && fns.length) fns.shift()(); } @@ -130,12 +154,12 @@ function _mount(target, anchor) { this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); } -var proto = { - destroy, +var protoDev = { + destroy: destroyDev, get, fire, on, - set, + set: setDev, _recompute: noop, _set, _mount, @@ -144,20 +168,23 @@ var proto = { /* generated by Svelte vX.Y.Z */ +const file = undefined; + function create_main_fragment(component, ctx) { var h1, text, text_1, text_2, text_3; return { - c() { + c: function create() { h1 = createElement("h1"); text = createText("Hello "); text_1 = createText(ctx.name); text_2 = createText("!"); text_3 = createText("\n"); debugger; + addLoc(h1, file, 0, 0, 0); }, - m(target, anchor) { + m: function mount(target, anchor) { insert(target, h1, anchor); append(h1, text); append(h1, text_1); @@ -165,7 +192,7 @@ function create_main_fragment(component, ctx) { insert(target, text_3, anchor); }, - p(changed, ctx) { + p: function update(changed, ctx) { if (changed.name) { setData(text_1, ctx.name); } @@ -173,7 +200,7 @@ function create_main_fragment(component, ctx) { debugger; }, - d(detach) { + d: function destroy$$1(detach) { if (detach) { detachNode(h1); detachNode(text_3); @@ -183,18 +210,25 @@ function create_main_fragment(component, ctx) { } 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({}, options.data); + if (!('name' in this._state)) console.warn(" was created without expected data property 'name'"); this._intro = true; 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, proto); +assign(SvelteComponent.prototype, protoDev); + +SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { +}; -export default SvelteComponent; \ No newline at end of file +export default SvelteComponent; diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js index 592f3a7a2b..9e0023fde2 100644 --- a/test/js/samples/debug-empty/expected.js +++ b/test/js/samples/debug-empty/expected.js @@ -1,20 +1,23 @@ /* generated by Svelte vX.Y.Z */ -import { append, assign, createElement, createText, detachNode, init, insert, proto, setData } from "svelte/shared.js"; +import { addLoc, append, assign, createElement, createText, detachNode, init, insert, protoDev, setData } from "svelte/shared.js"; + +const file = undefined; function create_main_fragment(component, ctx) { var h1, text, text_1, text_2, text_3; return { - c() { + c: function create() { h1 = createElement("h1"); text = createText("Hello "); text_1 = createText(ctx.name); text_2 = createText("!"); text_3 = createText("\n"); debugger; + addLoc(h1, file, 0, 0, 0); }, - m(target, anchor) { + m: function mount(target, anchor) { insert(target, h1, anchor); append(h1, text); append(h1, text_1); @@ -22,7 +25,7 @@ function create_main_fragment(component, ctx) { insert(target, text_3, anchor); }, - p(changed, ctx) { + p: function update(changed, ctx) { if (changed.name) { setData(text_1, ctx.name); } @@ -30,7 +33,7 @@ function create_main_fragment(component, ctx) { debugger; }, - d(detach) { + d: function destroy(detach) { if (detach) { detachNode(h1); detachNode(text_3); @@ -40,17 +43,24 @@ function create_main_fragment(component, ctx) { } 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({}, options.data); + if (!('name' in this._state)) console.warn(" was created without expected data property 'name'"); this._intro = true; 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, proto); +assign(SvelteComponent.prototype, protoDev); + +SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { +}; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/debug-foo-bar-baz-things/_config.js b/test/js/samples/debug-foo-bar-baz-things/_config.js new file mode 100644 index 0000000000..b1f2518e8a --- /dev/null +++ b/test/js/samples/debug-foo-bar-baz-things/_config.js @@ -0,0 +1,5 @@ +export default { + options: { + dev: true + } +}; \ No newline at end of file diff --git a/test/js/samples/debug-foo-bar-baz-things/expected-bundle.js b/test/js/samples/debug-foo-bar-baz-things/expected-bundle.js index 92431339d1..873b28aa2b 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected-bundle.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected-bundle.js @@ -5,6 +5,12 @@ function assign(tar, src) { return tar; } +function addLoc(element, file, line, column, char) { + element.__svelte_meta = { + loc: { file, line, column, char } + }; +} + function append(target, node) { target.appendChild(node); } @@ -49,6 +55,13 @@ function destroy(detach) { this._state = {}; } +function destroyDev(detach) { + destroy.call(this, detach); + this.destroy = function() { + console.warn('Component was already destroyed'); + }; +} + function _differs(a, b) { return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); } @@ -128,6 +141,17 @@ function _set(newState) { } } +function setDev(newState) { + if (typeof newState !== 'object') { + throw new Error( + this._debugName + '.set was called without an object of data key-values to update.' + ); + } + + this._checkReadOnly(newState); + set.call(this, newState); +} + function callAll(fns) { while (fns && fns.length) fns.shift()(); } @@ -136,12 +160,12 @@ function _mount(target, anchor) { this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); } -var proto = { - destroy, +var protoDev = { + destroy: destroyDev, get, fire, on, - set, + set: setDev, _recompute: noop, _set, _mount, @@ -150,6 +174,8 @@ var proto = { /* generated by Svelte vX.Y.Z */ +const file = undefined; + function create_main_fragment(component, ctx) { var text, p, text_1, text_2; @@ -162,7 +188,7 @@ function create_main_fragment(component, ctx) { } return { - c() { + c: function create() { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } @@ -171,9 +197,10 @@ function create_main_fragment(component, ctx) { p = createElement("p"); text_1 = createText("foo: "); text_2 = createText(ctx.foo); + addLoc(p, file, 5, 0, 91); }, - m(target, anchor) { + m: function mount(target, anchor) { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].m(target, anchor); } @@ -184,7 +211,7 @@ function create_main_fragment(component, ctx) { append(p, text_2); }, - p(changed, ctx) { + p: function update(changed, ctx) { if (changed.things) { each_value = ctx.things; @@ -211,7 +238,7 @@ function create_main_fragment(component, ctx) { } }, - d(detach) { + d: function destroy$$1(detach) { destroyEach(each_blocks, detach); if (detach) { @@ -227,7 +254,7 @@ function create_each_block(component, ctx) { var span, text_value = ctx.thing.name, text, text_1; return { - c() { + c: function create() { span = createElement("span"); text = createText(text_value); text_1 = createText("\n\t"); @@ -235,15 +262,16 @@ function create_each_block(component, ctx) { const { foo, bar, baz, thing } = ctx; console.log({ foo, bar, baz, thing }); debugger; + addLoc(span, file, 1, 1, 25); }, - m(target, anchor) { + m: function mount(target, anchor) { insert(target, span, anchor); append(span, text); insert(target, text_1, anchor); }, - p(changed, ctx) { + p: function update(changed, ctx) { if ((changed.things) && text_value !== (text_value = ctx.thing.name)) { setData(text, text_value); } @@ -255,7 +283,7 @@ function create_each_block(component, ctx) { } }, - d(detach) { + d: function destroy$$1(detach) { if (detach) { detachNode(span); detachNode(text_1); @@ -273,18 +301,28 @@ function get_each_context(ctx, list, i) { } 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({}, options.data); + if (!('things' in this._state)) console.warn(" was created without expected data property 'things'"); + if (!('foo' in this._state)) console.warn(" was created without expected data property 'foo'"); + if (!('bar' in this._state)) console.warn(" was created without expected data property 'bar'"); + if (!('baz' in this._state)) console.warn(" was created without expected data property 'baz'"); this._intro = true; 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, proto); +assign(SvelteComponent.prototype, protoDev); + +SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { +}; -export default SvelteComponent; \ No newline at end of file +export default SvelteComponent; diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index 1406c3b927..eb8c70bac6 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -1,5 +1,7 @@ /* generated by Svelte vX.Y.Z */ -import { append, assign, createElement, createText, destroyEach, detachNode, init, insert, proto, setData } from "svelte/shared.js"; +import { addLoc, append, assign, createElement, createText, destroyEach, detachNode, init, insert, protoDev, setData } from "svelte/shared.js"; + +const file = undefined; function create_main_fragment(component, ctx) { var text, p, text_1, text_2; @@ -13,7 +15,7 @@ function create_main_fragment(component, ctx) { } return { - c() { + c: function create() { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } @@ -22,9 +24,10 @@ function create_main_fragment(component, ctx) { p = createElement("p"); text_1 = createText("foo: "); text_2 = createText(ctx.foo); + addLoc(p, file, 5, 0, 91); }, - m(target, anchor) { + m: function mount(target, anchor) { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].m(target, anchor); } @@ -35,7 +38,7 @@ function create_main_fragment(component, ctx) { append(p, text_2); }, - p(changed, ctx) { + p: function update(changed, ctx) { if (changed.things) { each_value = ctx.things; @@ -62,7 +65,7 @@ function create_main_fragment(component, ctx) { } }, - d(detach) { + d: function destroy(detach) { destroyEach(each_blocks, detach); if (detach) { @@ -78,7 +81,7 @@ function create_each_block(component, ctx) { var span, text_value = ctx.thing.name, text, text_1; return { - c() { + c: function create() { span = createElement("span"); text = createText(text_value); text_1 = createText("\n\t"); @@ -86,15 +89,16 @@ function create_each_block(component, ctx) { const { foo, bar, baz, thing } = ctx; console.log({ foo, bar, baz, thing }); debugger; + addLoc(span, file, 1, 1, 25); }, - m(target, anchor) { + m: function mount(target, anchor) { insert(target, span, anchor); append(span, text); insert(target, text_1, anchor); }, - p(changed, ctx) { + p: function update(changed, ctx) { if ((changed.things) && text_value !== (text_value = ctx.thing.name)) { setData(text, text_value); } @@ -106,7 +110,7 @@ function create_each_block(component, ctx) { } }, - d(detach) { + d: function destroy(detach) { if (detach) { detachNode(span); detachNode(text_1); @@ -124,17 +128,27 @@ function get_each_context(ctx, list, i) { } 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({}, options.data); + if (!('things' in this._state)) console.warn(" was created without expected data property 'things'"); + if (!('foo' in this._state)) console.warn(" was created without expected data property 'foo'"); + if (!('bar' in this._state)) console.warn(" was created without expected data property 'bar'"); + if (!('baz' in this._state)) console.warn(" was created without expected data property 'baz'"); this._intro = true; 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, proto); +assign(SvelteComponent.prototype, protoDev); + +SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { +}; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/debug-foo/_config.js b/test/js/samples/debug-foo/_config.js new file mode 100644 index 0000000000..b1f2518e8a --- /dev/null +++ b/test/js/samples/debug-foo/_config.js @@ -0,0 +1,5 @@ +export default { + options: { + dev: true + } +}; \ No newline at end of file diff --git a/test/js/samples/debug-foo/expected-bundle.js b/test/js/samples/debug-foo/expected-bundle.js index 53d68c309f..d4fd9ffaec 100644 --- a/test/js/samples/debug-foo/expected-bundle.js +++ b/test/js/samples/debug-foo/expected-bundle.js @@ -5,6 +5,12 @@ function assign(tar, src) { return tar; } +function addLoc(element, file, line, column, char) { + element.__svelte_meta = { + loc: { file, line, column, char } + }; +} + function append(target, node) { target.appendChild(node); } @@ -49,6 +55,13 @@ function destroy(detach) { this._state = {}; } +function destroyDev(detach) { + destroy.call(this, detach); + this.destroy = function() { + console.warn('Component was already destroyed'); + }; +} + function _differs(a, b) { return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); } @@ -128,6 +141,17 @@ function _set(newState) { } } +function setDev(newState) { + if (typeof newState !== 'object') { + throw new Error( + this._debugName + '.set was called without an object of data key-values to update.' + ); + } + + this._checkReadOnly(newState); + set.call(this, newState); +} + function callAll(fns) { while (fns && fns.length) fns.shift()(); } @@ -136,12 +160,12 @@ function _mount(target, anchor) { this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); } -var proto = { - destroy, +var protoDev = { + destroy: destroyDev, get, fire, on, - set, + set: setDev, _recompute: noop, _set, _mount, @@ -150,6 +174,8 @@ var proto = { /* generated by Svelte vX.Y.Z */ +const file = undefined; + function create_main_fragment(component, ctx) { var text, p, text_1, text_2; @@ -162,7 +188,7 @@ function create_main_fragment(component, ctx) { } return { - c() { + c: function create() { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } @@ -171,9 +197,10 @@ function create_main_fragment(component, ctx) { p = createElement("p"); text_1 = createText("foo: "); text_2 = createText(ctx.foo); + addLoc(p, file, 5, 0, 74); }, - m(target, anchor) { + m: function mount(target, anchor) { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].m(target, anchor); } @@ -184,7 +211,7 @@ function create_main_fragment(component, ctx) { append(p, text_2); }, - p(changed, ctx) { + p: function update(changed, ctx) { if (changed.things) { each_value = ctx.things; @@ -211,7 +238,7 @@ function create_main_fragment(component, ctx) { } }, - d(detach) { + d: function destroy$$1(detach) { destroyEach(each_blocks, detach); if (detach) { @@ -227,7 +254,7 @@ function create_each_block(component, ctx) { var span, text_value = ctx.thing.name, text, text_1; return { - c() { + c: function create() { span = createElement("span"); text = createText(text_value); text_1 = createText("\n\t"); @@ -235,15 +262,16 @@ function create_each_block(component, ctx) { const { foo } = ctx; console.log({ foo }); debugger; + addLoc(span, file, 1, 1, 25); }, - m(target, anchor) { + m: function mount(target, anchor) { insert(target, span, anchor); append(span, text); insert(target, text_1, anchor); }, - p(changed, ctx) { + p: function update(changed, ctx) { if ((changed.things) && text_value !== (text_value = ctx.thing.name)) { setData(text, text_value); } @@ -255,7 +283,7 @@ function create_each_block(component, ctx) { } }, - d(detach) { + d: function destroy$$1(detach) { if (detach) { detachNode(span); detachNode(text_1); @@ -273,18 +301,26 @@ function get_each_context(ctx, list, i) { } 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({}, options.data); + if (!('things' in this._state)) console.warn(" was created without expected data property 'things'"); + if (!('foo' in this._state)) console.warn(" was created without expected data property 'foo'"); this._intro = true; 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, proto); +assign(SvelteComponent.prototype, protoDev); + +SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { +}; -export default SvelteComponent; \ No newline at end of file +export default SvelteComponent; diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index 4795565e59..214ec7486e 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -1,5 +1,7 @@ /* generated by Svelte vX.Y.Z */ -import { append, assign, createElement, createText, destroyEach, detachNode, init, insert, proto, setData } from "svelte/shared.js"; +import { addLoc, append, assign, createElement, createText, destroyEach, detachNode, init, insert, protoDev, setData } from "svelte/shared.js"; + +const file = undefined; function create_main_fragment(component, ctx) { var text, p, text_1, text_2; @@ -13,7 +15,7 @@ function create_main_fragment(component, ctx) { } return { - c() { + c: function create() { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } @@ -22,9 +24,10 @@ function create_main_fragment(component, ctx) { p = createElement("p"); text_1 = createText("foo: "); text_2 = createText(ctx.foo); + addLoc(p, file, 5, 0, 74); }, - m(target, anchor) { + m: function mount(target, anchor) { for (var i = 0; i < each_blocks.length; i += 1) { each_blocks[i].m(target, anchor); } @@ -35,7 +38,7 @@ function create_main_fragment(component, ctx) { append(p, text_2); }, - p(changed, ctx) { + p: function update(changed, ctx) { if (changed.things) { each_value = ctx.things; @@ -62,7 +65,7 @@ function create_main_fragment(component, ctx) { } }, - d(detach) { + d: function destroy(detach) { destroyEach(each_blocks, detach); if (detach) { @@ -78,7 +81,7 @@ function create_each_block(component, ctx) { var span, text_value = ctx.thing.name, text, text_1; return { - c() { + c: function create() { span = createElement("span"); text = createText(text_value); text_1 = createText("\n\t"); @@ -86,15 +89,16 @@ function create_each_block(component, ctx) { const { foo } = ctx; console.log({ foo }); debugger; + addLoc(span, file, 1, 1, 25); }, - m(target, anchor) { + m: function mount(target, anchor) { insert(target, span, anchor); append(span, text); insert(target, text_1, anchor); }, - p(changed, ctx) { + p: function update(changed, ctx) { if ((changed.things) && text_value !== (text_value = ctx.thing.name)) { setData(text, text_value); } @@ -106,7 +110,7 @@ function create_each_block(component, ctx) { } }, - d(detach) { + d: function destroy(detach) { if (detach) { detachNode(span); detachNode(text_1); @@ -124,17 +128,25 @@ function get_each_context(ctx, list, i) { } 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({}, options.data); + if (!('things' in this._state)) console.warn(" was created without expected data property 'things'"); + if (!('foo' in this._state)) console.warn(" was created without expected data property 'foo'"); this._intro = true; 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, proto); +assign(SvelteComponent.prototype, protoDev); + +SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) { +}; export default SvelteComponent; \ No newline at end of file