slightly improve qweb compiler code

This commit is contained in:
Géry Debongnie
2019-02-09 13:09:42 +01:00
parent 69047135a1
commit 7d4e32106b
+45 -69
View File
@@ -91,6 +91,22 @@ export class Context {
this.code.push(prefix + line); this.code.push(prefix + line);
} }
addIf(condition: string) {
this.addLine(`if (${condition}) {`);
this.indent();
}
addElse() {
this.dedent();
this.addLine("} else {");
this.indent();
}
closeIf() {
this.dedent();
this.addLine("}");
}
getValue(val: any): any { getValue(val: any): any {
return val in this.variables ? this.getValue(this.variables[val]) : val; return val in this.variables ? this.getValue(this.variables[val]) : val;
} }
@@ -418,19 +434,15 @@ export class QWeb {
attrs.length + tattrs.length > 0 ? `{attrs:{${attrs.join(",")}}}` : "{}"; attrs.length + tattrs.length > 0 ? `{attrs:{${attrs.join(",")}}}` : "{}";
ctx.addLine(`let c${nodeID} = [], p${nodeID} = ${p};`); ctx.addLine(`let c${nodeID} = [], p${nodeID} = ${p};`);
for (let id of tattrs) { for (let id of tattrs) {
ctx.addLine(`if (_${id} instanceof Array) {`); ctx.addIf(`_${id} instanceof Array`);
ctx.indent();
ctx.addLine(`p${nodeID}.attrs[_${id}[0]] = _${id}[1];`); ctx.addLine(`p${nodeID}.attrs[_${id}[0]] = _${id}[1];`);
ctx.dedent(); ctx.addElse();
ctx.addLine(`} else {`);
ctx.indent();
ctx.addLine(`for (let key in _${id}) {`); ctx.addLine(`for (let key in _${id}) {`);
ctx.indent(); ctx.indent();
ctx.addLine(`p${nodeID}.attrs[key] = _${id}[key];`); ctx.addLine(`p${nodeID}.attrs[key] = _${id}[key];`);
ctx.dedent(); ctx.dedent();
ctx.addLine(`}`); ctx.addLine(`}`);
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`);
} }
ctx.addLine( ctx.addLine(
`let vn${nodeID} = h('${node.nodeName}', p${nodeID}, c${nodeID});` `let vn${nodeID} = h('${node.nodeName}', p${nodeID}, c${nodeID});`
@@ -524,8 +536,7 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Context) {
if (typeof value === "string") { if (typeof value === "string") {
const exprID = ctx.generateID(); const exprID = ctx.generateID();
ctx.addLine(`let e${exprID} = ${qweb._formatExpression(value)};`); ctx.addLine(`let e${exprID} = ${qweb._formatExpression(value)};`);
ctx.addLine(`if (e${exprID} || e${exprID} === 0) {`); ctx.addIf(`e${exprID} || e${exprID} === 0`);
ctx.indent();
let text = `e${exprID}`; let text = `e${exprID}`;
if (!ctx.parentNode) { if (!ctx.parentNode) {
@@ -539,14 +550,11 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Context) {
update: (_, n) => n.elm.innerHTML = e${exprID}, update: (_, n) => n.elm.innerHTML = e${exprID},
};`); // p${ctx.parentNode}.elm.innerHTML = e${exprID} };`); // p${ctx.parentNode}.elm.innerHTML = e${exprID}
} }
ctx.dedent();
if (node.childNodes.length) { if (node.childNodes.length) {
ctx.addLine("} else {"); ctx.addElse();
ctx.indent();
qweb._compileChildren(node, ctx); qweb._compileChildren(node, ctx);
ctx.dedent();
} }
ctx.addLine("}"); ctx.closeIf();
return; return;
} }
if (value instanceof NodeList) { if (value instanceof NodeList) {
@@ -604,13 +612,11 @@ const ifDirective: Directive = {
priority: 20, priority: 20,
atNodeEncounter({ node, qweb, ctx }): boolean { atNodeEncounter({ node, qweb, ctx }): boolean {
let cond = ctx.getValue(node.getAttribute("t-if")!); let cond = ctx.getValue(node.getAttribute("t-if")!);
ctx.addLine(`if (${qweb._formatExpression(cond)}) {`); ctx.addIf(`${qweb._formatExpression(cond)}`);
ctx.indent();
return false; return false;
}, },
finalize({ ctx }) { finalize({ ctx }) {
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`);
} }
}; };
@@ -624,8 +630,7 @@ const elifDirective: Directive = {
return false; return false;
}, },
finalize({ ctx }) { finalize({ ctx }) {
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`);
} }
}; };
@@ -638,8 +643,7 @@ const elseDirective: Directive = {
return false; return false;
}, },
finalize({ ctx }) { finalize({ ctx }) {
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`);
} }
}; };
@@ -804,50 +808,28 @@ const widgetDirective: Directive = {
ctx.addLine(`let isNew${widgetID} = !w${widgetID};`); ctx.addLine(`let isNew${widgetID} = !w${widgetID};`);
// check if we can reuse current rendering promise // check if we can reuse current rendering promise
ctx.addLine(`if (w${widgetID} && w${widgetID}.__widget__.renderPromise) {`); ctx.addIf(`w${widgetID} && w${widgetID}.__widget__.renderPromise`);
ctx.indent(); ctx.addIf(`w${widgetID}.__widget__.isStarted`);
ctx.addLine(`if (w${widgetID}.__widget__.isStarted) {`); ctx.addIf(`props${widgetID} === w${widgetID}.__widget__.renderProps`);
ctx.indent();
ctx.addLine(
`if (props${widgetID} === w${widgetID}.__widget__.renderProps) {`
);
ctx.indent();
ctx.addLine(`def${defID} = w${widgetID}.__widget__.renderPromise;`); ctx.addLine(`def${defID} = w${widgetID}.__widget__.renderPromise;`);
ctx.dedent(); ctx.addElse();
ctx.addLine(`} else {`);
ctx.indent();
ctx.addLine(`def${defID} = w${widgetID}.updateProps(props${widgetID});`); ctx.addLine(`def${defID} = w${widgetID}.updateProps(props${widgetID});`);
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`); ctx.addElse();
ctx.dedent();
ctx.addLine(`} else {`); // not started
ctx.indent();
ctx.addLine(`isNew${widgetID} = true`); ctx.addLine(`isNew${widgetID} = true`);
ctx.addLine( ctx.addIf(`props${widgetID} === w${widgetID}.__widget__.renderProps`);
`if (props${widgetID} === w${widgetID}.__widget__.renderProps) {`
);
ctx.indent();
ctx.addLine(`def${defID} = w${widgetID}.__widget__.renderPromise;`); ctx.addLine(`def${defID} = w${widgetID}.__widget__.renderPromise;`);
ctx.dedent(); ctx.addElse();
ctx.addLine(`} else {`);
ctx.indent();
ctx.addLine(`w${widgetID}.destroy();`); ctx.addLine(`w${widgetID}.destroy();`);
ctx.addLine(`w${widgetID} = false`); ctx.addLine(`w${widgetID} = false`);
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`); ctx.closeIf();
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`);
ctx.dedent();
ctx.addLine(`}`);
ctx.addLine(`if (!def${defID}) {`); ctx.addIf(`!def${defID}`);
ctx.indent(); ctx.addIf(`w${widgetID}`);
ctx.addLine(`if (w${widgetID}) {`);
ctx.indent();
ctx.addLine(`def${defID} = w${widgetID}.updateProps(props${widgetID});`); ctx.addLine(`def${defID} = w${widgetID}.updateProps(props${widgetID});`);
ctx.dedent(); ctx.addElse();
ctx.addLine(`} else {`);
ctx.indent();
ctx.addLine( ctx.addLine(
`w${widgetID} = new context.widgets['${value}'](owner, props${widgetID});` `w${widgetID} = new context.widgets['${value}'](owner, props${widgetID});`
); );
@@ -863,13 +845,10 @@ const widgetDirective: Directive = {
} }
ctx.addLine(`def${defID} = w${widgetID}._start();`); ctx.addLine(`def${defID} = w${widgetID}._start();`);
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`); ctx.closeIf();
ctx.dedent();
ctx.addLine(`}`);
ctx.addLine(`if (isNew${widgetID}) {`); ctx.addIf(`isNew${widgetID}`);
ctx.indent();
ctx.addLine( ctx.addLine(
`def${defID} = def${defID}.then(vnode=>{let pvnode=h(vnode.sel, {key: ${templateID}});c${ `def${defID} = def${defID}.then(vnode=>{let pvnode=h(vnode.sel, {key: ${templateID}});c${
ctx.parentNode ctx.parentNode
@@ -877,9 +856,7 @@ const widgetDirective: Directive = {
keepAlive ? "detach" : "destroy" keepAlive ? "detach" : "destroy"
}()}}});` }()}}});`
); );
ctx.dedent(); ctx.addElse();
ctx.addLine(`} else {`);
ctx.indent();
ctx.addLine( ctx.addLine(
`def${defID} = def${defID}.then(()=>{if (!w${widgetID}.__widget__.vnode) {return};let vnode=h(w${widgetID}.__widget__.vnode.sel, {key: ${templateID}});vnode.elm=w${widgetID}.el;c${ `def${defID} = def${defID}.then(()=>{if (!w${widgetID}.__widget__.vnode) {return};let vnode=h(w${widgetID}.__widget__.vnode.sel, {key: ${templateID}});vnode.elm=w${widgetID}.el;c${
ctx.parentNode ctx.parentNode
@@ -887,8 +864,7 @@ const widgetDirective: Directive = {
keepAlive ? "detach" : "destroy" keepAlive ? "detach" : "destroy"
}()}}});` }()}}});`
); );
ctx.dedent(); ctx.closeIf();
ctx.addLine(`}`);
ctx.addLine(`extra.promises.push(def${defID});`); ctx.addLine(`extra.promises.push(def${defID});`);