hoist nodes, not snippets

pull/3539/head
Richard Harris 6 years ago
parent 0bcbe965dc
commit 1d8d17bc07

6
package-lock.json generated

@ -507,9 +507,9 @@
"dev": true "dev": true
}, },
"code-red": { "code-red": {
"version": "0.0.7", "version": "0.0.8",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.7.tgz", "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.8.tgz",
"integrity": "sha512-UgcXT2tiYOFe5MF6FYeP1s+XKvd5XFlm+p+By6/Q/0/NwgT2ZqkR32liLhosDivtO1vvtLTg51LN1LUW5AYSEw==", "integrity": "sha512-wvKPondTM1H6MoUnz5tj6z1xawzmaulkC0qLv5S1KLkShWgRybgIdvGyVr5pPQt2ovpdmh6BcpRXXoqs5X8tcA==",
"dev": true, "dev": true,
"requires": { "requires": {
"acorn": "^7.0.0", "acorn": "^7.0.0",

@ -63,7 +63,7 @@
"acorn": "^7.0.0", "acorn": "^7.0.0",
"agadoo": "^1.0.1", "agadoo": "^1.0.1",
"c8": "^5.0.1", "c8": "^5.0.1",
"code-red": "0.0.7", "code-red": "0.0.8",
"codecov": "^3.5.0", "codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22", "css-tree": "1.0.0-alpha22",
"eslint": "^6.3.0", "eslint": "^6.3.0",

@ -111,8 +111,8 @@ export default class Component {
hoistable_nodes: Set<Node> = new Set(); hoistable_nodes: Set<Node> = new Set();
node_for_declaration: Map<string, Node> = new Map(); node_for_declaration: Map<string, Node> = new Map();
partly_hoisted: string[] = []; partly_hoisted: Node[] = [];
fully_hoisted: string[] = []; fully_hoisted: Node[] = [];
reactive_declarations: Array<{ reactive_declarations: Array<{
assignees: Set<string>; assignees: Set<string>;
dependencies: Set<string>; dependencies: Set<string>;
@ -1077,7 +1077,11 @@ export default class Component {
const top_level_function_declarations = new Map(); const top_level_function_declarations = new Map();
this.ast.instance.content.body.forEach(node => { const { body } = this.ast.instance.content;
let i = body.length;
while (i--) {
const node = body[i];
if (node.type === 'VariableDeclaration') { if (node.type === 'VariableDeclaration') {
const all_hoistable = node.declarations.every(d => { const all_hoistable = node.declarations.every(d => {
if (!d.init) return false; if (!d.init) return false;
@ -1105,7 +1109,9 @@ export default class Component {
}); });
hoistable_nodes.add(node); hoistable_nodes.add(node);
this.fully_hoisted.push(`[✂${node.start}-${node.end}✂]`);
body.splice(i, 1);
this.fully_hoisted.push(node);
} }
} }
@ -1120,7 +1126,7 @@ export default class Component {
if (node.type === 'FunctionDeclaration') { if (node.type === 'FunctionDeclaration') {
top_level_function_declarations.set(node.id.name, node); top_level_function_declarations.set(node.id.name, node);
} }
}); }
const checked = new Set(); const checked = new Set();
const walking = new Set(); const walking = new Set();
@ -1209,7 +1215,9 @@ export default class Component {
remove_indentation(this.code, node); remove_indentation(this.code, node);
this.fully_hoisted.push(`[✂${node.start}-${node.end}✂]`); const i = body.indexOf(node);
body.splice(i, 1);
this.fully_hoisted.push(node);
} }
} }
} }

@ -1,7 +1,7 @@
import Node from './shared/Node'; import Node from './shared/Node';
import Expression from './shared/Expression'; import Expression from './shared/Expression';
import Component from '../Component'; import Component from '../Component';
import deindent from '../utils/deindent'; import { b } from 'code-red';
import Block from '../render_dom/Block'; import Block from '../render_dom/Block';
import { sanitize } from '../../utils/names'; import { sanitize } from '../../utils/names';
import { Identifier } from '../../interfaces'; import { Identifier } from '../../interfaces';
@ -51,7 +51,7 @@ export default class EventHandler extends Node {
referenced: true referenced: true
}); });
component.partly_hoisted.push(deindent` component.partly_hoisted.push(b`
function ${id}(event) { function ${id}(event) {
@bubble($$self, event); @bubble($$self, event);
} }

@ -325,8 +325,8 @@ export default class Expression {
const body = code.slice(node.body.start, node.body.end).trim(); const body = code.slice(node.body.start, node.body.end).trim();
const fn = node.type === 'FunctionExpression' const fn = node.type === 'FunctionExpression'
? `${node.async ? 'async ' : ''}function${node.generator ? '*' : ''} ${id}(${args.join(', ')}) ${body}` ? b`${node.async ? 'async ' : ''}function${node.generator ? '*' : ''} ${id}(${args.join(', ')}) ${body}`
: `const ${id} = ${node.async ? 'async ' : ''}(${args.join(', ')}) => ${body};`; : b`const ${id} = ${node.async ? 'async ' : ''}(${args.join(', ')}) => ${body};`;
if (dependencies.size === 0 && contextual_dependencies.size === 0) { if (dependencies.size === 0 && contextual_dependencies.size === 0) {
// we can hoist this out of the component completely // we can hoist this out of the component completely
@ -411,6 +411,8 @@ export default class Expression {
}); });
} }
throw new Error(`bad`);
return this.rendered = `[✂${this.node.start}-${this.node.end}✂]`; return this.rendered = `[✂${this.node.start}-${this.node.end}✂]`;
} }
} }

