Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Diagrams Macro Fix #2219

Merged
merged 8 commits into from Jan 3, 2023
Expand Up @@ -59,6 +59,16 @@ object DiagrammedExpr {
*/
def simpleExpr[T](expression: T, anchor: Int): DiagrammedExpr[T] = new DiagrammedSimpleExpr(expression, anchor)

/**
* Create by-name <code>DiagrammedExpr</code> that wraps <code>by-name</code> or <code>Function</code> expression.
* The created <code>DiagrammedExpr</code> will not be displayed in the diagram as value.
*
* @param expression the by-name expression value
* @param anchor the anchor of the expression
* @return a by-name <code>DiagrammedExpr</code>
*/
def byNameExpr[T](expression: => T, anchor: Int): DiagrammedExpr[T] = new DiagrammedByNameExpr(expression, anchor)

/**
* Create apply <code>DiagrammedExpr</code> that wraps <code>Apply</code> or <code>TypeApply</code> expression.
*
Expand Down Expand Up @@ -87,6 +97,11 @@ private[diagrams] class DiagrammedSimpleExpr[T](val value: T, val anchor: Int) e
def anchorValues = List(AnchorValue(anchor, value))
}

private[diagrams] class DiagrammedByNameExpr[T](valueFun: => T, val anchor: Int) extends DiagrammedExpr[T] {
lazy val value: T = valueFun
def anchorValues = List.empty
}

private[diagrams] class DiagrammedApplyExpr[T](qualifier: DiagrammedExpr[_], args: List[DiagrammedExpr[_]], val value: T, val anchor: Int) extends DiagrammedExpr[T] {

def anchorValues = {
Expand Down
Expand Up @@ -42,6 +42,10 @@ object DiagramsMacro {
case '{ $x: t } => '{ DiagrammedExpr.simpleExpr[t]($x, ${ getAnchor(term) } ) }.asTerm
}

def byNameExpr(term: Term): Term = term.asExpr match {
case '{ $x: t } => '{ DiagrammedExpr.byNameExpr[t]($x, ${ getAnchor(term) } ) }.asTerm
}

def xmlSugarExpr(term: Term): Term = term.asExpr match {
case '{ $x: t } => '{
DiagrammedExpr.simpleExpr[t]($x, ${
Expand Down Expand Up @@ -74,9 +78,9 @@ object DiagramsMacro {
case (Typed(Repeated(args, _), _), AppliedType(_, _)) =>
(diagrams :++ args.map(parse), others)
case (arg, ByNameType(_)) =>
(diagrams, others :+ arg)
(diagrams, others :+ byNameExpr(arg))
case (arg, tp) =>
if (tp.widen.typeSymbol.fullName.startsWith("scala.Function")) (diagrams, others :+ arg)
if (tp.widen.typeSymbol.fullName.startsWith("scala.Function")) (diagrams, others :+ byNameExpr(arg))
else (diagrams :+ parse(arg), others)
}
}
Expand Down Expand Up @@ -141,11 +145,13 @@ object DiagramsMacro {

let(Symbol.spliceOwner, left) { l =>
let(Symbol.spliceOwner, diagrams) { rs =>
l.asExpr match {
case '{ $left: DiagrammedExpr[t] } =>
val rights = rs.map(_.asExprOf[DiagrammedExpr[_]])
val res = Select.overloaded(Select.unique(l, "value"), op, Nil, diagrams.map(r => Select.unique(r, "value")) ++ others).asExprOf[r]
'{ DiagrammedExpr.applyExpr[r]($left, ${Expr.ofList(rights)}, $res, $anchor) }.asTerm
let(Symbol.spliceOwner, others) { os =>
l.asExpr match {
case '{ $left: DiagrammedExpr[t] } =>
val rights = rs.map(_.asExprOf[DiagrammedExpr[_]])
val res = Select.overloaded(Select.unique(l, "value"), op, Nil, rs.map(r => Select.unique(r, "value")) ++ os.map(o => Select.unique(o, "value"))).asExprOf[r]
'{ DiagrammedExpr.applyExpr[r]($left, ${Expr.ofList(rights)}, $res, $anchor) }.asTerm
}
}
}
}
Expand All @@ -160,11 +166,13 @@ object DiagramsMacro {

let(Symbol.spliceOwner, left) { l =>
let(Symbol.spliceOwner, diagrams) { rs =>
l.asExpr match {
case '{ $left: DiagrammedExpr[t] } =>
val rights = rs.map(_.asExprOf[DiagrammedExpr[_]])
val res = Select.overloaded(Select.unique(l, "value"), op, Nil, diagrams.map(r => Select.unique(r, "value")) ++ others).asExprOf[r]
'{ DiagrammedExpr.applyExpr[r]($left, ${Expr.ofList(rights)}, $res, $anchor) }.asTerm
let(Symbol.spliceOwner, others) { os =>
l.asExpr match {
case '{ $left: DiagrammedExpr[t] } =>
val rights = rs.map(_.asExprOf[DiagrammedExpr[_]])
val res = Select.overloaded(Select.unique(l, "value"), op, Nil, rs.map(r => Select.unique(r, "value")) ++ os.map(o => Select.unique(o, "value"))).asExprOf[r]
'{ DiagrammedExpr.applyExpr[r]($left, ${Expr.ofList(rights)}, $res, $anchor) }.asTerm
}
}
}
}
Expand Down Expand Up @@ -197,11 +205,13 @@ object DiagramsMacro {

let(Symbol.spliceOwner, left) { l =>
let(Symbol.spliceOwner, diagrams) { rs =>
l.asExpr match {
case '{ $left: DiagrammedExpr[t] } =>
val rights = rs.map(_.asExprOf[DiagrammedExpr[_]])
val res = Select.overloaded(Select.unique(l, "value"), op, targs.map(_.tpe), diagrams.map(r => Select.unique(r, "value")) ++ others).asExprOf[r]
'{ DiagrammedExpr.applyExpr[r]($left, ${Expr.ofList(rights)}, $res, $anchor) }.asTerm
let(Symbol.spliceOwner, others) { os =>
l.asExpr match {
case '{ $left: DiagrammedExpr[t] } =>
val rights = rs.map(_.asExprOf[DiagrammedExpr[_]])
val res = Select.overloaded(Select.unique(l, "value"), op, targs.map(_.tpe), rs.map(r => Select.unique(r, "value")) ++ os.map(o => Select.unique(o, "value"))).asExprOf[r]
'{ DiagrammedExpr.applyExpr[r]($left, ${Expr.ofList(rights)}, $res, $anchor) }.asTerm
}
}
}
}
Expand Down
Expand Up @@ -23,6 +23,12 @@ import org.scalatest.exceptions.TestFailedException
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers

// SKIP-SCALATESTJS,NATIVE-START
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.{Duration, SECONDS}
import scala.concurrent.{Await, Future}
// SKIP-SCALATESTJS,NATIVE-END

class DiagramsSpec extends AnyFunSpec with Matchers with Diagrams {

val fileName: String = "DiagramsSpec.scala"
Expand Down Expand Up @@ -2586,6 +2592,16 @@ class DiagramsSpec extends AnyFunSpec with Matchers with Diagrams {
|assert(java.math.BigInteger.ZERO == java.math.BigInteger.ZERO)
""".stripMargin)
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
assert(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42)
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END

}

describe("The assert(boolean, clue) method") {
Expand Down Expand Up @@ -5050,8 +5066,16 @@ class DiagramsSpec extends AnyFunSpec with Matchers with Diagrams {
|assert(java.math.BigDecimal.ZERO == java.math.BigDecimal.ZERO, "this is a clue")
""".stripMargin)
}
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
assert(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42, "this is a clue")
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END
}

describe("The assume(boolean) method") {
it("should do nothing when is used to check a == 3") {
Expand Down Expand Up @@ -7515,6 +7539,15 @@ class DiagramsSpec extends AnyFunSpec with Matchers with Diagrams {
|assume(java.math.BigDecimal.ZERO == java.math.BigDecimal.ZERO)
""".stripMargin)
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
assume(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42)
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END
}

describe("The assume(boolean, clue) method") {
Expand Down Expand Up @@ -9979,6 +10012,15 @@ class DiagramsSpec extends AnyFunSpec with Matchers with Diagrams {
|assume(java.math.BigDecimal.ZERO == java.math.BigDecimal.ZERO, "this is a clue")
""".stripMargin)
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
assume(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42, "this is a clue")
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END
}
}
}
Expand Up @@ -22,6 +22,12 @@ import org.scalatest.exceptions.TestCanceledException
import org.scalatest.exceptions.TestFailedException
import org.scalatest.funspec.AnyFunSpec

// SKIP-SCALATESTJS,NATIVE-START
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.{Duration, SECONDS}
import scala.concurrent.{Await, Future}
// SKIP-SCALATESTJS,NATIVE-END

class DirectDiagrammedAssertionsSpec extends AnyFunSpec with org.scalatest.matchers.should.Matchers {

val fileName: String = "DirectDiagrammedAssertionsSpec.scala"
Expand Down Expand Up @@ -2584,6 +2590,15 @@ class DirectDiagrammedAssertionsSpec extends AnyFunSpec with org.scalatest.match
|org.scalatest.diagrams.Diagrams.assert(java.math.BigInteger.ZERO == java.math.BigInteger.ZERO)
""".stripMargin)
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
org.scalatest.diagrams.Diagrams.assert(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42)
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END
}

describe("The org.scalatest.diagrams.Diagrams.assert(boolean, clue) method") {
Expand Down Expand Up @@ -5042,6 +5057,15 @@ class DirectDiagrammedAssertionsSpec extends AnyFunSpec with org.scalatest.match
|org.scalatest.diagrams.Diagrams.assert(java.math.BigDecimal.ZERO == java.math.BigDecimal.ZERO, "this is a clue")
""".stripMargin)
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
org.scalatest.diagrams.Diagrams.assert(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42, "this is a clue")
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END
}

describe("The org.scalatest.diagrams.Diagrams.assume(boolean) method") {
Expand Down Expand Up @@ -7500,6 +7524,15 @@ class DirectDiagrammedAssertionsSpec extends AnyFunSpec with org.scalatest.match
|org.scalatest.diagrams.Diagrams.assume(java.math.BigDecimal.ZERO == java.math.BigDecimal.ZERO)
""".stripMargin)
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
org.scalatest.diagrams.Diagrams.assume(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42)
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END
}

describe("The org.scalatest.diagrams.Diagrams.assume(boolean, clue) method") {
Expand Down Expand Up @@ -9958,6 +9991,15 @@ class DirectDiagrammedAssertionsSpec extends AnyFunSpec with org.scalatest.match
|org.scalatest.diagrams.Diagrams.assume(java.math.BigDecimal.ZERO == java.math.BigDecimal.ZERO, "this is a clue")
""".stripMargin)
}

// scala js and native does not support Await.result
// SKIP-SCALATESTJS,NATIVE-START
it("should invoke future one time only") {
var count = 0
org.scalatest.diagrams.Diagrams.assume(Await.result(Future { count = count + 1; 42 }, Duration(1, SECONDS)) == 42, "this is a clue")
count shouldBe 1
}
// SKIP-SCALATESTJS,NATIVE-END
}

}
Expand Down
Expand Up @@ -59,6 +59,16 @@ object DiagrammedExpr {
*/
def simpleExpr[T](expression: T, anchor: Int): DiagrammedExpr[T] = new DiagrammedSimpleExpr(expression, anchor)

/**
* Create by-name <code>DiagrammedExpr</code> that wraps <code>by-name</code> or <code>Function</code> expression.
* The created <code>DiagrammedExpr</code> will not be displayed in the diagram as value.
*
* @param expression the by-name expression value
* @param anchor the anchor of the expression
* @return a by-name <code>DiagrammedExpr</code>
*/
def byNameExpr[T](expression: => T, anchor: Int): DiagrammedExpr[() => T] = new DiagrammedByNameExpr(() => expression, anchor)

/**
* Create apply <code>DiagrammedExpr</code> that wraps <code>Apply</code> or <code>TypeApply</code> expression.
*
Expand Down Expand Up @@ -87,6 +97,11 @@ private[diagrams] class DiagrammedSimpleExpr[T](val value: T, val anchor: Int) e
def anchorValues = List(AnchorValue(anchor, value))
}

private[diagrams] class DiagrammedByNameExpr[T](valueFun: () => T, val anchor: Int) extends DiagrammedExpr[() => T] {
def value: () => T = valueFun
def anchorValues = List.empty
}

private[diagrams] class DiagrammedApplyExpr[T](qualifier: DiagrammedExpr[_], args: List[DiagrammedExpr[_]], val value: T, val anchor: Int) extends DiagrammedExpr[T] {

def anchorValues = {
Expand Down