include ast in svelte.compile return value (#632)

pull/636/head
Rich Harris 8 years ago
parent 5dc12bbe84
commit 135f626395

@ -10,6 +10,7 @@ import getIntro from './shared/utils/getIntro';
import getOutro from './shared/utils/getOutro'; import getOutro from './shared/utils/getOutro';
import processCss from './shared/processCss'; import processCss from './shared/processCss';
import annotateWithScopes from '../utils/annotateWithScopes'; import annotateWithScopes from '../utils/annotateWithScopes';
import clone from '../utils/clone';
import DomBlock from './dom/Block'; import DomBlock from './dom/Block';
import SsrBlock from './server-side-rendering/Block'; import SsrBlock from './server-side-rendering/Block';
import { Node, Parsed, CompileOptions } from '../interfaces'; import { Node, Parsed, CompileOptions } from '../interfaces';
@ -48,6 +49,8 @@ export default class Generator {
name: string, name: string,
options: CompileOptions options: CompileOptions
) { ) {
this.ast = clone(parsed);
this.parsed = parsed; this.parsed = parsed;
this.source = source; this.source = source;
this.name = name; this.name = name;
@ -330,6 +333,7 @@ export default class Generator {
addString('\n\n' + getOutro(format, name, options, this.imports)); addString('\n\n' + getOutro(format, name, options, this.imports));
return { return {
ast: this.ast,
code: compiled.toString(), code: compiled.toString(),
map: compiled.generateMap({ map: compiled.generateMap({
includeContent: true, includeContent: true,

@ -0,0 +1,18 @@
import { Node } from '../interfaces';
export default function clone(node: Node) {
const cloned = {};
for (const key in node) {
const value = node[key];
if (Array.isArray(value)) {
cloned[key] = value.map(clone);
} else if (value && typeof value === 'object') {
cloned[key] = clone(value);
} else {
cloned[key] = value;
}
}
return cloned;
}

@ -1,10 +1,10 @@
import assert from "assert"; import assert from 'assert';
import * as fs from "fs"; import fs from 'fs';
import { svelte } from "../helpers.js"; import { svelte } from '../helpers.js';
describe("parse", () => { describe('parse', () => {
fs.readdirSync("test/parser/samples").forEach(dir => { fs.readdirSync('test/parser/samples').forEach(dir => {
if (dir[0] === ".") return; if (dir[0] === '.') return;
// add .solo to a sample directory name to only run that test // add .solo to a sample directory name to only run that test
const solo = /\.solo$/.test(dir); const solo = /\.solo$/.test(dir);
@ -17,14 +17,14 @@ describe("parse", () => {
(solo ? it.only : it)(dir, () => { (solo ? it.only : it)(dir, () => {
const input = fs const input = fs
.readFileSync(`test/parser/samples/${dir}/input.html`, "utf-8") .readFileSync(`test/parser/samples/${dir}/input.html`, 'utf-8')
.replace(/\s+$/, ""); .replace(/\s+$/, '');
try { try {
const actual = svelte.parse(input); const actual = svelte.parse(input);
fs.writeFileSync( fs.writeFileSync(
`test/parser/samples/${dir}/_actual.json`, `test/parser/samples/${dir}/_actual.json`,
JSON.stringify(actual, null, "\t") JSON.stringify(actual, null, '\t')
); );
const expected = require(`./samples/${dir}/output.json`); const expected = require(`./samples/${dir}/output.json`);
@ -32,7 +32,7 @@ describe("parse", () => {
assert.deepEqual(actual.css, expected.css); assert.deepEqual(actual.css, expected.css);
assert.deepEqual(actual.js, expected.js); assert.deepEqual(actual.js, expected.js);
} catch (err) { } catch (err) {
if (err.name !== "ParseError") throw err; if (err.name !== 'ParseError') throw err;
try { try {
const expected = require(`./samples/${dir}/error.json`); const expected = require(`./samples/${dir}/error.json`);
@ -41,13 +41,13 @@ describe("parse", () => {
assert.deepEqual(err.loc, expected.loc); assert.deepEqual(err.loc, expected.loc);
assert.equal(err.pos, expected.pos); assert.equal(err.pos, expected.pos);
} catch (err2) { } catch (err2) {
throw err2.code === "MODULE_NOT_FOUND" ? err : err2; throw err2.code === 'MODULE_NOT_FOUND' ? err : err2;
} }
} }
}); });
}); });
it("handles errors with options.onerror", () => { it('handles errors with options.onerror', () => {
let errored = false; let errored = false;
svelte.compile(`<h1>unclosed`, { svelte.compile(`<h1>unclosed`, {
@ -60,9 +60,18 @@ describe("parse", () => {
assert.ok(errored); assert.ok(errored);
}); });
it("throws without options.onerror", () => { it('throws without options.onerror', () => {
assert.throws(() => { assert.throws(() => {
svelte.compile(`<h1>unclosed`); svelte.compile(`<h1>unclosed`);
}, /<h1> was left open/); }, /<h1> was left open/);
}); });
it('includes AST in svelte.compile output', () => {
const dir = fs.readdirSync('test/parser/samples')[0];
const source = fs.readFileSync(`test/parser/samples/${dir}/input.html`, 'utf-8');
const { ast } = svelte.compile(source);
const parsed = svelte.parse(source);
assert.deepEqual(ast, parsed);
});
}); });

Loading…
Cancel
Save