@ -236,7 +236,7 @@ export default function dom(
${component.module_javascript} ${component.module_javascript}
${component.fully_hoisted.length > 0 && component.fully_hoisted.join('\n\n')} ${component.fully_hoisted}
`); `);
const filtered_declarations = component.vars const filtered_declarations = component.vars
@ -314,6 +314,7 @@ export default function dom(
}) })
.map(n => `$$dirty.${n}`).join(' || '); .map(n => `$$dirty.${n}`).join(' || ');
throw new Error(`bad`);
let snippet = `[✂${d.node.body.start}-${d.node.end}✂]`; let snippet = `[✂${d.node.body.start}-${d.node.end}✂]`;
if (condition) snippet = `if (${condition}) { ${snippet} }`; if (condition) snippet = `if (${condition}) { ${snippet} }`;

@ -2,7 +2,6 @@ import Renderer from '../Renderer';
import Block from '../Block'; import Block from '../Block';
import Text from '../../nodes/Text'; import Text from '../../nodes/Text';
import Wrapper from './shared/Wrapper'; import Wrapper from './shared/Wrapper';
import { stringify } from '../../utils/stringify';
import { Identifier } from '../../../interfaces'; import { Identifier } from '../../../interfaces';
import { x } from 'code-red'; import { x } from 'code-red';
@ -72,8 +71,8 @@ export default class TextWrapper extends Wrapper {
block.add_element( block.add_element(
this.var, this.var,
use_space ? x`@space()` : x`@text(${stringify(this.data)})`, use_space ? x`@space()` : x`@text("${this.data}")`,
parent_nodes && (use_space ? x`@claim_space(${parent_nodes})` : x`@claim_text(${parent_nodes}, ${stringify(this.data)})`), parent_nodes && (use_space ? x`@claim_space(${parent_nodes})` : x`@claim_text(${parent_nodes}, "${this.data}")`),
parent_node parent_node
); );
} }

@ -145,7 +145,7 @@ export default function ssr(
${component.module_javascript} ${component.module_javascript}
${component.fully_hoisted.length > 0 && component.fully_hoisted.join('\n\n')} ${component.fully_hoisted}
const ${name} = @create_ssr_component(($$result, $$props, $$bindings, $$slots) => { const ${name} = @create_ssr_component(($$result, $$props, $$bindings, $$slots) => {
${blocks.join('\n\n')} ${blocks.join('\n\n')}

@ -4,7 +4,6 @@ export default function flatten_reference(node: Node) {
if (node.type === 'Expression') throw new Error('bad'); if (node.type === 'Expression') throw new Error('bad');
const nodes = []; const nodes = [];
const parts = []; const parts = [];
const prop_end = node.end;
while (node.type === 'MemberExpression') { while (node.type === 'MemberExpression') {
nodes.unshift(node.property); nodes.unshift(node.property);
@ -16,7 +15,6 @@ export default function flatten_reference(node: Node) {
node = node.object; node = node.object;
} }
const prop_start = node.end;
const name = node.type === 'Identifier' const name = node.type === 'Identifier'
? node.name ? node.name
: node.type === 'ThisExpression' ? 'this' : null; : node.type === 'ThisExpression' ? 'this' : null;
@ -27,5 +25,5 @@ export default function flatten_reference(node: Node) {
parts.unshift(name); parts.unshift(name);
} }
return { name, nodes, parts, keypath: `${name}[✂${prop_start}-${prop_end}✂]` }; return { name, nodes, parts };
} }

@ -1,3 +1,4 @@
export function snip(expression) { export function snip(expression) {
throw new Error(`bad`);
return `[✂${expression.node.start}-${expression.node.end}✂]`; return `[✂${expression.node.start}-${expression.node.end}✂]`;
} }

@ -1 +1,5 @@
<h1>Hello world!</h1> <script>
let name = 'world';
</script>
<h1>Hello {name}!</h1>
Loading…
Cancel
Save