|
|
|
|
@ -5,7 +5,6 @@ import flatten_reference from '../utils/flatten_reference.js';
|
|
|
|
|
import { reserved_keywords } from '../utils/reserved_keywords.js';
|
|
|
|
|
import { renderer_invalidate } from './invalidate.js';
|
|
|
|
|
export default class Renderer {
|
|
|
|
|
|
|
|
|
|
/** @type {import('../Component.js').default} */
|
|
|
|
|
component; // TODO Maybe Renderer shouldn't know about Component?
|
|
|
|
|
|
|
|
|
|
@ -81,7 +80,14 @@ export default class Renderer {
|
|
|
|
|
dependencies: new Set()
|
|
|
|
|
});
|
|
|
|
|
this.block.has_update_method = true;
|
|
|
|
|
this.fragment = new FragmentWrapper(this, this.block, component.fragment.children, null, true, null);
|
|
|
|
|
this.fragment = new FragmentWrapper(
|
|
|
|
|
this,
|
|
|
|
|
this.block,
|
|
|
|
|
component.fragment.children,
|
|
|
|
|
null,
|
|
|
|
|
true,
|
|
|
|
|
null
|
|
|
|
|
);
|
|
|
|
|
// TODO messy
|
|
|
|
|
this.blocks.forEach((block) => {
|
|
|
|
|
if (block instanceof Block) {
|
|
|
|
|
@ -95,18 +101,14 @@ export default class Renderer {
|
|
|
|
|
const { variable } = member;
|
|
|
|
|
if (variable) {
|
|
|
|
|
member.priority += 2;
|
|
|
|
|
if (variable.mutated || variable.reassigned)
|
|
|
|
|
member.priority += 4;
|
|
|
|
|
if (variable.mutated || variable.reassigned) member.priority += 4;
|
|
|
|
|
// these determine whether variable is included in initial context
|
|
|
|
|
// array, so must have the highest priority
|
|
|
|
|
if (variable.is_reactive_dependency && (variable.mutated || variable.reassigned))
|
|
|
|
|
member.priority += 16;
|
|
|
|
|
if (variable.export_name)
|
|
|
|
|
member.priority += 32;
|
|
|
|
|
if (variable.referenced)
|
|
|
|
|
member.priority += 64;
|
|
|
|
|
}
|
|
|
|
|
else if (member.is_non_contextual) {
|
|
|
|
|
if (variable.export_name) member.priority += 32;
|
|
|
|
|
if (variable.referenced) member.priority += 64;
|
|
|
|
|
} else if (member.is_non_contextual) {
|
|
|
|
|
// determine whether variable is included in initial context
|
|
|
|
|
// array, so must have the highest priority
|
|
|
|
|
member.priority += 8;
|
|
|
|
|
@ -115,19 +117,24 @@ export default class Renderer {
|
|
|
|
|
member.priority += 1;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
this.context.sort((a, b) => b.priority - a.priority || ( /** @type {number} */(a.index.value)) - ( /** @type {number} */(b.index.value)));
|
|
|
|
|
this.context.sort(
|
|
|
|
|
(a, b) =>
|
|
|
|
|
b.priority - a.priority ||
|
|
|
|
|
/** @type {number} */ (a.index.value) - /** @type {number} */ (b.index.value)
|
|
|
|
|
);
|
|
|
|
|
this.context.forEach((member, i) => (member.index.value = i));
|
|
|
|
|
let i = this.context.length;
|
|
|
|
|
while (i--) {
|
|
|
|
|
const member = this.context[i];
|
|
|
|
|
if (member.variable) {
|
|
|
|
|
if (member.variable.referenced ||
|
|
|
|
|
if (
|
|
|
|
|
member.variable.referenced ||
|
|
|
|
|
member.variable.export_name ||
|
|
|
|
|
(member.variable.is_reactive_dependency &&
|
|
|
|
|
(member.variable.mutated || member.variable.reassigned)))
|
|
|
|
|
(member.variable.mutated || member.variable.reassigned))
|
|
|
|
|
)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (member.is_non_contextual) {
|
|
|
|
|
} else if (member.is_non_contextual) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -140,7 +147,6 @@ export default class Renderer {
|
|
|
|
|
*/
|
|
|
|
|
add_to_context(name, contextual = false) {
|
|
|
|
|
if (!this.context_lookup.has(name)) {
|
|
|
|
|
|
|
|
|
|
/** @type {ContextMember} */
|
|
|
|
|
const member = {
|
|
|
|
|
name,
|
|
|
|
|
@ -156,8 +162,7 @@ export default class Renderer {
|
|
|
|
|
const member = this.context_lookup.get(name);
|
|
|
|
|
if (contextual) {
|
|
|
|
|
member.is_contextual = true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
} else {
|
|
|
|
|
member.is_non_contextual = true;
|
|
|
|
|
member.variable = this.component.var_lookup.get(name);
|
|
|
|
|
}
|
|
|
|
|
@ -181,23 +186,22 @@ export default class Renderer {
|
|
|
|
|
dirty(names, is_reactive_declaration = false) {
|
|
|
|
|
const renderer = this;
|
|
|
|
|
const dirty = /** @type {| import('estree').Identifier
|
|
|
|
|
| import('estree').MemberExpression} */ ((is_reactive_declaration ? x `$$self.$$.dirty` : x `#dirty`));
|
|
|
|
|
| import('estree').MemberExpression} */ (
|
|
|
|
|
is_reactive_declaration ? x`$$self.$$.dirty` : x`#dirty`
|
|
|
|
|
);
|
|
|
|
|
const get_bitmask = () => {
|
|
|
|
|
|
|
|
|
|
/** @type {BitMasks} */
|
|
|
|
|
const bitmask = [];
|
|
|
|
|
names.forEach((name) => {
|
|
|
|
|
const member = renderer.context_lookup.get(name);
|
|
|
|
|
if (!member)
|
|
|
|
|
return;
|
|
|
|
|
if (!member) return;
|
|
|
|
|
if (member.index.value === -1) {
|
|
|
|
|
throw new Error('unset index');
|
|
|
|
|
}
|
|
|
|
|
const value = /** @type {number} */ (member.index.value);
|
|
|
|
|
const i = (value / 31) | 0;
|
|
|
|
|
const n = 1 << value % 31;
|
|
|
|
|
if (!bitmask[i])
|
|
|
|
|
bitmask[i] = { n: 0, names: [] };
|
|
|
|
|
if (!bitmask[i]) bitmask[i] = { n: 0, names: [] };
|
|
|
|
|
bitmask[i].n |= n;
|
|
|
|
|
bitmask[i].names.push(name);
|
|
|
|
|
});
|
|
|
|
|
@ -213,7 +217,9 @@ export default class Renderer {
|
|
|
|
|
get expression() {
|
|
|
|
|
const bitmask = get_bitmask();
|
|
|
|
|
if (!bitmask.length) {
|
|
|
|
|
return /** @type {import('estree').BinaryExpression} */ (x `${dirty} & /*${names.join(', ')}*/ 0`);
|
|
|
|
|
return /** @type {import('estree').BinaryExpression} */ (
|
|
|
|
|
x`${dirty} & /*${names.join(', ')}*/ 0`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (renderer.context_overflow) {
|
|
|
|
|
return bitmask
|
|
|
|
|
@ -222,7 +228,9 @@ export default class Renderer {
|
|
|
|
|
.map(({ b, i }) => x`${dirty}[${i}] & /*${b.names.join(', ')}*/ ${b.n}`)
|
|
|
|
|
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`);
|
|
|
|
|
}
|
|
|
|
|
return /** @type {import('estree').BinaryExpression} */ (x `${dirty} & /*${names.join(', ')}*/ ${bitmask[0].n}`);
|
|
|
|
|
return /** @type {import('estree').BinaryExpression} */ (
|
|
|
|
|
x`${dirty} & /*${names.join(', ')}*/ ${bitmask[0].n}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
@ -270,9 +278,10 @@ export default class Renderer {
|
|
|
|
|
this.component.add_reference(node, name);
|
|
|
|
|
}
|
|
|
|
|
if (member !== undefined) {
|
|
|
|
|
const replacement = /** @type {import('estree').MemberExpression} */ (x `/*${member.name}*/ ${ctx}[${member.index}]`);
|
|
|
|
|
if (nodes[0].loc)
|
|
|
|
|
replacement.object.loc = nodes[0].loc;
|
|
|
|
|
const replacement = /** @type {import('estree').MemberExpression} */ (
|
|
|
|
|
x`/*${member.name}*/ ${ctx}[${member.index}]`
|
|
|
|
|
);
|
|
|
|
|
if (nodes[0].loc) replacement.object.loc = nodes[0].loc;
|
|
|
|
|
nodes[0] = replacement;
|
|
|
|
|
return nodes.reduce((lhs, rhs) => x`${lhs}.${rhs}`);
|
|
|
|
|
}
|
|
|
|
|
@ -285,7 +294,6 @@ export default class Renderer {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @typedef {Array<{
|
|
|
|
|
* n: number;
|
|
|
|
|
|