Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[expressions] Provide interface to override just property getter #12

Open
brsanthu opened this issue Nov 14, 2024 · 0 comments · May be fixed by #13
Open

[expressions] Provide interface to override just property getter #12

brsanthu opened this issue Nov 14, 2024 · 0 comments · May be fixed by #13

Comments

@brsanthu
Copy link

Ref: justinfagnani/jexpr#13

We want to support case-insensitive property getter so user doesn't need to know exact case. Based on your suggestion on that ticket, we created our own EvalAstFactory but we need to override three methods even though all of them would call one common function. I think it is better if you can provide a new API getValue (or some other name) which is supposed to return value for a given object and property name, we can override just that method instead of 3 methods as shown below.

function getValueIgnoreCase(obj: RealAny, name: string): RealAny {
  if (obj == undefined || !name) {
    return undefined;
  }

  let value = obj[name];
  if (value == undefined) {
    const nameLower = (name + '').toLowerCase();
    for (const key of Object.keys(obj)) {
      if (key.toLowerCase() === nameLower) {
        value = obj[key];
        break;
      }
    }
  }

  return value;
}

class CustomEvalFactory extends EvalAstFactory {
  override id(v: string): ID {
    return {
      type: 'ID',
      value: v,
      evaluate(scope) {
        // TODO(justinfagnani): this prevents access to properties named 'this'
        if (this.value === 'this') return scope;
        return getValueIgnoreCase(scope, this.value);
      },
      getIds(idents) {
        idents.push(this.value);
        return idents;
      },
    };
  }

  override getter(g: Expression, n: string): Getter {
    return {
      type: 'Getter',
      receiver: g,
      name: n,
      evaluate(scope) {
        return getValueIgnoreCase(this.receiver.evaluate(scope), this.name);
      },
      getIds(idents) {
        this.receiver.getIds(idents);
        return idents;
      },
    };
  }

  override index(e: Expression, a: Expression): Index {
    return {
      type: 'Index',
      receiver: e,
      argument: a,
      evaluate(scope) {
        return getValueIgnoreCase(this.receiver.evaluate(scope), this.argument.evaluate(scope));
      },
      getIds(idents) {
        this.receiver.getIds(idents);
        return idents;
      },
    };
  }
}
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant