fix indentation, update snapshot tests

pull/864/head
Rich Harris 8 years ago
parent 49403d4326
commit 4dbfc65e74

@ -25,6 +25,51 @@ interface Computation {
deps: string[] deps: string[]
} }
function detectIndentation(str: string) {
const pattern = /^[\t\s]{1,4}/gm;
let match;
while (match = pattern.exec(str)) {
if (match[0][0] === '\t') return '\t';
if (match[0].length === 2) return ' ';
}
return ' ';
}
function getIndentationLevel(str: string, b: number) {
let a = b;
while (a > 0 && str[a - 1] !== '\n') a -= 1;
return /^\s*/.exec(str.slice(a, b))[0];
}
function getIndentExclusionRanges(node: Node) {
const ranges: Node[] = [];
walk(node, {
enter(node: Node) {
if (node.type === 'TemplateElement') ranges.push(node);
}
});
return ranges;
}
function removeIndentation(
code: MagicString,
start: number,
end: number,
indentationLevel: string,
ranges: Node[]
) {
const str = code.original.slice(start, end);
const pattern = new RegExp(`^${indentationLevel}`, 'gm');
let match;
while (match = pattern.exec(str)) {
// TODO bail if we're inside an exclusion range
code.remove(start + match.index, start + match.index + indentationLevel.length);
}
}
export default class Generator { export default class Generator {
ast: Parsed; ast: Parsed;
parsed: Parsed; parsed: Parsed;
@ -45,7 +90,6 @@ export default class Generator {
importedComponents: Map<string, string>; importedComponents: Map<string, string>;
namespace: string; namespace: string;
hasComponents: boolean; hasComponents: boolean;
hasJs: boolean;
computations: Computation[]; computations: Computation[];
templateProperties: Record<string, Node>; templateProperties: Record<string, Node>;
slots: Set<string>; slots: Set<string>;
@ -409,7 +453,7 @@ export default class Generator {
} }
parseJs() { parseJs() {
const { source } = this; const { code, source } = this;
const { js } = this.parsed; const { js } = this.parsed;
const imports = this.imports; const imports = this.imports;
@ -418,11 +462,14 @@ export default class Generator {
const componentDefinition = new CodeBuilder(); const componentDefinition = new CodeBuilder();
let namespace = null; let namespace = null;
let hasJs = !!js;
if (js) { if (js) {
this.addSourcemapLocations(js.content); this.addSourcemapLocations(js.content);
const indentation = detectIndentation(source.slice(js.start, js.end));
const indentationLevel = getIndentationLevel(source, js.content.body[0].start);
const indentExclusionRanges = getIndentExclusionRanges(js.content);
const scope = annotateWithScopes(js.content); const scope = annotateWithScopes(js.content);
scope.declarations.forEach(name => { scope.declarations.forEach(name => {
this.userVars.add(name); this.userVars.add(name);
@ -500,6 +547,12 @@ export default class Generator {
let name = this.getUniqueName(key); let name = this.getUniqueName(key);
this.templateVars.set(disambiguator ? `${disambiguator}-${key}` : key, name); this.templateVars.set(disambiguator ? `${disambiguator}-${key}` : key, name);
// deindent
const indentationLevel = getIndentationLevel(source, node.start);
if (indentationLevel) {
removeIndentation(code, node.start, node.end, indentationLevel, indentExclusionRanges);
}
// TODO disambiguate between different categories, and ensure // TODO disambiguate between different categories, and ensure
// no conflicts with existing aliases // no conflicts with existing aliases
if (node.type === 'ArrowFunctionExpression') { if (node.type === 'ArrowFunctionExpression') {
@ -624,35 +677,46 @@ export default class Generator {
} }
} }
// now that we've analysed the default export, we can determine whether or not we need to keep it
let hasDefaultExport = !!defaultExport;
if (defaultExport && defaultExport.declaration.properties.length === 0) {
hasDefaultExport = false;
removeNode(this.code, js.content, defaultExport);
}
// if we do need to keep it, then we need to replace `export default` // if we do need to keep it, then we need to replace `export default`
if (hasDefaultExport) { // if (defaultExport) {
this.code.overwrite( // this.code.overwrite(
defaultExport.start, // defaultExport.start,
defaultExport.declaration.start, // defaultExport.declaration.start,
`var ${this.alias('template')} = ` // `var ${this.alias('template')} = `
); // );
// }
if (indentationLevel) {
if (defaultExport) {
removeIndentation(code, js.content.start, defaultExport.start, indentationLevel, indentExclusionRanges);
removeIndentation(code, defaultExport.end, js.content.end, indentationLevel, indentExclusionRanges);
} else {
removeIndentation(code, js.content.start, js.content.end, indentationLevel, indentExclusionRanges);
}
} }
if (js.content.body.length === 0) { if (js.content.body.length === 0) {
// if there's no need to include user code, remove it altogether // if there's no need to include user code, remove it altogether
this.code.remove(js.content.start, js.content.end); this.code.remove(js.content.start, js.content.end);
hasJs = false;
} }
this.javascript = hasDefaultExport ? let a = js.content.start;
`[✂${js.content.start}-${defaultExport.start}✂]${componentDefinition}[✂${defaultExport.end}-${js.content.end}✂]` : while (/\s/.test(source[a])) a += 1;
`[✂${js.content.start}-${js.content.end}✂]`;
let b = js.content.end;
while (/\s/.test(source[b - 1])) b -= 1;
if (defaultExport) {
this.javascript = '';
if (a !== defaultExport.start) this.javascript += `[✂${a}-${defaultExport.start}✂]`;
if (!componentDefinition.isEmpty()) this.javascript += componentDefinition;
if (defaultExport.end !== b) this.javascript += `[✂${defaultExport.end}-${b}✂]`;
} else {
this.javascript = a === b ? null : `[✂${a}-${b}✂]`;
}
} }
this.computations = computations; this.computations = computations;
this.hasJs = hasJs;
this.namespace = namespace; this.namespace = namespace;
this.templateProperties = templateProperties; this.templateProperties = templateProperties;
} }

@ -92,7 +92,6 @@ export default function dom(
const { const {
computations, computations,
hasJs,
name, name,
templateProperties, templateProperties,
namespace, namespace,
@ -338,7 +337,7 @@ export default function dom(
} }
` : (!sharedPath && `${name}.prototype._recompute = @noop;`)} ` : (!sharedPath && `${name}.prototype._recompute = @noop;`)}
${templateProperties.setup && `@template.setup(${name});`} ${templateProperties.setup && `%setup(${name});`}
`); `);
const usedHelpers = new Set(); const usedHelpers = new Set();

@ -219,7 +219,7 @@ export default function visitComponent(
const expression = node.name === ':Self' const expression = node.name === ':Self'
? generator.name ? generator.name
: generator.importedComponents.get(node.name) || : generator.importedComponents.get(node.name) ||
`@template.components.${node.name}`; `@template.components.${node.name}`; // TODO this is out of date
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
${statements.join('\n')} ${statements.join('\n')}

@ -82,7 +82,7 @@ export default function ssr(
const generator = new SsrGenerator(parsed, source, options.name || 'SvelteComponent', stylesheet, options); const generator = new SsrGenerator(parsed, source, options.name || 'SvelteComponent', stylesheet, options);
const { computations, name, hasJs, templateProperties } = generator; const { computations, name, templateProperties } = generator;
// create main render() function // create main render() function
const mainBlock = new Block({ const mainBlock = new Block({

@ -72,7 +72,7 @@ export default function visitComponent(
const expression = node.name === ':Self' const expression = node.name === ':Self'
? generator.name ? generator.name
: generator.importedComponents.get(node.name) || : generator.importedComponents.get(node.name) ||
`@template.components.${node.name}`; `@template.components.${node.name}`; // TODO out of date
bindings.forEach(binding => { bindings.forEach(binding => {
block.addBinding(binding, expression); block.addBinding(binding, expression);

@ -4,7 +4,7 @@ import * as path from "path";
import { rollup } from "rollup"; import { rollup } from "rollup";
import { loadConfig, svelte } from "../helpers.js"; import { loadConfig, svelte } from "../helpers.js";
describe.skip("js", () => { describe("js", () => {
fs.readdirSync("test/js/samples").forEach(dir => { fs.readdirSync("test/js/samples").forEach(dir => {
if (dir[0] === ".") return; if (dir[0] === ".") return;
@ -62,13 +62,13 @@ describe.skip("js", () => {
); );
assert.equal( assert.equal(
actual.trim().replace(/^\s+$/gm, ""), actual.trim().replace(/^[ \t]+$/gm, ""),
expected.trim().replace(/^\s+$/gm, "") expected.trim().replace(/^[ \t]+$/gm, "")
); );
assert.equal( assert.equal(
code.trim().replace(/^\s+$/gm, ""), code.trim().replace(/^[ \t]+$/gm, ""),
expectedBundle.trim().replace(/^\s+$/gm, "") expectedBundle.trim().replace(/^[ \t]+$/gm, "")
); );
}).catch(err => { }).catch(err => {
if (err.loc) console.error(err.loc); if (err.loc) console.error(err.loc);

@ -190,13 +190,9 @@ var proto = {
}; };
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
var template = (function() { function data() {
return { return { foo: 42 }
data: function () { }
return { foo: 42 }
}
};
}());
function encapsulateStyles(node) { function encapsulateStyles(node) {
setAttribute(node, "svelte-3590263702", ""); setAttribute(node, "svelte-3590263702", "");
@ -244,7 +240,7 @@ function create_main_fragment(state, component) {
function SvelteComponent(options) { function SvelteComponent(options) {
init(this, options); init(this, options);
this._state = assign(template.data(), options.data); this._state = assign(data(), options.data);
if (!document.getElementById("svelte-3590263702-style")) add_css(); if (!document.getElementById("svelte-3590263702-style")) add_css();

@ -1,13 +1,9 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { appendNode, assign, createElement, createText, detachNode, init, insertNode, noop, proto, setAttribute } from "svelte/shared.js"; import { appendNode, assign, createElement, createText, detachNode, init, insertNode, noop, proto, setAttribute } from "svelte/shared.js";
var template = (function() { function data() {
return { return { foo: 42 }
data: function () { };
return { foo: 42 }
}
};
}());
function encapsulateStyles(node) { function encapsulateStyles(node) {
setAttribute(node, "svelte-3590263702", ""); setAttribute(node, "svelte-3590263702", "");
@ -55,7 +51,7 @@ function create_main_fragment(state, component) {
function SvelteComponent(options) { function SvelteComponent(options) {
init(this, options); init(this, options);
this._state = assign(template.data(), options.data); this._state = assign(data(), options.data);
if (!document.getElementById("svelte-3590263702-style")) add_css(); if (!document.getElementById("svelte-3590263702-style")) add_css();

@ -166,17 +166,11 @@ var proto = {
}; };
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
var template = (function() { var Nested = window.Nested;
return {
components: {
Nested: window.Nested
}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
var nested = new template.components.Nested({ var nested = new Nested({
_root: component._root, _root: component._root,
data: { foo: "bar" } data: { foo: "bar" }
}); });

@ -1,17 +1,11 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { assign, callAll, init, noop, proto } from "svelte/shared.js"; import { assign, callAll, init, noop, proto } from "svelte/shared.js";
var template = (function() { var Nested = window.Nested;
return {
components: {
Nested: window.Nested
}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
var nested = new template.components.Nested({ var nested = new Nested({
_root: component._root, _root: component._root,
data: { foo: "bar" } data: { foo: "bar" }
}); });

@ -166,14 +166,13 @@ var proto = {
}; };
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
var template = (function() { function a(x) {
return { return x * 2;
computed: { }
a: x => x * 2,
b: x => x * 3 function b(x) {
} return x * 3;
}; }
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
@ -207,8 +206,8 @@ assign(SvelteComponent.prototype, proto);
SvelteComponent.prototype._recompute = function _recompute(changed, state) { SvelteComponent.prototype._recompute = function _recompute(changed, state) {
if (changed.x) { if (changed.x) {
if (differs(state.a, (state.a = template.computed.a(state.x)))) changed.a = true; if (differs(state.a, (state.a = a(state.x)))) changed.a = true;
if (differs(state.b, (state.b = template.computed.b(state.x)))) changed.b = true; if (differs(state.b, (state.b = b(state.x)))) changed.b = true;
} }
}; };

@ -1,14 +1,13 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { assign, differs, init, noop, proto } from "svelte/shared.js"; import { assign, differs, init, noop, proto } from "svelte/shared.js";
var template = (function() { function a(x) {
return { return x * 2;
computed: { }
a: x => x * 2,
b: x => x * 3 function b(x) {
} return x * 3;
}; }
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
@ -42,8 +41,8 @@ assign(SvelteComponent.prototype, proto);
SvelteComponent.prototype._recompute = function _recompute(changed, state) { SvelteComponent.prototype._recompute = function _recompute(changed, state) {
if (changed.x) { if (changed.x) {
if (differs(state.a, (state.a = template.computed.a(state.x)))) changed.a = true; if (differs(state.a, (state.a = a(state.x)))) changed.a = true;
if (differs(state.b, (state.b = template.computed.b(state.x)))) changed.b = true; if (differs(state.b, (state.b = b(state.x)))) changed.b = true;
} }
} }
export default SvelteComponent; export default SvelteComponent;

@ -178,20 +178,15 @@ var proto = {
}; };
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
var template = (function() { function foo( node, callback ) {
return { // code goes here
methods: { }
foo ( bar ) {
console.log( bar ); var methods = {
} foo ( bar ) {
}, console.log( bar );
events: { }
foo ( node, callback ) { };
// code goes here
}
}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
var button, foo_handler; var button, foo_handler;
@ -204,7 +199,7 @@ function create_main_fragment(state, component) {
}, },
hydrate: function() { hydrate: function() {
foo_handler = template.events.foo.call(component, button, function(event) { foo_handler = foo.call(component, button, function(event) {
var state = component.get(); var state = component.get();
component.foo( state.bar ); component.foo( state.bar );
}); });
@ -238,6 +233,6 @@ function SvelteComponent(options) {
} }
} }
assign(SvelteComponent.prototype, template.methods, proto); assign(SvelteComponent.prototype, methods, proto);
export default SvelteComponent; export default SvelteComponent;

@ -1,20 +1,15 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { assign, createElement, detachNode, init, insertNode, noop, proto } from "svelte/shared.js"; import { assign, createElement, detachNode, init, insertNode, noop, proto } from "svelte/shared.js";
var template = (function() { function foo( node, callback ) {
return { // code goes here
methods: { };
foo ( bar ) {
console.log( bar ); var methods = {
} foo ( bar ) {
}, console.log( bar );
events: { }
foo ( node, callback ) { };
// code goes here
}
}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
var button, foo_handler; var button, foo_handler;
@ -27,7 +22,7 @@ function create_main_fragment(state, component) {
}, },
hydrate: function() { hydrate: function() {
foo_handler = template.events.foo.call(component, button, function(event) { foo_handler = foo.call(component, button, function(event) {
var state = component.get(); var state = component.get();
component.foo( state.bar ); component.foo( state.bar );
}); });
@ -61,5 +56,5 @@ function SvelteComponent(options) {
} }
} }
assign(SvelteComponent.prototype, template.methods, proto); assign(SvelteComponent.prototype, methods, proto);
export default SvelteComponent; export default SvelteComponent;

@ -180,14 +180,6 @@ var proto = {
}; };
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
var template = (function() {
return {
components: {
NonImported
}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
var text; var text;
@ -195,7 +187,7 @@ function create_main_fragment(state, component) {
_root: component._root _root: component._root
}); });
var nonimported = new template.components.NonImported({ var nonimported = new NonImported({
_root: component._root _root: component._root
}); });

@ -2,13 +2,7 @@
import { assign, callAll, createText, detachNode, init, insertNode, noop, proto } from "svelte/shared.js"; import { assign, callAll, createText, detachNode, init, insertNode, noop, proto } from "svelte/shared.js";
import Imported from 'Imported.html'; import Imported from 'Imported.html';
var template = (function() {
return {
components: {
NonImported
}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
var text; var text;
@ -17,7 +11,7 @@ function create_main_fragment(state, component) {
_root: component._root _root: component._root
}); });
var nonimported = new template.components.NonImported({ var nonimported = new NonImported({
_root: component._root _root: component._root
}); });

@ -166,13 +166,9 @@ var proto = {
}; };
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
var template = (function() { function oncreate() {}
return {
// this test should be removed in v2 function ondestroy() {}
oncreate () {},
ondestroy () {}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
@ -193,14 +189,14 @@ function SvelteComponent(options) {
init(this, options); init(this, options);
this._state = options.data || {}; this._state = options.data || {};
this._handlers.destroy = [template.ondestroy]; this._handlers.destroy = [ondestroy];
var oncreate = template.oncreate.bind(this); var _oncreate = oncreate.bind(this);
if (!options._root) { if (!options._root) {
this._oncreate = [oncreate]; this._oncreate = [_oncreate];
} else { } else {
this._root._oncreate.push(oncreate); this._root._oncreate.push(_oncreate);
} }
this._fragment = create_main_fragment(this._state, this); this._fragment = create_main_fragment(this._state, this);

@ -1,13 +1,9 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { assign, callAll, init, noop, proto } from "svelte/shared.js"; import { assign, callAll, init, noop, proto } from "svelte/shared.js";
var template = (function() { function oncreate() {};
return {
// this test should be removed in v2 function ondestroy() {};
oncreate () {},
ondestroy () {}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
@ -28,14 +24,14 @@ function SvelteComponent(options) {
init(this, options); init(this, options);
this._state = options.data || {}; this._state = options.data || {};
this._handlers.destroy = [template.ondestroy] this._handlers.destroy = [ondestroy]
var oncreate = template.oncreate.bind(this); var _oncreate = oncreate.bind(this);
if (!options._root) { if (!options._root) {
this._oncreate = [oncreate]; this._oncreate = [_oncreate];
} else { } else {
this._root._oncreate.push(oncreate); this._root._oncreate.push(_oncreate);
} }
this._fragment = create_main_fragment(this._state, this); this._fragment = create_main_fragment(this._state, this);

@ -166,24 +166,21 @@ var proto = {
}; };
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
var template = (function() { var methods = {
return { foo ( bar ) {
methods: { console.log( bar );
foo ( bar ) { }
console.log( bar ); };
}
}, function setup(Component) {
setup: (Component) => { Component.SOME_CONSTANT = 42;
Component.SOME_CONSTANT = 42; Component.factory = function (target) {
Component.factory = function (target) { return new Component({
return new Component({ target: target
target: target });
});
};
Component.prototype.foo( 'baz' );
}
}; };
}()); Component.prototype.foo( 'baz' );
}
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
@ -212,8 +209,8 @@ function SvelteComponent(options) {
} }
} }
assign(SvelteComponent.prototype, template.methods, proto); assign(SvelteComponent.prototype, methods, proto);
template.setup(SvelteComponent); setup(SvelteComponent);
export default SvelteComponent; export default SvelteComponent;

@ -1,24 +1,21 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { assign, init, noop, proto } from "svelte/shared.js"; import { assign, init, noop, proto } from "svelte/shared.js";
var template = (function() { var methods = {
return { foo ( bar ) {
methods: { console.log( bar );
foo ( bar ) { }
console.log( bar ); };
}
}, function setup(Component) {
setup: (Component) => { Component.SOME_CONSTANT = 42;
Component.SOME_CONSTANT = 42; Component.factory = function (target) {
Component.factory = function (target) { return new Component({
return new Component({ target: target
target: target });
}); }
} Component.prototype.foo( 'baz' );
Component.prototype.foo( 'baz' ); }
}
};
}());
function create_main_fragment(state, component) { function create_main_fragment(state, component) {
@ -47,7 +44,7 @@ function SvelteComponent(options) {
} }
} }
assign(SvelteComponent.prototype, template.methods, proto); assign(SvelteComponent.prototype, methods, proto);
template.setup(SvelteComponent); setup(SvelteComponent);
export default SvelteComponent; export default SvelteComponent;

@ -0,0 +1,5 @@
export default {
test(assert, component) {
assert.ok(component.constructor.FOO);
}
};

@ -0,0 +1,7 @@
<script>
export default {
setup(Component) {
Component.FOO = true;
}
};
</script>
Loading…
Cancel
Save