Skip to content

Some useful tree constructors #5567

Closed
Closed
@liufengyun

Description

@liufengyun

In implementing ScalaTest macros, I find two tree constructors are useful:

def selectApply(receiver: Term, name: Name, args: List[Term]): Term
def let(expr: Term)(body: Ident => Term): Term

The constructor selectApply should do overloading resolution internally, but no other adapation (like inserting apply nor implicits). The constructor let allows creating bindings friendly.

The current implementation of assert is as follows:

      case Term.Apply(Term.Select(lhs, op), rhs :: Nil) =>
        op match {
          case "==" =>
            val left = lhs.seal[Any]
            val right = rhs.seal[Any]
            '{
              val _left   = ~left
              val _right  = ~right
              val _result = _left == _right
              val _bool = Bool.binaryMacroBool(_left, ~op.toExpr, _right, _result, ~prettifier)
              Assertions.assertionsHelper.macroAssert(_bool, ~clue, ~pos)
            }
          case ">" =>
            // blocked by tasty constructors
            // https://github.com/lampepfl/dotty/pull/5438
            val left = lhs.seal[Int]
            val right = rhs.seal[Int]
            '{
              val _left   = ~left
              val _right  = ~right
              val _result = _left > _right
              val _bool = Bool.binaryMacroBool(_left, ~op.toExpr, _right, _result, ~prettifier)
              Assertions.assertionsHelper.macroAssert(_bool, ~clue, ~pos)
            }

With the two constructors, the implementation can be made more generic & simpler:

case Term.Apply(Term.Select(lhs, op), rhs :: Nil) =>
  val res =
  let(lhs) { left =>
    let(rhs) { right =>
      let(selectApply(left, op, right)) { result =>
         val l = left.seal[Any]
         val r = right.seal[Any]
         val b = result.seal[Boolean]
        '{
            val _bool = Bool.binaryMacroBool(~l, ~op.toExpr, ~r, ~b, ~prettifier)
            Assertions.assertionsHelper.macroAssert(_bool, ~clue, ~pos)      
         }
    }
  }
  res.seal[Assertion]

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions