track variable hoistability

pull/2011/head
Richard Harris 7 years ago
parent d92e0130ea
commit 6743d8c238

@ -861,8 +861,7 @@ export default class Component {
// reference instance variables other than other
// hoistable functions. TODO others?
const { hoistable_names, hoistable_nodes, imported_declarations, instance_scope: scope } = this;
const template_scope = this.fragment.scope;
const { hoistable_names, hoistable_nodes, imported_declarations, var_lookup } = this;
const top_level_function_declarations = new Map();
@ -870,6 +869,8 @@ export default class Component {
if (node.type === 'VariableDeclaration') {
if (node.declarations.every(d => d.init && d.init.type === 'Literal' && !this.var_lookup.get(d.id.name).mutated)) {
node.declarations.forEach(d => {
const variable = this.var_lookup.get(d.id.name);
variable.hoistable = true;
hoistable_names.add(d.id.name);
});
@ -920,7 +921,9 @@ export default class Component {
else if (owner === instance_scope) {
if (name === fn_declaration.id.name) return;
if (hoistable_names.has(name)) return;
const variable = var_lookup.get(name);
if (variable.hoistable) return;
if (imported_declarations.has(name)) return;
if (top_level_function_declarations.has(name)) {
@ -957,6 +960,8 @@ export default class Component {
for (const [name, node] of top_level_function_declarations) {
if (!checked.has(node) && is_hoistable(node)) {
const variable = this.var_lookup.get(name);
variable.hoistable = true;
hoistable_names.add(name);
hoistable_nodes.add(node);
@ -1079,7 +1084,8 @@ export default class Component {
}
qualify(name) {
if (this.hoistable_names.has(name)) return name;
const variable = this.var_lookup.get(name);
if (variable && variable.hoistable) return name;
if (this.imported_declarations.has(name)) return name;
if (this.declarations.indexOf(name) === -1) return name;

@ -457,10 +457,12 @@ function isContextual(component: Component, scope: TemplateScope, name: string)
// if it's a name below root scope, it's contextual
if (!scope.isTopLevel(name)) return true;
const variable = component.var_lookup.get(name);
// hoistables, module declarations, and imports are non-contextual
if (component.hoistable_names.has(name)) return false;
if (component.module_scope && component.module_scope.declarations.has(name)) return false;
if (component.imported_declarations.has(name)) return false;
if (variable.hoistable) return false;
if (variable.module) return false; // TODO make all module-level variables hoistable by default
if (variable.import_type) return false; // TODO ditto
// assume contextual
return true;

@ -97,7 +97,7 @@ export default function dom(
props.forEach(x => {
const variable = component.var_lookup.get(x.name);
if (component.imported_declarations.has(x.name) || component.hoistable_names.has(x.name)) {
if (component.imported_declarations.has(x.name) || variable.hoistable) {
body.push(deindent`
get ${x.exported_as}() {
return ${x.name};
@ -254,14 +254,18 @@ export default function dom(
`);
const filtered_declarations = component.declarations.filter(name => {
if (component.hoistable_names.has(name)) return false;
const variable = component.var_lookup.get(name);
if (variable && variable.hoistable) return false;
if (component.imported_declarations.has(name)) return false;
if (props.find(p => p.exported_as === name)) return true;
return component.template_references.has(name);
});
const filtered_props = props.filter(prop => {
if (component.hoistable_names.has(prop.name)) return false;
const variable = component.var_lookup.get(prop.name);
if (variable.hoistable) return false;
if (component.imported_declarations.has(prop.name)) return false;
if (prop.name[0] === '$') return false;
return true;

@ -22,11 +22,8 @@ export default function addActions(
);
block.addVariable(name);
const fn = component.imported_declarations.has(action.name) || component.hoistable_names.has(action.name)
? action.name
: `ctx.${action.name}`;
component.add_reference(action.name);
const fn = component.qualify(action.name);
block.builders.mount.addLine(
`${name} = ${fn}.call(null, ${target}${snippet ? `, ${snippet}` : ''}) || {};`

@ -91,4 +91,5 @@ export interface Var {
referenced?: boolean;
writable?: boolean;
initialised?: boolean;
hoistable?: boolean;
}
Loading…
Cancel
Save