substituteSlots method

Expr substituteSlots(
  1. Map<SlotId, Value> bindings
)

Returns a new expression with all `ExprSlot` occurrences replaced using the provided bindings.

Implementation

Expr substituteSlots(Map<SlotId, Value> bindings) {
  Expr visit(Expr expr) => switch (expr) {
    ExprValue() => expr,
    ExprVariable() => expr,
    ExprUnknown() => expr,
    ExprSlot(:final slotId) => switch (bindings[slotId]) {
      final Value value => Expr.value(value),
      _ => throw StateError('Missing binding for slot ${slotId.toJson()}'),
    },
    ExprNot(:final arg) => Expr.not(visit(arg)),
    ExprNegate(:final arg) => Expr.negate(visit(arg)),
    ExprAnd(:final left, :final right) => Expr.and(
      left: visit(left),
      right: visit(right),
    ),
    ExprOr(:final left, :final right) => Expr.or(
      left: visit(left),
      right: visit(right),
    ),
    ExprEquals(:final left, :final right) => Expr.equals(
      left: visit(left),
      right: visit(right),
    ),
    ExprNotEquals(:final left, :final right) => Expr.notEquals(
      left: visit(left),
      right: visit(right),
    ),
    ExprLessThan(:final left, :final right) => Expr.lessThan(
      left: visit(left),
      right: visit(right),
    ),
    ExprLessThanOrEquals(:final left, :final right) => Expr.lessThanOrEquals(
      left: visit(left),
      right: visit(right),
    ),
    ExprGreaterThan(:final left, :final right) => Expr.greaterThan(
      left: visit(left),
      right: visit(right),
    ),
    ExprGreaterThanOrEquals(:final left, :final right) =>
      Expr.greaterThanOrEquals(left: visit(left), right: visit(right)),
    ExprAdd(:final left, :final right) => Expr.add(
      left: visit(left),
      right: visit(right),
    ),
    ExprSubt(:final left, :final right) => Expr.subtract(
      left: visit(left),
      right: visit(right),
    ),
    ExprMult(:final left, :final right) => Expr.multiply(
      left: visit(left),
      right: visit(right),
    ),
    ExprContains(:final left, :final right) => Expr.contains(
      left: visit(left),
      right: visit(right),
    ),
    ExprContainsAll(:final left, :final right) => Expr.containsAll(
      left: visit(left),
      right: visit(right),
    ),
    ExprContainsAny(:final left, :final right) => Expr.containsAny(
      left: visit(left),
      right: visit(right),
    ),
    ExprGetAttribute(:final left, :final attr) => Expr.getAttribute(
      left: visit(left),
      attr: attr,
    ),
    ExprHasAttribute(:final left, :final attr) => Expr.hasAttribute(
      left: visit(left),
      attr: attr,
    ),
    ExprGetTag(:final left, :final tag) => Expr.getTag(
      left: visit(left),
      tag: visit(tag),
    ),
    ExprHasTag(:final left, :final tag) => Expr.hasTag(
      left: visit(left),
      tag: visit(tag),
    ),
    ExprLike(:final left, :final pattern) => Expr.like(
      left: visit(left),
      pattern: pattern,
    ),
    ExprIn(:final left, :final right) => Expr.in_(
      left: visit(left),
      right: visit(right),
    ),
    ExprIs(
      left: final left,
      entityType: final entityType,
      inExpr: final inExpr,
    ) =>
      Expr.is_(
        left: visit(left),
        entityType: entityType,
        inExpr: inExpr == null ? null : visit(inExpr),
      ),
    ExprIfThenElse(:final cond, :final then, :final otherwise) =>
      Expr.ifThenElse(
        cond: visit(cond),
        then: visit(then),
        otherwise: visit(otherwise),
      ),
    ExprSet(:final expressions) => Expr.set([
      for (final expression in expressions) visit(expression),
    ]),
    ExprRecord(:final attributes) => Expr.record({
      for (final entry in attributes.entries) entry.key: visit(entry.value),
    }),
    ExprExtensionCall(:final fn, :final args) => Expr.extensionCall(
      fn: fn,
      args: [for (final arg in args) visit(arg)],
    ),
  };

  return visit(this);
}