fix indentation, update snapshot tests

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

@ -25,6 +25,51 @@ interface Computation {
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 {
ast: Parsed;
parsed: Parsed;
@ -45,7 +90,6 @@ export default class Generator {
importedComponents: Map<string, string>;
namespace: string;
hasComponents: boolean;
hasJs: boolean;
computations: Computation[];
templateProperties: Record<string, Node>;
slots: Set<string>;
@ -409,7 +453,7 @@ export default class Generator {
}
parseJs() {
const { source } = this;
const { code, source } = this;
const { js } = this.parsed;
const imports = this.imports;
@ -418,11 +462,14 @@ export default class Generator {
const componentDefinition = new CodeBuilder();
let namespace = null;
let hasJs = !!js;
if (js) {
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);
scope.declarations.forEach(name => {
this.userVars.add(name);
@ -500,6 +547,12 @@ export default class Generator {
let name = this.getUniqueName(key);
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
// no conflicts with existing aliases
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 (hasDefaultExport) {
this.code.overwrite(
defaultExport.start,
defaultExport.declaration.start,
`var ${this.alias('template')} = `
);
// if (defaultExport) {
// this.code.overwrite(
// defaultExport.start,
// defaultExport.declaration.start,
// `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 there's no need to include user code, remove it altogether
this.code.remove(js.content.start, js.content.end);
hasJs = false;
}
this.javascript = hasDefaultExport ?
`[✂${js.content.start}-${defaultExport.start}✂]${componentDefinition}[✂${defaultExport.end}-${js.content.end}✂]` :
`[✂${js.content.start}-${js.content.end}✂]`;
let a = js.content.start;
while (/\s/.test(source[a])) a += 1;
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.hasJs = hasJs;
this.namespace = namespace;
this.templateProperties = templateProperties;
}

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

@ -219,7 +219,7 @@ export default function visitComponent(
const expression = node.name === ':Self'
? generator.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`
${statements.join('\n')}

@ -82,7 +82,7 @@ export default function ssr(
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
const mainBlock = new Block({

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

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

@ -190,13 +190,9 @@ var proto = {
};
/* generated by Svelte vX.Y.Z */
var template = (function() {
return {
data: function () {
return { foo: 42 }
}
};
}());
function data() {
return { foo: 42 }
}
function encapsulateStyles(node) {
setAttribute(node, "svelte-3590263702", "");
@ -244,7 +240,7 @@ function create_main_fragment(state, component) {
function SvelteComponent(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();

@ -1,13 +1,9 @@
/* generated by Svelte vX.Y.Z */
import { appendNode, assign, createElement, createText, detachNode, init, insertNode, noop, proto, setAttribute } from "svelte/shared.js";
var template = (function() {
return {
data: function () {
return { foo: 42 }
}
};
}());
function data() {
return { foo: 42 }
};
function encapsulateStyles(node) {
setAttribute(node, "svelte-3590263702", "");
@ -55,7 +51,7 @@ function create_main_fragment(state, component) {
function SvelteComponent(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();

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

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

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

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

@ -178,20 +178,15 @@ var proto = {
};
/* generated by Svelte vX.Y.Z */
var template = (function() {
return {
methods: {
foo ( bar ) {
console.log( bar );
}
},
events: {
foo ( node, callback ) {
// code goes here
}
}
};
}());
function foo( node, callback ) {
// code goes here
}
var methods = {
foo ( bar ) {
console.log( bar );
}
};
function create_main_fragment(state, component) {
var button, foo_handler;
@ -204,7 +199,7 @@ function create_main_fragment(state, component) {
},
hydrate: function() {
foo_handler = template.events.foo.call(component, button, function(event) {
foo_handler = foo.call(component, button, function(event) {
var state = component.get();
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;

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

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

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

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

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

@ -166,24 +166,21 @@ var proto = {
};
/* generated by Svelte vX.Y.Z */
var template = (function() {
return {
methods: {
foo ( bar ) {
console.log( bar );
}
},
setup: (Component) => {
Component.SOME_CONSTANT = 42;
Component.factory = function (target) {
return new Component({
target: target
});
};
Component.prototype.foo( 'baz' );
}
var methods = {
foo ( bar ) {
console.log( bar );
}
};
function setup(Component) {
Component.SOME_CONSTANT = 42;
Component.factory = function (target) {
return new Component({
target: target
});
};
}());
Component.prototype.foo( 'baz' );
}
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;

@ -1,24 +1,21 @@
/* generated by Svelte vX.Y.Z */
import { assign, init, noop, proto } from "svelte/shared.js";
var template = (function() {
return {
methods: {
foo ( bar ) {
console.log( bar );
}
},
setup: (Component) => {
Component.SOME_CONSTANT = 42;
Component.factory = function (target) {
return new Component({
target: target
});
}
Component.prototype.foo( 'baz' );
}
};
}());
var methods = {
foo ( bar ) {
console.log( bar );
}
};
function setup(Component) {
Component.SOME_CONSTANT = 42;
Component.factory = function (target) {
return new Component({
target: target
});
}
Component.prototype.foo( 'baz' );
}
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;

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