handle slot updates when parent component has a bitmask overflow

pull/4078/head
Rich Harris 6 years ago
parent 8a6abc9215
commit 46e6559153

@ -2,6 +2,7 @@ import Let from '../../../nodes/Let';
import { x, p } from 'code-red'; import { x, p } from 'code-red';
import Block from '../../Block'; import Block from '../../Block';
import TemplateScope from '../../../nodes/shared/TemplateScope'; import TemplateScope from '../../../nodes/shared/TemplateScope';
import { BinaryExpression } from 'estree';
export function get_slot_definition(block: Block, scope: TemplateScope, lets: Let[]) { export function get_slot_definition(block: Block, scope: TemplateScope, lets: Let[]) {
if (lets.length === 0) return { block, scope }; if (lets.length === 0) return { block, scope };
@ -28,21 +29,65 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
properties: Array.from(names).map(name => p`${block.renderer.context_lookup.get(name).index}: ${name}`) properties: Array.from(names).map(name => p`${block.renderer.context_lookup.get(name).index}: ${name}`)
}; };
const changes = Array.from(names) const { context_lookup } = block.renderer;
.map(name => {
const { context_lookup } = block.renderer;
const literal = { let expression;
type: 'Literal',
get value() { // i am well aware that this code is gross
// TODO make it less gross
const changes = {
get type() {
if (block.renderer.context_overflow) return 'ArrayExpression';
expression = Array.from(names)
.map(name => {
const i = context_lookup.get(name).index.value as number; const i = context_lookup.get(name).index.value as number;
return 1 << i; return x`${name} ? ${1 << i} : 0`;
} })
}; .reduce((lhs, rhs) => x`${lhs} | ${rhs}`) as BinaryExpression;
return expression.type;
},
get elements() {
const grouped = [];
Array.from(names).forEach(name => {
const i = context_lookup.get(name).index.value as number;
const g = Math.floor(i / 31);
return x`${name} ? ${literal} : 0`; if (!grouped[g]) grouped[g] = [];
}) grouped[g].push({ name, n: i % 31 });
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`); });
const elements = [];
for (let g = 0; g < grouped.length; g += 1) {
elements[g] = grouped[g]
? grouped[g]
.map(({ name, n }) => x`${name} ? ${1 << n} : 0`)
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`)
: x`0`;
}
return elements;
},
get test() {
return expression.test;
},
get consequent() {
return expression.consequent;
},
get alternate() {
return expression.alternate;
},
get left() {
return expression.left;
},
get right() {
return expression.right;
},
operator: '|'
};
return { return {
block, block,

@ -77,9 +77,15 @@ export function get_slot_context(definition, ctx, $$scope, fn) {
} }
export function get_slot_changes(definition, $$scope, dirty, fn) { export function get_slot_changes(definition, $$scope, dirty, fn) {
return definition[2] && fn if (definition[2] && fn) {
? $$scope.dirty | definition[2](fn(dirty)) const lets = definition[2](fn(dirty));
: $$scope.dirty;
return typeof $$scope.dirty === 'object'
? $$scope.dirty.map((n, i) => n | lets[i])
: $$scope.dirty | lets;
}
return $$scope.dirty;
} }
export function exclude_internal_props(props) { export function exclude_internal_props(props) {

Loading…
Cancel
Save