[FIX] component: make arrow-function capture backwards compatible

When fixing the absence of capture for arrow functions passed as props,
we unintentionally introduced a breaking change: bare function calls in
the arrow functions used to be called  with the rendering context as
their this value and this was no longer the case.

This commit fixes that by intentionally not capturing the value of
functions that are called withing the arrow function.
This commit is contained in:
Samuel Degueldre
2021-12-07 15:09:21 +01:00
committed by aab-odoo
parent 73f94fba3f
commit 0bc9573a8a
4 changed files with 108 additions and 4 deletions
+9 -2
View File
@@ -162,7 +162,7 @@ export class CompilationContext {
const tokens = compileExprToArray(expr, this.variables);
const done = new Set();
return tokens
.map((tok) => {
.map((tok, i) => {
// "this" in captured expressions should be the current component
if (tok.value === "this") {
if (!done.has("this")) {
@@ -174,7 +174,14 @@ export class CompilationContext {
// Variables that should be looked up in the scope. isLocal is for arrow
// function arguments that should stay untouched (eg "ev => ev" should
// not become "const ev_1 = scope['ev']; ev_1 => ev_1")
if (tok.varName && !tok.isLocal) {
if (
tok.varName &&
!tok.isLocal &&
// HACK: for backwards compatibility, we don't capture bare methods
// this allows them to be called with the rendering context/scope
// as their this value.
(!tokens[i + 1] || tokens[i + 1].type !== "LEFT_PAREN")
) {
if (!done.has(tok.varName)) {
done.add(tok.varName);
this.addLine(`const ${tok.varName}_${argId} = ${tok.value};`);