Merge branch 'debug' of https://github.com/GarrettGeorge/svelte into GarrettGeorge-debug

pull/1646/head
Rich Harris 6 years ago
commit a5967fa118

@ -0,0 +1,51 @@
import Node from './shared/Node';
import Tag from './shared/Tag';
import Block from '../dom/Block';
import Expression from './shared/Expression';
import deindent from '../../utils/deindent';
export default class DebugTag extends Node {
expression: Expression;
constructor(compiler, parent, scope, info) {
super(compiler, parent, scope, info);
if (info.expression !== null)
// Debug when expression nodes change
this.expression = new Expression(compiler, parent, scope, info.expression);
else
// "Debug all"
this.expression = info.expression
}
build(
block: Block,
parentNode: string,
parentNodes: string,
) {
// Debug all
if (this.expression === null) {
block.builders.create.addLine('debugger;');
block.builders.update.addLine('debugger;');
} else {
const { dependencies } = this.expression;
const condition = [...dependencies].map(d => `changed.${d}`).join(' || ');
const identifiers = this.expression.node.expressions.map(e => e.name).join(', ');
block.builders.update.addBlock(deindent`
if (${condition}) {
const { ${identifiers} } = ctx;
console.log({ ${identifiers} });
debugger;
}
`);
block.builders.create.addBlock(deindent`
const { ${identifiers} } = ctx;
console.log({ ${identifiers} });
debugger;
`);
}
}
}

@ -21,7 +21,45 @@ import mapChildren from './shared/mapChildren';
import { dimensions } from '../../utils/patterns';
// source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7
const booleanAttributes = new Set('async autocomplete autofocus autoplay border challenge checked compact contenteditable controls default defer disabled formnovalidate frameborder hidden indeterminate ismap loop multiple muted nohref noresize noshade novalidate nowrap open readonly required reversed scoped scrolling seamless selected sortable spellcheck translate'.split(' '));
const booleanAttributes = new Set([
'async',
'autocomplete',
'autofocus',
'autoplay',
'border',
'challenge',
'checked',
'compact',
'contenteditable',
'controls',
'default',
'defer',
'disabled',
'formnovalidate',
'frameborder',
'hidden',
'indeterminate',
'ismap',
'loop',
'multiple',
'muted',
'nohref',
'noresize',
'noshade',
'novalidate',
'nowrap',
'open',
'readonly',
'required',
'reversed',
'scoped',
'scrolling',
'seamless',
'selected',
'sortable',
'spellcheck',
'translate'
]);
export default class Element extends Node {
type: 'Element';

@ -7,6 +7,7 @@ import Head from '../Head';
import IfBlock from '../IfBlock';
import MustacheTag from '../MustacheTag';
import RawMustacheTag from '../RawMustacheTag';
import DebugTag from '../DebugTag';
import Slot from '../Slot';
import Text from '../Text';
import Title from '../Title';
@ -24,6 +25,7 @@ function getConstructor(type): typeof Node {
case 'IfBlock': return IfBlock;
case 'MustacheTag': return MustacheTag;
case 'RawMustacheTag': return RawMustacheTag;
case 'DebugTag': return DebugTag;
case 'Slot': return Slot;
case 'Text': return Text;
case 'Title': return Title;

@ -313,6 +313,30 @@ export default function mustache(parser: Parser) {
type: 'RawMustacheTag',
expression,
});
} else if (parser.eat('@debug')) {
let expression;
// Implies {@debug} which indicates "debug all"
if (/\s*}/.test(parser.template[parser.index]))
expression = null;
else
expression = readExpression(parser);
if (expression !== null && expression.type !== 'SequenceExpression')
parser.error({
code: 'invalid-debug-args',
message: '{@debug ...} arguments must be identifers, not arbitrary expressions'
}, expression.start);
parser.allowWhitespace();
parser.eat('}', true);
parser.current().children.push({
start,
end: parser.index,
type: 'DebugTag',
expression,
});
} else {
const expression = readExpression(parser);

@ -22,6 +22,7 @@ export default function error(message: string, props: {
start: number,
end?: number
}) {
console.error(props);
const error = new CompileError(message);
error.name = props.name;

@ -0,0 +1,200 @@
function noop() {}
function assign(tar, src) {
for (var k in src) tar[k] = src[k];
return tar;
}
function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor);
}
function detachNode(node) {
node.parentNode.removeChild(node);
}
function createElement(name) {
return document.createElement(name);
}
function createText(data) {
return document.createTextNode(data);
}
function setData(text, data) {
text.data = '' + data;
}
function blankObject() {
return Object.create(null);
}
function destroy(detach) {
this.destroy = noop;
this.fire('destroy');
this.set = noop;
this._fragment.d(detach !== false);
this._fragment = null;
this._state = {};
}
function _differs(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
function fire(eventName, data) {
var handlers =
eventName in this._handlers && this._handlers[eventName].slice();
if (!handlers) return;
for (var i = 0; i < handlers.length; i += 1) {
var handler = handlers[i];
if (!handler.__calling) {
try {
handler.__calling = true;
handler.call(this, data);
} finally {
handler.__calling = false;
}
}
}
}
function get() {
return this._state;
}
function init(component, options) {
component._handlers = blankObject();
component._bind = options._bind;
component.options = options;
component.root = options.root || component;
component.store = options.store || component.root.store;
}
function on(eventName, handler) {
var handlers = this._handlers[eventName] || (this._handlers[eventName] = []);
handlers.push(handler);
return {
cancel: function() {
var index = handlers.indexOf(handler);
if (~index) handlers.splice(index, 1);
}
};
}
function 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;
}
function _set(newState) {
var oldState = this._state,
changed = {},
dirty = false;
for (var key in newState) {
if (this._differs(newState[key], oldState[key])) changed[key] = dirty = true;
}
if (!dirty) return;
this._state = assign(assign({}, oldState), newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
if (this._fragment) {
this.fire("state", { changed: changed, current: this._state, previous: oldState });
this._fragment.p(changed, this._state);
this.fire("update", { changed: changed, current: this._state, previous: oldState });
}
}
function callAll(fns) {
while (fns && fns.length) fns.shift()();
}
function _mount(target, anchor) {
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
}
var proto = {
destroy,
get,
fire,
on,
set,
_recompute: noop,
_set,
_mount,
_differs
};
/* generated by Svelte vX.Y.Z */
function create_main_fragment(component, ctx) {
var h1, text, text_1, text_2, text_3;
return {
c() {
h1 = createElement("h1");
text = createText("Hello ");
text_1 = createText(ctx.name);
text_2 = createText("!");
text_3 = createText("\n");
debugger;
},
m(target, anchor) {
insert(target, h1, anchor);
append(h1, text);
append(h1, text_1);
append(h1, text_2);
insert(target, text_3, anchor);
},
p(changed, ctx) {
if (changed.name) {
setData(text_1, ctx.name);
}
debugger;
},
d(detach) {
if (detach) {
detachNode(h1);
detachNode(text_3);
}
}
};
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._intro = true;
this._fragment = create_main_fragment(this, this._state);
if (options.target) {
this._fragment.c();
this._mount(options.target, options.anchor);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,56 @@
/* generated by Svelte vX.Y.Z */
import { append, assign, createElement, createText, detachNode, init, insert, proto, setData } from "svelte/shared.js";
function create_main_fragment(component, ctx) {
var h1, text, text_1, text_2, text_3;
return {
c() {
h1 = createElement("h1");
text = createText("Hello ");
text_1 = createText(ctx.name);
text_2 = createText("!");
text_3 = createText("\n");
debugger;
},
m(target, anchor) {
insert(target, h1, anchor);
append(h1, text);
append(h1, text_1);
append(h1, text_2);
insert(target, text_3, anchor);
},
p(changed, ctx) {
if (changed.name) {
setData(text_1, ctx.name);
}
debugger;
},
d(detach) {
if (detach) {
detachNode(h1);
detachNode(text_3);
}
}
};
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._intro = true;
this._fragment = create_main_fragment(this, this._state);
if (options.target) {
this._fragment.c();
this._mount(options.target, options.anchor);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,2 @@
<h1>Hello {name}!</h1>
{@debug}

@ -0,0 +1,290 @@
function noop() {}
function assign(tar, src) {
for (var k in src) tar[k] = src[k];
return tar;
}
function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor);
}
function detachNode(node) {
node.parentNode.removeChild(node);
}
function destroyEach(iterations, detach) {
for (var i = 0; i < iterations.length; i += 1) {
if (iterations[i]) iterations[i].d(detach);
}
}
function createElement(name) {
return document.createElement(name);
}
function createText(data) {
return document.createTextNode(data);
}
function setData(text, data) {
text.data = '' + data;
}
function blankObject() {
return Object.create(null);
}
function destroy(detach) {
this.destroy = noop;
this.fire('destroy');
this.set = noop;
this._fragment.d(detach !== false);
this._fragment = null;
this._state = {};
}
function _differs(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
function fire(eventName, data) {
var handlers =
eventName in this._handlers && this._handlers[eventName].slice();
if (!handlers) return;
for (var i = 0; i < handlers.length; i += 1) {
var handler = handlers[i];
if (!handler.__calling) {
try {
handler.__calling = true;
handler.call(this, data);
} finally {
handler.__calling = false;
}
}
}
}
function get() {
return this._state;
}
function init(component, options) {
component._handlers = blankObject();
component._bind = options._bind;
component.options = options;
component.root = options.root || component;
component.store = options.store || component.root.store;
}
function on(eventName, handler) {
var handlers = this._handlers[eventName] || (this._handlers[eventName] = []);
handlers.push(handler);
return {
cancel: function() {
var index = handlers.indexOf(handler);
if (~index) handlers.splice(index, 1);
}
};
}
function 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;
}
function _set(newState) {
var oldState = this._state,
changed = {},
dirty = false;
for (var key in newState) {
if (this._differs(newState[key], oldState[key])) changed[key] = dirty = true;
}
if (!dirty) return;
this._state = assign(assign({}, oldState), newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
if (this._fragment) {
this.fire("state", { changed: changed, current: this._state, previous: oldState });
this._fragment.p(changed, this._state);
this.fire("update", { changed: changed, current: this._state, previous: oldState });
}
}
function callAll(fns) {
while (fns && fns.length) fns.shift()();
}
function _mount(target, anchor) {
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
}
var proto = {
destroy,
get,
fire,
on,
set,
_recompute: noop,
_set,
_mount,
_differs
};
/* generated by Svelte vX.Y.Z */
function create_main_fragment(component, ctx) {
var text, p, text_1, text_2;
var each_value = ctx.things;
var each_blocks = [];
for (var i = 0; i < each_value.length; i += 1) {
each_blocks[i] = create_each_block(component, get_each_context(ctx, each_value, i));
}
return {
c() {
for (var i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
text = createText("\n\n");
p = createElement("p");
text_1 = createText("foo: ");
text_2 = createText(ctx.foo);
},
m(target, anchor) {
for (var i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(target, anchor);
}
insert(target, text, anchor);
insert(target, p, anchor);
append(p, text_1);
append(p, text_2);
},
p(changed, ctx) {
if (changed.things) {
each_value = ctx.things;
for (var i = 0; i < each_value.length; i += 1) {
const child_ctx = get_each_context(ctx, each_value, i);
if (each_blocks[i]) {
each_blocks[i].p(changed, child_ctx);
} else {
each_blocks[i] = create_each_block(component, child_ctx);
each_blocks[i].c();
each_blocks[i].m(text.parentNode, text);
}
}
for (; i < each_blocks.length; i += 1) {
each_blocks[i].d(1);
}
each_blocks.length = each_value.length;
}
if (changed.foo) {
setData(text_2, ctx.foo);
}
},
d(detach) {
destroyEach(each_blocks, detach);
if (detach) {
detachNode(text);
detachNode(p);
}
}
};
}
// (1:0) {#each things as thing}
function create_each_block(component, ctx) {
var span, text_value = ctx.thing.name, text, text_1;
return {
c() {
span = createElement("span");
text = createText(text_value);
text_1 = createText("\n\t");
const { foo, bar, baz } = ctx;
console.log({ foo, bar, baz });
debugger;
},
m(target, anchor) {
insert(target, span, anchor);
append(span, text);
insert(target, text_1, anchor);
},
p(changed, ctx) {
if ((changed.things) && text_value !== (text_value = ctx.thing.name)) {
setData(text, text_value);
}
if (changed.foo || changed.bar || changed.baz) {
const { foo, bar, baz } = ctx;
console.log({ foo, bar, baz });
debugger;
}
},
d(detach) {
if (detach) {
detachNode(span);
detachNode(text_1);
}
}
};
}
function get_each_context(ctx, list, i) {
const child_ctx = Object.create(ctx);
child_ctx.thing = list[i];
child_ctx.each_value = list;
child_ctx.thing_index = i;
return child_ctx;
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._intro = true;
this._fragment = create_main_fragment(this, this._state);
if (options.target) {
this._fragment.c();
this._mount(options.target, options.anchor);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,140 @@
/* generated by Svelte vX.Y.Z */
import { append, assign, createElement, createText, destroyEach, detachNode, init, insert, proto, setData } from "svelte/shared.js";
function create_main_fragment(component, ctx) {
var text, p, text_1, text_2;
var each_value = ctx.things;
var each_blocks = [];
for (var i = 0; i < each_value.length; i += 1) {
each_blocks[i] = create_each_block(component, get_each_context(ctx, each_value, i));
}
return {
c() {
for (var i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
text = createText("\n\n");
p = createElement("p");
text_1 = createText("foo: ");
text_2 = createText(ctx.foo);
},
m(target, anchor) {
for (var i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(target, anchor);
}
insert(target, text, anchor);
insert(target, p, anchor);
append(p, text_1);
append(p, text_2);
},
p(changed, ctx) {
if (changed.things) {
each_value = ctx.things;
for (var i = 0; i < each_value.length; i += 1) {
const child_ctx = get_each_context(ctx, each_value, i);
if (each_blocks[i]) {
each_blocks[i].p(changed, child_ctx);
} else {
each_blocks[i] = create_each_block(component, child_ctx);
each_blocks[i].c();
each_blocks[i].m(text.parentNode, text);
}
}
for (; i < each_blocks.length; i += 1) {
each_blocks[i].d(1);
}
each_blocks.length = each_value.length;
}
if (changed.foo) {
setData(text_2, ctx.foo);
}
},
d(detach) {
destroyEach(each_blocks, detach);
if (detach) {
detachNode(text);
detachNode(p);
}
}
};
}
// (1:0) {#each things as thing}
function create_each_block(component, ctx) {
var span, text_value = ctx.thing.name, text, text_1;
return {
c() {
span = createElement("span");
text = createText(text_value);
text_1 = createText("\n\t");
const { foo, bar, baz, thing } = ctx;
console.log({ foo, bar, baz, thing });
debugger;
},
m(target, anchor) {
insert(target, span, anchor);
append(span, text);
insert(target, text_1, anchor);
},
p(changed, ctx) {
if ((changed.things) && text_value !== (text_value = ctx.thing.name)) {
setData(text, text_value);
}
if (changed.foo || changed.bar || changed.baz || changed.things) {
const { foo, bar, baz, thing } = ctx;
console.log({ foo, bar, baz, thing });
debugger;
}
},
d(detach) {
if (detach) {
detachNode(span);
detachNode(text_1);
}
}
};
}
function get_each_context(ctx, list, i) {
const child_ctx = Object.create(ctx);
child_ctx.thing = list[i];
child_ctx.each_value = list;
child_ctx.thing_index = i;
return child_ctx;
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._intro = true;
this._fragment = create_main_fragment(this, this._state);
if (options.target) {
this._fragment.c();
this._mount(options.target, options.anchor);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,6 @@
{#each things as thing}
<span>{thing.name}</span>
{@debug foo, bar, baz, thing}
{/each}
<p>foo: {foo}</p>

@ -0,0 +1,15 @@
[{
"code": "invalid-debug-args",
"message": "{@debug ...} arguments must be identifers, not arbitrary expressions",
"start": {
"line": 2,
"column": 9,
"character": 13
},
"end": {
"line": 2,
"column": 9,
"character": 13
},
"pos": 13
}]

@ -0,0 +1,4 @@
<p>
{@debug a + b}
{a + b}
</p>
Loading…
Cancel
Save