From 017f48e00b863ecfc6a39c16c89a6ccb1dcde13d Mon Sep 17 00:00:00 2001 From: Dominik Gruntz Date: Wed, 28 Mar 2012 12:03:51 +0200 Subject: String interpolation bug fix This change fixes a bug in class StringContext.scala. Parts were not correctly added to the resulting string. This commit includes a test case which covers the example reported in the bug. Closes SI-5614. --- test/files/run/t5614.check | 3 +++ test/files/run/t5614.flags | 1 + test/files/run/t5614.scala | 5 +++++ 3 files changed, 9 insertions(+) create mode 100644 test/files/run/t5614.check create mode 100644 test/files/run/t5614.flags create mode 100644 test/files/run/t5614.scala (limited to 'test/files/run') diff --git a/test/files/run/t5614.check b/test/files/run/t5614.check new file mode 100644 index 0000000000..f659f2da3b --- /dev/null +++ b/test/files/run/t5614.check @@ -0,0 +1,3 @@ +3 +a +b diff --git a/test/files/run/t5614.flags b/test/files/run/t5614.flags new file mode 100644 index 0000000000..48fd867160 --- /dev/null +++ b/test/files/run/t5614.flags @@ -0,0 +1 @@ +-Xexperimental diff --git a/test/files/run/t5614.scala b/test/files/run/t5614.scala new file mode 100644 index 0000000000..7c85c33f12 --- /dev/null +++ b/test/files/run/t5614.scala @@ -0,0 +1,5 @@ +object Test extends App { + val str = s"a\nb" + println(str.length) + println(str) +} -- cgit v1.2.3 From 41c0b0b7b9bd5089e35e1bf32fbcb471a9c78641 Mon Sep 17 00:00:00 2001 From: Geoff Reedy Date: Tue, 20 Mar 2012 19:33:52 -0600 Subject: Fix for SI-5591. And test case for SI-5591. --- src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 2 +- test/files/run/phantomValueClass.check | 1 + test/files/run/phantomValueClass.scala | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 test/files/run/phantomValueClass.check create mode 100644 test/files/run/phantomValueClass.scala (limited to 'test/files/run') diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 5104518dd9..3515c1d521 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -68,7 +68,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { private def normalize(stpe: Type, clazz: Symbol): Type = stpe match { case PolyType(tparams, restpe) => - GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe, clazz)) + GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe.substSym(tparams takeRight clazz.typeParams.length, clazz.typeParams), clazz)) case MethodType(tparams, restpe) => restpe case _ => diff --git a/test/files/run/phantomValueClass.check b/test/files/run/phantomValueClass.check new file mode 100644 index 0000000000..323fae03f4 --- /dev/null +++ b/test/files/run/phantomValueClass.check @@ -0,0 +1 @@ +foobar diff --git a/test/files/run/phantomValueClass.scala b/test/files/run/phantomValueClass.scala new file mode 100644 index 0000000000..f6509f2189 --- /dev/null +++ b/test/files/run/phantomValueClass.scala @@ -0,0 +1,10 @@ +final class Phantom[A](val s: String) extends AnyVal { + def compose(p: Phantom[A]): Phantom[A] = new Phantom[A](s+p.s) +} + +object Test extends App { + val x = new Phantom[Int]("foo") + val y = new Phantom[Int]("bar") + val z = x compose y + println(z.s) +} -- cgit v1.2.3 From e593d8b9ed6d8d98c698d0a7dc47c3341d59c357 Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Tue, 27 Mar 2012 20:08:30 +0200 Subject: Make NumericRange# O(1) instead of O(n). It makes me a bit nervous that NumericRange[Int] will get different wrong values in overflow situations compared to Range due to the missing toLong though. It could probably need some investigation if reordering the operations can rule out wrong values, e. g. only fail when the fold also fails. Apart from that, it might make sense to just throw an exception if an overflow happens instead of silent overflow. --- src/library/scala/collection/immutable/NumericRange.scala | 7 +++++++ test/files/run/t4658.check | 12 ++++++------ test/files/run/t4658.scala | 14 +++----------- 3 files changed, 16 insertions(+), 17 deletions(-) (limited to 'test/files/run') diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index 65bd9ab6f2..0966fa035f 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -172,6 +172,13 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { try containsTyped(x.asInstanceOf[T]) catch { case _: ClassCastException => false } + final override def sum[B >: T](implicit num: Numeric[B]): B = { + import num.Ops + if (isEmpty) this.num fromInt 0 + else if (numRangeElements == 1) head + else ((this.num fromInt numRangeElements) * (head + last) / (this.num fromInt 2)) + } + override lazy val hashCode = super.hashCode() override def equals(other: Any) = other match { case x: NumericRange[_] => diff --git a/test/files/run/t4658.check b/test/files/run/t4658.check index 743b0faee3..bb6405175e 100644 --- a/test/files/run/t4658.check +++ b/test/files/run/t4658.check @@ -19,8 +19,8 @@ Ranges: -30 -10 IntRanges: -Disabled #1 -Disabled #2 +-1073741824 +-1073741824 0 0 55 @@ -39,8 +39,8 @@ Disabled #2 -30 -10 LongRanges: -Disabled #1 -Disabled #2 +2305843008139952128 +-2305843008139952128 0 0 55 @@ -59,8 +59,8 @@ Disabled #2 -30 -10 BigIntRanges: -Disabled #1 -Disabled #2 +2305843008139952128 +-2305843008139952128 0 0 55 diff --git a/test/files/run/t4658.scala b/test/files/run/t4658.scala index e1799fae9b..8c07c50694 100644 --- a/test/files/run/t4658.scala +++ b/test/files/run/t4658.scala @@ -20,22 +20,14 @@ object Test { def numericBigIntRanges = rangeData.map(r => if (r.inclusive) NumericRange.inclusive(BigInt(r.start), BigInt(r.end), BigInt(r.step)) else NumericRange(BigInt(r.start), BigInt(r.end), BigInt(r.step))) def main(args: Array[String]) { - // We drop the first two tests for all ranges which don't have a decent sum implementation, - // because it is just too slow. println("Ranges:") ranges.foreach{range => println(range.sum)} println("IntRanges:") - println("Disabled #1") - println("Disabled #2") - numericIntRanges.drop(2).foreach{range => println(range.sum)} + numericIntRanges.foreach{range => println(range.sum)} println("LongRanges:") - println("Disabled #1") - println("Disabled #2") - numericLongRanges.drop(2).foreach{range => println(range.sum)} + numericLongRanges.foreach{range => println(range.sum)} println("BigIntRanges:") - println("Disabled #1") - println("Disabled #2") - numericBigIntRanges.drop(2).foreach{range => println(range.sum)} + numericBigIntRanges.foreach{range => println(range.sum)} } } \ No newline at end of file -- cgit v1.2.3 From 174a75f78df9436884100768eff7ec938315280d Mon Sep 17 00:00:00 2001 From: Dmitry Nadezhin Date: Sun, 8 Apr 2012 14:43:07 +0400 Subject: SI-4540 Fix [RichDouble|RichFloat|RichLong].isValid[Byte|Short|Char|Int]. This commit fixes test cases mentioned in comment 03/Apr/12 to SI-4540. Methods are fixed in leaf classes RichDouble|RichFloat|RichLong. Their superclasses are not modified. File is-valid-num.scala contains commented tests of isValidLong|isValidFloat|isValidLong, but they are not added anywhere now. --- src/library/scala/runtime/RichDouble.scala | 12 ++ src/library/scala/runtime/RichFloat.scala | 12 ++ src/library/scala/runtime/RichLong.scala | 8 + test/files/run/is-valid-num.scala | 331 ++++++++++++++++++++++++----- 4 files changed, 305 insertions(+), 58 deletions(-) (limited to 'test/files/run') diff --git a/src/library/scala/runtime/RichDouble.scala b/src/library/scala/runtime/RichDouble.scala index 0a9cda40ec..f702b9e3da 100644 --- a/src/library/scala/runtime/RichDouble.scala +++ b/src/library/scala/runtime/RichDouble.scala @@ -35,4 +35,16 @@ final class RichDouble(val self: Double) extends FractionalProxy[Double] { def isInfinity: Boolean = java.lang.Double.isInfinite(self) def isPosInfinity: Boolean = isInfinity && self > 0.0 def isNegInfinity: Boolean = isInfinity && self < 0.0 + + override def isValidByte = self.toByte.toDouble == self + override def isValidShort = self.toShort.toDouble == self + override def isValidChar = self.toChar.toDouble == self + override def isValidInt = self.toInt.toDouble == self + // override def isValidLong = { val l = self.toLong; l.toDouble == self && l != Long.MaxValue } + // override def isValidFloat = self.toFloat.toDouble == self + // override def isValidDouble = !java.lang.Double.isNaN(self) + override def isWhole = { + val l = self.toLong + l.toDouble == self || l == Long.MaxValue && self < Double.PositiveInfinity || l == Long.MinValue && self > Double.NegativeInfinity + } } diff --git a/src/library/scala/runtime/RichFloat.scala b/src/library/scala/runtime/RichFloat.scala index c6478ec0c9..6b72a9dd55 100644 --- a/src/library/scala/runtime/RichFloat.scala +++ b/src/library/scala/runtime/RichFloat.scala @@ -36,4 +36,16 @@ final class RichFloat(val self: Float) extends FractionalProxy[Float] { def isInfinity: Boolean = java.lang.Float.isInfinite(self) def isPosInfinity: Boolean = isInfinity && self > 0.0f def isNegInfinity: Boolean = isInfinity && self < 0.0f + + override def isValidByte = self.toByte.toFloat == self + override def isValidShort = self.toShort.toFloat == self + override def isValidChar = self.toChar.toFloat == self + override def isValidInt = { val i = self.toInt; i.toFloat == self && i != Int.MaxValue } + // override def isValidLong = { val l = self.toLong; l.toFloat == self && l != Long.MaxValue } + // override def isValidFloat = !java.lang.Float.isNaN(self) + // override def isValidDouble = !java.lang.Float.isNaN(self) + override def isWhole = { + val l = self.toLong + l.toFloat == self || l == Long.MaxValue && self < Float.PositiveInfinity || l == Long.MinValue && self > Float.NegativeInfinity + } } diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala index f93d9459d1..5784934ffd 100644 --- a/src/library/scala/runtime/RichLong.scala +++ b/src/library/scala/runtime/RichLong.scala @@ -12,4 +12,12 @@ final class RichLong(val self: Long) extends IntegralProxy[Long] { def toBinaryString: String = java.lang.Long.toBinaryString(self) def toHexString: String = java.lang.Long.toHexString(self) def toOctalString: String = java.lang.Long.toOctalString(self) + + override def isValidByte = self.toByte.toLong == self + override def isValidShort = self.toShort.toLong == self + override def isValidChar = self.toChar.toLong == self + override def isValidInt = self.toInt.toLong == self + // override def isValidLong = true + // override def isValidFloat = self.toFloat.toLong == self && self != Long.MaxValue + // override def isValidDouble = self.toDouble.toLong == self && self != Long.MaxValue } diff --git a/test/files/run/is-valid-num.scala b/test/files/run/is-valid-num.scala index 9c43e98911..402eff99d6 100644 --- a/test/files/run/is-valid-num.scala +++ b/test/files/run/is-valid-num.scala @@ -3,95 +3,310 @@ object Test { def y = BigDecimal("" + (Short.MaxValue + 1) + ".0") def y1 = BigDecimal("0.1") def y2 = BigDecimal("0.5") - + def l1 = Int.MaxValue.toLong + 1 def l2 = Int.MinValue.toLong - 1 def main(args: Array[String]): Unit = { +// assert(x.isWhole, x) assert(!x.isValidDouble, x) assert(!x.isValidFloat, x) assert(!x.isValidLong, x) assert(!x.isValidInt, x) assert(!x.isValidChar, x) + assert(!x.isValidShort, x) assert(!x.isValidByte, x) +// assert(y.isWhole, y) assert(!y.isValidShort, y) assert(y.isValidChar, y) assert(y.isValidInt, y) assert(y.isValidFloat, y) assert(y.isValidDouble, y) + assert(y.isValidLong, y) + assert(!y.isValidByte, y) +// assert(!y1.isWhole) assert(!y1.isValidLong, y1) assert(!y1.isValidFloat, y1) assert(!y1.isValidDouble, y1) + assert(!y1.isValidInt, y1) + assert(!y1.isValidChar, y1) + assert(!y1.isValidShort, y1) + assert(!y1.isValidByte, y1) assert(!y2.isValidLong, y2) assert(y2.isValidFloat, y2) assert(y2.isValidDouble, y2) - testBigIntIsFloat() - testBigIntIsDouble() - assert(!l1.isValidInt && (l1 - 1).isValidInt, l1) assert(!l2.isValidInt && (l2 + 1).isValidInt, l2) + + testBigInts() + testNonWholeDoubles() + testNaNs() + } + + def testBigInts() { + def biExp2(e: Int) = BigInt(1) << e + def checkBigInt2(bi: BigInt) { checkBigInt(-bi); checkBigInt(bi) } + + val pf = 24 + val pd = 53 + + checkBigInt(BigInt(0)) + checkBigInt2(biExp2(0)) + + checkBigInt2(biExp2(7) - 1) + checkBigInt2(biExp2(7)) + checkBigInt2(biExp2(7) + 1) + + checkBigInt2(biExp2(8) - 1) + checkBigInt2(biExp2(8)) + checkBigInt2(biExp2(8) + 1) + + checkBigInt2(biExp2(15) - 1) + checkBigInt2(biExp2(15)) + checkBigInt2(biExp2(15) + 1) + + checkBigInt2(biExp2(16) - 1) + checkBigInt2(biExp2(16)) + checkBigInt2(biExp2(16) + 1) + + checkBigInt2(biExp2(pf) - 1) + checkBigInt2(biExp2(pf)) + checkBigInt2(biExp2(pf) + 1) + checkBigInt2(biExp2(pf) + 2) + checkBigInt2(biExp2(pf) - 2) + checkBigInt2(biExp2(pf + 1) - 1) + checkBigInt2(biExp2(pf + 1)) + checkBigInt2(biExp2(pf + 1) + 1) + checkBigInt2(biExp2(pf + 1) + 2) + checkBigInt2(biExp2(pf + 1) + 3) + checkBigInt2(biExp2(pf + 1) + 4) + + checkBigInt2(biExp2(31) - 1) + checkBigInt2(biExp2(31)) + checkBigInt2(biExp2(31) + 1) + + checkBigInt2(biExp2(32) - 1) + checkBigInt2(biExp2(32)) + checkBigInt2(biExp2(32) + 1) + checkBigInt2(biExp2(32) + biExp2(64 - pf)) + checkBigInt2(biExp2(32) + biExp2(64 - pf + 1)) + + checkBigInt2(biExp2(pd) - 1) + checkBigInt2(biExp2(pd)) + checkBigInt2(biExp2(pd) + 1) + checkBigInt2(biExp2(pd) + 2) + checkBigInt2(biExp2(pd + 1) - 2) + checkBigInt2(biExp2(pd + 1) - 1) + checkBigInt2(biExp2(pd + 1)) + checkBigInt2(biExp2(pd + 1) + 1) + checkBigInt2(biExp2(pd + 1) + 2) + checkBigInt2(biExp2(pd + 1) + 3) + checkBigInt2(biExp2(pd + 1) + 4) + + checkBigInt2(biExp2(63) - 1) + checkBigInt2(biExp2(63)) + checkBigInt2(biExp2(63) + 1) + checkBigInt2(biExp2(63) + biExp2(63 - pd)) + checkBigInt2(biExp2(63) + biExp2(63 - pd + 1)) + checkBigInt2(biExp2(63) + biExp2(63 - pf)) + checkBigInt2(biExp2(63) + biExp2(63 - pf + 1)) + + checkBigInt2(biExp2(64) - 1) + checkBigInt2(biExp2(64)) + checkBigInt2(biExp2(64) + 1) + checkBigInt2(biExp2(64) + biExp2(64 - pd)) + checkBigInt2(biExp2(64) + biExp2(64 - pd + 1)) + checkBigInt2(biExp2(64) + biExp2(64 - pf)) + checkBigInt2(biExp2(64) + biExp2(64 - pf + 1)) + + checkBigInt2(biExp2(127)) + checkBigInt2(biExp2(128) - biExp2(128 - pf)) + checkBigInt2(biExp2(128) - biExp2(128 - pf - 1)) + checkBigInt2(biExp2(128)) + + checkBigInt2(biExp2(1023)) + checkBigInt2(biExp2(1024) - biExp2(1024 - pd)) + checkBigInt2(biExp2(1024) - biExp2(1024 - pd - 1)) + checkBigInt2(biExp2(1024)) + } + + def testNonWholeDoubles() { + checkNonWholeDouble(0.5) + checkNonWholeDouble(-math.E) + checkNonWholeDouble((1L << 51).toDouble + 0.5) + checkNonWholeDouble((1L << 23).toDouble + 0.5) + checkNonWholeDouble(Double.PositiveInfinity) + checkNonWholeDouble(Double.NegativeInfinity) } - def biExp2(e: Int) = BigInt(1) << e + def testNaNs() { + assert(!Double.NaN.isWhole, Double.NaN) +// assert(!Double.NaN.isValidDouble, Double.NaN) +// assert(!Double.NaN.isValidFloat, Double.NaN) +// assert(!Double.NaN.isValidLong, Double.NaN) + assert(!Double.NaN.isValidInt, Double.NaN) + assert(!Double.NaN.isValidChar, Double.NaN) + assert(!Double.NaN.isValidShort, Double.NaN) + assert(!Double.NaN.isValidByte, Double.NaN) - def testBigIntIsFloat() { - val prec = 24 - def checkFloatT(x: BigInt) = { - assert(x.isValidFloat, x) - assert((-x).isValidFloat, -x) + assert(!Float.NaN.isWhole, Float.NaN) +// assert(!Float.NaN.isValidDouble, Float.NaN) +// assert(!Float.NaN.isValidFloat, Float.NaN) +// assert(!Float.NaN.isValidLong, Float.NaN) + assert(!Float.NaN.isValidInt, Float.NaN) + assert(!Float.NaN.isValidChar, Float.NaN) + assert(!Float.NaN.isValidShort, Float.NaN) + assert(!Float.NaN.isValidByte, Float.NaN) + } + + def checkNonWholeDouble(d: Double) { + val f = d.toFloat + val isFloat = f == d + + if (!d.isInfinity) { + val bd = BigDecimal(new java.math.BigDecimal(d)) +// assert(!bd.isWhole, bd) + assert(bd.isValidDouble, bd) + assert(bd.isValidFloat == isFloat, bd) + assert(!bd.isValidLong, bd) + assert(!bd.isValidInt, bd) + assert(!bd.isValidChar, bd) + assert(!bd.isValidShort, bd) + assert(!bd.isValidByte, bd) + } + + assert(!d.isWhole, d) +// assert(d.isValidDouble, d) +// assert(d.isValidFloat == isFloat, d) +// assert(!d.isValidLong, d) + assert(!d.isValidInt, d) + assert(!d.isValidChar, d) + assert(!d.isValidShort, d) + assert(!d.isValidByte, d) + + if (isFloat) { + assert(!f.isWhole, f) +// assert(f.isValidDouble, f) +// assert(f.isValidFloat == isFloat, f) +// assert(!f.isValidLong, f) + assert(!f.isValidInt, f) + assert(!f.isValidChar, f) + assert(!f.isValidShort, f) + assert(!f.isValidByte, f) } - def checkFloatF(x: BigInt) = { - assert(!x.isValidFloat, x) - assert(!(-x).isValidFloat, -x) - } - checkFloatT(biExp2(prec) - 1) - checkFloatT(biExp2(prec)) - checkFloatF(biExp2(prec) + 1) - checkFloatT(biExp2(prec) + 2) - checkFloatT(biExp2(prec) - 2) - checkFloatF(biExp2(prec + 1) - 1) - checkFloatT(biExp2(prec + 1)) - checkFloatF(biExp2(prec + 1) + 1) - checkFloatF(biExp2(prec + 1) + 2) - checkFloatF(biExp2(prec + 1) + 3) - checkFloatT(biExp2(prec + 1) + 4) - checkFloatT(biExp2(64)) - checkFloatF(biExp2(64) + biExp2(64 - prec)) - checkFloatT(biExp2(64) + biExp2(64 - prec + 1)) - checkFloatT(biExp2(127)) - checkFloatT(biExp2(128) - biExp2(128 - prec)) - checkFloatF(biExp2(128) - biExp2(128 - prec - 1)) - checkFloatF(biExp2(128)) } - def testBigIntIsDouble() { - val prec = 53 - def checkDoubleT(x: BigInt) = { - assert(x.isValidDouble, x) - assert((-x).isValidDouble, -x) + def checkBigInt(bi: BigInt) { + val bd = BigDecimal(bi, java.math.MathContext.UNLIMITED) + val isByte = bi >= Byte.MinValue && bi <= Byte.MaxValue + val isShort = bi >= Short.MinValue && bi <= Short.MaxValue + val isChar = bi >= Char.MinValue && bi <= Char.MaxValue + val isInt = bi >= Int.MinValue && bi <= Int.MaxValue + val isLong = bi >= Long.MinValue && bi <= Long.MaxValue + val isFloat = !bi.toFloat.isInfinity && bd.compare(BigDecimal(new java.math.BigDecimal(bi.toFloat))) == 0 + val isDouble = !bi.toDouble.isInfinity && bd.compare(BigDecimal(new java.math.BigDecimal(bi.toDouble))) == 0 + +// assert(bd.isWhole, bd) + assert(bd.isValidDouble == isDouble, bd) + assert(bd.isValidFloat == isFloat, bd) + assert(bd.isValidLong == isLong, bd) + assert(bd.isValidInt == isInt, bd) + assert(bd.isValidChar == isChar, bd) + assert(bd.isValidShort == isShort, bd) + assert(bd.isValidByte == isByte, bd) + +// assert(bi.isWhole, bi) + assert(bi.isValidDouble == isDouble, bi) + assert(bi.isValidFloat == isFloat, bi) + assert(bi.isValidLong == isLong, bi) + assert(bi.isValidInt == isInt, bi) + assert(bi.isValidChar == isChar, bi) + assert(bi.isValidShort == isShort, bi) + assert(bi.isValidByte == isByte, bi) + + if (isDouble) { + val d = bi.toDouble + assert(d.isWhole, d) +// assert(d.isValidDouble == isDouble, d) +// assert(d.isValidFloat == isFloat, d) +// assert(d.isValidLong == isLong, d) + assert(d.isValidInt == isInt, d) + assert(d.isValidChar == isChar, d) + assert(d.isValidShort == isShort, d) + assert(d.isValidByte == isByte, d) + } + + if (isFloat) { + val f = bi.toFloat + assert(f.isWhole, f) +// assert(f.isValidDouble == isDouble, f) +// assert(f.isValidFloat == isFloat, f) +// assert(f.isValidLong == isLong, f) + assert(f.isValidInt == isInt, f) + assert(f.isValidChar == isChar, f) + assert(f.isValidShort == isShort, f) + assert(f.isValidByte == isByte, f) + } + + if (isLong) { + val l = bi.toLong + assert(l.isWhole, l) +// assert(l.isValidDouble == isDouble, l) +// assert(l.isValidFloat == isFloat, l) +// assert(l.isValidLong == isLong, l) + assert(l.isValidInt == isInt, l) + assert(l.isValidChar == isChar, l) + assert(l.isValidShort == isShort, l) + assert(l.isValidByte == isByte, l) + } + + if (isInt) { + val i = bi.toInt + assert(i.isWhole, i) +// assert(i.isValidDouble == isDouble, i) +// assert(i.isValidFloat == isFloat, i) +// assert(i.isValidLong == isLong, i) + assert(i.isValidInt == isInt, i) + assert(i.isValidChar == isChar, i) + assert(i.isValidShort == isShort, i) + assert(i.isValidByte == isByte, i) } - def checkDoubleF(x: BigInt) = { - assert(!x.isValidDouble, x) - assert(!(-x).isValidDouble, -x) + + if (isChar) { + val c = bi.toChar + assert(c.isWhole, c) +// assert(c.isValidDouble == isDouble, c) +// assert(c.isValidFloat == isFloat, c) +// assert(c.isValidLong == isLong, c) + assert(c.isValidInt == isInt, c) + assert(c.isValidChar == isChar, c) + assert(c.isValidShort == isShort, c) + assert(c.isValidByte == isByte, c) + } + + if (isShort) { + val s = bi.toShort + assert(s.isWhole, s) +// assert(s.isValidDouble == isDouble, s) +// assert(s.isValidFloat == isFloat, s) +// assert(s.isValidLong == isLong, s) + assert(s.isValidInt == isInt, s) + assert(s.isValidChar == isChar, s) + assert(s.isValidShort == isShort, s) + assert(s.isValidByte == isByte, s) + } + + if (isByte) { + val b = bi.toByte + assert(b.isWhole, b) +// assert(b.isValidDouble == isDouble, b) +// assert(b.isValidFloat == isFloat, b) +// assert(b.isValidLong == isLong, b) + assert(b.isValidInt == isInt, b) + assert(b.isValidChar == isChar, b) + assert(b.isValidShort == isShort, b) + assert(b.isValidByte == isByte, b) } - checkDoubleT(biExp2(prec) - 1) - checkDoubleT(biExp2(prec)) - checkDoubleF(biExp2(prec) + 1) - checkDoubleT(biExp2(prec) + 2) - checkDoubleT(biExp2(prec + 1) - 2) - checkDoubleF(biExp2(prec + 1) - 1) - checkDoubleT(biExp2(prec + 1)) - checkDoubleF(biExp2(prec + 1) + 1) - checkDoubleF(biExp2(prec + 1) + 2) - checkDoubleF(biExp2(prec + 1) + 3) - checkDoubleT(biExp2(prec + 1) + 4) - checkDoubleT(biExp2(64)) - checkDoubleF(biExp2(64) + biExp2(64 - prec)) - checkDoubleT(biExp2(64) + biExp2(64 - prec + 1)) - checkDoubleT(biExp2(1023)) - checkDoubleT(biExp2(1024) - biExp2(1024 - prec)) - checkDoubleF(biExp2(1024) - biExp2(1024 - prec - 1)) - checkDoubleF(biExp2(1024)) } } -- cgit v1.2.3 From bed400c5a8d4fc5f5ee4b270f757cdfae94c3f6a Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 9 Apr 2012 14:23:13 -0700 Subject: Cleaning up some repl mechanisms. --- src/compiler/scala/reflect/internal/Symbols.scala | 2 +- .../scala/tools/nsc/interpreter/ExprTyper.scala | 2 +- .../scala/tools/nsc/interpreter/ILoop.scala | 8 +- .../scala/tools/nsc/interpreter/IMain.scala | 94 +++++++++++++++------- .../scala/tools/nsc/interpreter/Naming.scala | 4 +- .../scala/tools/nsc/interpreter/ReplVals.scala | 1 + test/files/run/repl-reset.check | 2 +- 7 files changed, 79 insertions(+), 34 deletions(-) (limited to 'test/files/run') diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index e6f03faa42..04bdb0f4ad 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -600,7 +600,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def ownerOfNewSymbols = this final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol - final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass + final def isOverridableMember = !(isClass || isEffectivelyFinal) && (this ne NoSymbol) && owner.isClass /** Does this symbol denote a wrapper created by the repl? */ final def isInterpreterWrapper = ( diff --git a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala index 68c8f2fdb8..a2ce8439de 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala @@ -124,7 +124,7 @@ trait ExprTyper { val decls = sym.tpe.decls.toList filterNot (x => x.isConstructor || x.isPrivate || (x.name.toString contains "$")) repltrace("decls: " + decls) if (decls.isEmpty) NoType - else typeCleanser(sym, decls.last.name) + else cleanMemberDecl(sym, decls.last.name) } case _ => NoType diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index e1ea69842f..108d4377a8 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -815,7 +815,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) interpretStartingWith(intp.mostRecentVar + code) } else { - def runCompletion = in.completion execute code map (intp bindValue _) + def runCompletion = + try in.completion execute code map (intp bindValue _) + catch { case ex: Exception => None } + /** Due to my accidentally letting file completion execution sneak ahead * of actual parsing this now operates in such a way that the scala * interpretation always wins. However to avoid losing useful file @@ -881,6 +884,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) case x => x } } + // Bind intp somewhere out of the regular namespace where + // we can get at it in generated code. + addThunk(intp.quietBind("$intp" -> intp)) loadFiles(settings) // it is broken on startup; go ahead and exit diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 9a12bc1471..0c64bb2901 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -93,6 +93,11 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends private var _lineManager: Line.Manager = null // logic for individual lines private val _compiler: Global = newCompiler(settings, reporter) // our private compiler + private val nextReqId = { + var counter = 0 + () => { counter += 1 ; counter } + } + def compilerClasspath: Seq[URL] = ( if (isInitializeComplete) global.classPath.asURLs else new PathResolver(settings).result.asURLs // the compiler's classpath @@ -457,7 +462,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** Build a request from the user. `trees` is `line` after being parsed. */ - private def buildRequest(line: String, trees: List[Tree]): Request = new Request(line, trees) + private def buildRequest(line: String, trees: List[Tree]): Request = { + executingRequest = new Request(line, trees) + executingRequest + } // rewriting "5 // foo" to "val x = { 5 // foo }" creates broken code because // the close brace is commented out. Strip single-line comments. @@ -556,17 +564,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends Right(buildRequest(line, trees)) } - def typeCleanser(sym: Symbol, memberName: Name): Type = { - // the types are all =>T; remove the => - val tp1 = afterTyper(sym.info.nonPrivateDecl(memberName).tpe match { - case NullaryMethodType(tp) => tp - case tp => tp - }) - // normalize non-public types so we don't see protected aliases like Self - afterTyper(tp1 match { - case TypeRef(_, sym, _) if !sym.isPublic => tp1.normalize - case tp => tp - }) + // normalize non-public types so we don't see protected aliases like Self + def normalizeNonPublic(tp: Type) = tp match { + case TypeRef(_, sym, _) if sym.isAliasType && !sym.isPublic => tp.normalize + case _ => tp } /** @@ -623,7 +624,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends * @param value the object value to bind to it * @return an indication of whether the binding succeeded */ - def bind(name: String, boundType: String, value: Any): IR.Result = { + def bind(name: String, boundType: String, value: Any, modifiers: List[String] = Nil): IR.Result = { val bindRep = new ReadEvalPrint() val run = bindRep.compile(""" |object %s { @@ -639,7 +640,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends IR.Error case Right(_) => - val line = "val %s = %s.value".format(name, bindRep.evalPath) + val line = "%sval %s = %s.value".format(modifiers map (_ + " ") mkString, name, bindRep.evalPath) repldbg("Interpreting: " + line) interpret(line) } @@ -824,7 +825,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends case xs => sys.error("Internal error: eval object " + evalClass + ", " + xs.mkString("\n", "\n", "")) } private def compileAndSaveRun(label: String, code: String) = { - showCodeIfDebugging(packaged(code)) + showCodeIfDebugging(code) val (success, run) = compileSourcesKeepingRun(new BatchSourceFile(label, packaged(code))) lastRun = run success @@ -834,6 +835,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** One line of code submitted by the user for interpretation */ // private class Request(val line: String, val trees: List[Tree]) { + val reqId = nextReqId() val lineRep = new ReadEvalPrint() private var _originalLine: String = null @@ -882,14 +884,31 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** generate the source code for the object that computes this request */ private object ObjectSourceCode extends CodeAssembler[MemberHandler] { + def path = pathToTerm("$intp") + def envLines = { + if (!isReplPower) Nil // power mode only for now + // $intp is not bound; punt, but include the line. + else if (path == "$intp") List( + "def $line = " + tquoted(originalLine), + "def $trees = Nil" + ) + else List( + "def $line = " + tquoted(originalLine), + "def $req = %s.requestForReqId(%s).orNull".format(path, reqId), + "def $trees = if ($req eq null) Nil else $req.trees".format(lineRep.readName, path, reqId) + ) + } + val preamble = """ |object %s { - |%s%s - """.stripMargin.format(lineRep.readName, importsPreamble, indentCode(toCompute)) + |%s%s%s + """.stripMargin.format(lineRep.readName, envLines.map(" " + _ + ";\n").mkString, importsPreamble, indentCode(toCompute)) val postamble = importsTrailer + "\n}" val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this } + def tquoted(s: String) = "\"\"\"" + s + "\"\"\"" + private object ResultObjectSourceCode extends CodeAssembler[MemberHandler] { /** We only want to generate this code when the result * is a value which can be referred to as-is. @@ -959,8 +978,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def lookupTypeOf(name: Name) = typeOf.getOrElse(name, typeOf(global.encode(name.toString))) def simpleNameOfType(name: TypeName) = (compilerTypeOf get name) map (_.typeSymbol.simpleName) - private def typeMap[T](f: Type => T): Map[Name, T] = - termNames ++ typeNames map (x => x -> f(typeCleanser(resultSymbol, x))) toMap + private def typeMap[T](f: Type => T): Map[Name, T] = { + termNames ++ typeNames map (x => x -> f(cleanMemberDecl(resultSymbol, x))) toMap + } /** Types of variables defined by this request. */ lazy val compilerTypeOf = typeMap[Type](x => x) @@ -1023,6 +1043,13 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends getOrElse Nil ) + def treesForRequestId(id: Int): List[Tree] = + requestForReqId(id).toList flatMap (_.trees) + + def requestForReqId(id: Int): Option[Request] = + if (executingRequest != null && executingRequest.reqId == id) Some(executingRequest) + else prevRequests find (_.reqId == id) + def requestForName(name: Name): Option[Request] = { assert(definedNameMap != null, "definedNameMap is null") definedNameMap get name @@ -1072,6 +1099,14 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends else NoType } } + def cleanMemberDecl(owner: Symbol, member: Name): Type = afterTyper { + normalizeNonPublic { + owner.info.nonPrivateDecl(member).tpe match { + case NullaryMethodType(tp) => tp + case tp => tp + } + } + } object replTokens extends { val global: imain.global.type = imain.global @@ -1118,15 +1153,18 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def apply[T: ClassManifest] : Symbol = apply(classManifest[T].erasure.getName) /** the previous requests this interpreter has processed */ - private lazy val prevRequests = mutable.ListBuffer[Request]() - private lazy val referencedNameMap = mutable.Map[Name, Request]() - private lazy val definedNameMap = mutable.Map[Name, Request]() - private lazy val directlyBoundNames = mutable.Set[Name]() - protected def prevRequestList = prevRequests.toList - private def allHandlers = prevRequestList flatMap (_.handlers) - def allSeenTypes = prevRequestList flatMap (_.typeOf.values.toList) distinct - def allImplicits = allHandlers filter (_.definesImplicit) flatMap (_.definedNames) - def importHandlers = allHandlers collect { case x: ImportHandler => x } + private var executingRequest: Request = _ + private val prevRequests = mutable.ListBuffer[Request]() + private val referencedNameMap = mutable.Map[Name, Request]() + private val definedNameMap = mutable.Map[Name, Request]() + private val directlyBoundNames = mutable.Set[Name]() + + private def allHandlers = prevRequestList flatMap (_.handlers) + def lastRequest = if (prevRequests.isEmpty) null else prevRequests.last + def prevRequestList = prevRequests.toList + def allSeenTypes = prevRequestList flatMap (_.typeOf.values.toList) distinct + def allImplicits = allHandlers filter (_.definesImplicit) flatMap (_.definedNames) + def importHandlers = allHandlers collect { case x: ImportHandler => x } def visibleTermNames: List[Name] = definedTerms ++ importedTerms distinct diff --git a/src/compiler/scala/tools/nsc/interpreter/Naming.scala b/src/compiler/scala/tools/nsc/interpreter/Naming.scala index 19266442cb..c3f51c74ec 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Naming.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Naming.scala @@ -41,10 +41,10 @@ trait Naming { private def removeIWPackages(s: String) = s.replaceAll("""\$iw[$.]""", "") trait SessionNames { - // All values are configurable by passing e.g. -Dscala.repl.naming.read=XXX + // All values are configurable by passing e.g. -Dscala.repl.name.read=XXX final def propOr(name: String): String = propOr(name, "$" + name) final def propOr(name: String, default: String): String = - sys.props.getOrElse("scala.repl.naming." + name, default) + sys.props.getOrElse("scala.repl.name." + name, default) // Prefixes used in repl machinery. Default to $line, $read, etc. def line = propOr("line") diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index c5d04b17c9..ad6e8dc48d 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -31,6 +31,7 @@ class StdReplVals(final val r: ILoop) extends ReplVals { power.unit("").asInstanceOf[analyzer.global.CompilationUnit] ) ) + def lastRequest = intp.lastRequest final lazy val replImplicits = new power.Implicits2 { import intp.global._ diff --git a/test/files/run/repl-reset.check b/test/files/run/repl-reset.check index 8c21ab067a..7256b851bb 100644 --- a/test/files/run/repl-reset.check +++ b/test/files/run/repl-reset.check @@ -28,7 +28,7 @@ val x3 = 3 case class BippyBungus() x1 + x2 + x3 -Forgetting all expression results and named terms: BippyBungus, x1, x2, x3 +Forgetting all expression results and named terms: $intp, BippyBungus, x1, x2, x3 Forgetting defined types: BippyBungus scala> x1 + x2 + x3 -- cgit v1.2.3 From 00e9446bfca132bf6ec89b9d75a2b90ad5ea098d Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 10 Apr 2012 06:30:08 -0700 Subject: Fix for SI-5648. More care in warning about bad comparisons. --- src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 11 +++++++++-- test/files/run/t5648.check | 4 ++++ test/files/run/t5648.flags | 1 + test/files/run/t5648.scala | 10 ++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/files/run/t5648.check create mode 100644 test/files/run/t5648.flags create mode 100644 test/files/run/t5648.scala (limited to 'test/files/run') diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 68a722aab4..806ee480f0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1053,10 +1053,17 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R /** Symbols which limit the warnings we can issue since they may be value types */ val isMaybeValue = Set(AnyClass, AnyRefClass, AnyValClass, ObjectClass, ComparableClass, JavaSerializableClass) - // Whether def equals(other: Any) is overridden or synthetic + // Whether def equals(other: Any) has known behavior: it is the default + // inherited from java.lang.Object, or it is a synthetically generated + // case equals. TODO - more cases are warnable if the target is a synthetic + // equals. def isUsingWarnableEquals = { val m = receiver.info.member(nme.equals_) - (m == Object_equals) || (m == Any_equals) || (m.isSynthetic && m.owner.isCase) + def n = actual.info.member(nme.equals_) + ( (m == Object_equals) + || (m == Any_equals) + || (m.isSynthetic && m.owner.isCase && !n.owner.isCase) + ) } // Whether this == or != is one of those defined in Any/AnyRef or an overload from elsewhere. def isUsingDefaultScalaOp = { diff --git a/test/files/run/t5648.check b/test/files/run/t5648.check new file mode 100644 index 0000000000..1140ff52e2 --- /dev/null +++ b/test/files/run/t5648.check @@ -0,0 +1,4 @@ +true +true +true +true diff --git a/test/files/run/t5648.flags b/test/files/run/t5648.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/run/t5648.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/run/t5648.scala b/test/files/run/t5648.scala new file mode 100644 index 0000000000..c5cea9e1cb --- /dev/null +++ b/test/files/run/t5648.scala @@ -0,0 +1,10 @@ +case class C(val s: Int*) + +object Test { + def main(args: Array[String]): Unit = { + println(new C(1, 3, 7) == new C(1, 3, 7)) + println(new C(1, 3, 7) == C(1, 3, 7)) + println(C(1, 3, 7) == new C(1, 3, 7)) + println(C(1, 3, 7) == C(1, 3, 7)) + } +} -- cgit v1.2.3 From 814cf34fb00f9ccb001249f4b3445ebc4f9942c9 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 12 Apr 2012 01:59:46 +0200 Subject: Next generation of macros Implements SIP 16: Self-cleaning macros: http://bit.ly/wjjXTZ Features: * Macro defs * Reification * Type tags * Manifests aliased to type tags * Extended reflection API * Several hundred tests * 1111 changed files Not yet implemented: * Reification of refined types * Expr.value splicing * Named and default macro expansions * Intricacies of interaction between macros and implicits * Emission of debug information for macros (compliant with JSR-45) Dedicated to Yuri Alekseyevich Gagarin --- build.xml | 2 +- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- .../scala/reflect/internal/AnnotationInfos.scala | 17 +- .../scala/reflect/internal/CapturedVariables.scala | 36 + .../scala/reflect/internal/Constants.scala | 10 +- .../scala/reflect/internal/Definitions.scala | 96 +- src/compiler/scala/reflect/internal/FreeVars.scala | 60 + .../scala/reflect/internal/Importers.scala | 39 +- .../scala/reflect/internal/NameManglers.scala | 7 +- .../scala/reflect/internal/Positions.scala | 38 +- .../scala/reflect/internal/Reporters.scala | 74 ++ src/compiler/scala/reflect/internal/Required.scala | 2 - src/compiler/scala/reflect/internal/StdNames.scala | 126 +- .../scala/reflect/internal/SymbolTable.scala | 6 +- src/compiler/scala/reflect/internal/Symbols.scala | 89 +- .../scala/reflect/internal/TreeBuildUtil.scala | 62 + src/compiler/scala/reflect/internal/TreeGen.scala | 2 +- src/compiler/scala/reflect/internal/TreeInfo.scala | 194 +++ .../scala/reflect/internal/TreePrinters.scala | 5 +- src/compiler/scala/reflect/internal/Trees.scala | 77 +- src/compiler/scala/reflect/internal/Types.scala | 53 +- .../scala/reflect/makro/runtime/Aliases.scala | 21 + .../reflect/makro/runtime/CapturedVariables.scala | 14 + .../scala/reflect/makro/runtime/Context.scala | 26 + .../scala/reflect/makro/runtime/Enclosures.scala | 36 + .../scala/reflect/makro/runtime/Errors.scala | 6 + .../reflect/makro/runtime/Infrastructure.scala | 34 + .../scala/reflect/makro/runtime/Names.scala | 20 + .../scala/reflect/makro/runtime/Reifiers.scala | 69 + .../scala/reflect/makro/runtime/Reporters.scala | 44 + .../scala/reflect/makro/runtime/Settings.scala | 36 + .../scala/reflect/makro/runtime/Symbols.scala | 8 + .../scala/reflect/makro/runtime/Typers.scala | 78 ++ .../scala/reflect/makro/runtime/Util.scala | 34 + src/compiler/scala/reflect/reify/Errors.scala | 63 + .../scala/reflect/reify/NodePrinters.scala | 111 ++ src/compiler/scala/reflect/reify/Phases.scala | 42 + src/compiler/scala/reflect/reify/Reifiers.scala | 154 +++ .../scala/reflect/reify/codegen/Names.scala | 15 + .../scala/reflect/reify/codegen/Positions.scala | 18 + .../scala/reflect/reify/codegen/Symbols.scala | 111 ++ .../scala/reflect/reify/codegen/Trees.scala | 220 ++++ .../scala/reflect/reify/codegen/Types.scala | 226 ++++ .../scala/reflect/reify/codegen/Util.scala | 112 ++ src/compiler/scala/reflect/reify/package.scala | 22 + .../scala/reflect/reify/phases/Calculate.scala | 61 + .../scala/reflect/reify/phases/Metalevels.scala | 148 +++ .../scala/reflect/reify/phases/Reify.scala | 42 + .../scala/reflect/reify/phases/Reshape.scala | 296 +++++ .../scala/reflect/runtime/ClassLoaders.scala | 25 + .../scala/reflect/runtime/ConversionUtil.scala | 1 + .../scala/reflect/runtime/JavaToScala.scala | 209 ++- src/compiler/scala/reflect/runtime/Loaders.scala | 130 -- src/compiler/scala/reflect/runtime/Memoizer.scala | 15 - src/compiler/scala/reflect/runtime/Mirror.scala | 36 +- .../scala/reflect/runtime/RuntimeTypes.scala | 27 - .../scala/reflect/runtime/SymbolLoaders.scala | 135 ++ .../scala/reflect/runtime/SymbolTable.scala | 23 +- .../reflect/runtime/SynchronizedSymbols.scala | 7 +- src/compiler/scala/reflect/runtime/ToolBoxes.scala | 363 ++++-- .../scala/reflect/runtime/TreeBuildUtil.scala | 49 - src/compiler/scala/reflect/runtime/Universe.scala | 20 +- src/compiler/scala/reflect/runtime/package.scala | 5 + src/compiler/scala/tools/cmd/FromString.scala | 4 +- src/compiler/scala/tools/nsc/ClassLoaders.scala | 64 + src/compiler/scala/tools/nsc/Global.scala | 46 +- src/compiler/scala/tools/nsc/MacroContext.scala | 10 - src/compiler/scala/tools/nsc/ReflectGlobal.scala | 7 +- src/compiler/scala/tools/nsc/ReflectMain.scala | 11 +- src/compiler/scala/tools/nsc/ToolBoxes.scala | 85 ++ src/compiler/scala/tools/nsc/ast/DocComments.scala | 4 +- src/compiler/scala/tools/nsc/ast/FreeVars.scala | 26 + .../scala/tools/nsc/ast/NodePrinters.scala | 32 +- src/compiler/scala/tools/nsc/ast/Positions.scala | 44 + src/compiler/scala/tools/nsc/ast/Reifiers.scala | 761 ----------- .../scala/tools/nsc/ast/ReifyPrinters.scala | 75 -- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 16 - src/compiler/scala/tools/nsc/ast/Trees.scala | 124 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 129 +- .../scala/tools/nsc/ast/parser/Scanners.scala | 3 +- .../scala/tools/nsc/ast/parser/Tokens.scala | 1 + .../scala/tools/nsc/backend/jvm/GenJVM.scala | 2 +- .../scala/tools/nsc/backend/jvm/GenJVMUtil.scala | 2 +- .../scala/tools/nsc/backend/msil/GenMSIL.scala | 6 +- .../scala/tools/nsc/interactive/Global.scala | 2 +- .../tools/nsc/interactive/RangePositions.scala | 2 +- .../scala/tools/nsc/interpreter/IMain.scala | 12 +- .../scala/tools/nsc/interpreter/Power.scala | 1 - .../scala/tools/nsc/interpreter/ReplVals.scala | 2 +- .../scala/tools/nsc/interpreter/RichClass.scala | 2 +- .../scala/tools/nsc/interpreter/TypeStrings.scala | 9 +- .../tools/nsc/reporters/AbstractReporter.scala | 11 +- .../tools/nsc/reporters/ConsoleReporter.scala | 1 - .../scala/tools/nsc/scratchpad/Executor.scala | 2 +- .../scala/tools/nsc/settings/MutableSettings.scala | 2 +- .../scala/tools/nsc/settings/ScalaSettings.scala | 149 ++- .../scala/tools/nsc/symtab/Positions.scala | 30 - .../scala/tools/nsc/symtab/classfile/Pickler.scala | 6 +- .../scala/tools/nsc/transform/AddInterfaces.scala | 2 +- .../scala/tools/nsc/transform/CleanUp.scala | 2 +- .../scala/tools/nsc/transform/Erasure.scala | 4 +- .../scala/tools/nsc/transform/LambdaLift.scala | 18 +- src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 +- .../scala/tools/nsc/transform/UnCurry.scala | 14 +- .../tools/nsc/typechecker/ContextErrors.scala | 33 +- .../scala/tools/nsc/typechecker/Contexts.scala | 31 +- .../scala/tools/nsc/typechecker/Implicits.scala | 190 ++- .../scala/tools/nsc/typechecker/Infer.scala | 24 +- .../scala/tools/nsc/typechecker/Macros.scala | 1361 +++++++++++++++++--- .../tools/nsc/typechecker/MethodSynthesis.scala | 14 +- .../scala/tools/nsc/typechecker/Namers.scala | 31 +- .../scala/tools/nsc/typechecker/RefChecks.scala | 6 + .../tools/nsc/typechecker/TypeDiagnostics.scala | 20 +- .../scala/tools/nsc/typechecker/Typers.scala | 180 ++- src/compiler/scala/tools/nsc/util/ClassPath.scala | 2 +- src/compiler/scala/tools/nsc/util/Position.scala | 126 +- src/compiler/scala/tools/reflect/package.scala | 2 +- src/library/scala/Predef.scala | 29 +- .../scala/collection/mutable/ArrayBuilder.scala | 18 +- .../scala/collection/mutable/ArrayOps.scala | 10 +- .../scala/collection/mutable/WrappedArray.scala | 2 +- .../collection/mutable/WrappedArrayBuilder.scala | 14 +- src/library/scala/reflect/ArrayTags.scala | 19 + src/library/scala/reflect/ClassManifest.scala | 263 ---- src/library/scala/reflect/ClassTags.scala | 158 +++ src/library/scala/reflect/Manifest.scala | 302 ----- src/library/scala/reflect/NoManifest.scala | 15 - src/library/scala/reflect/OptManifest.scala | 17 - src/library/scala/reflect/ReflectionUtils.scala | 26 +- src/library/scala/reflect/TagMaterialization.scala | 154 +++ src/library/scala/reflect/api/Attachments.scala | 16 + src/library/scala/reflect/api/ClassLoaders.scala | 16 + src/library/scala/reflect/api/Exprs.scala | 48 + src/library/scala/reflect/api/FreeVars.scala | 42 + src/library/scala/reflect/api/Importers.scala | 19 + src/library/scala/reflect/api/Mirror.scala | 17 +- src/library/scala/reflect/api/Positions.scala | 215 +++- src/library/scala/reflect/api/Reporters.scala | 65 + src/library/scala/reflect/api/RuntimeTypes.scala | 20 - src/library/scala/reflect/api/Scopes.scala | 9 +- .../scala/reflect/api/StandardDefinitions.scala | 68 +- src/library/scala/reflect/api/StandardNames.scala | 156 ++- src/library/scala/reflect/api/Symbols.scala | 61 +- src/library/scala/reflect/api/ToolBoxes.scala | 90 ++ src/library/scala/reflect/api/TreeBuildUtil.scala | 111 +- src/library/scala/reflect/api/TreePrinters.scala | 6 +- src/library/scala/reflect/api/Trees.scala | 178 ++- src/library/scala/reflect/api/TypeTags.scala | 193 +++ src/library/scala/reflect/api/Types.scala | 91 +- src/library/scala/reflect/api/Universe.scala | 79 +- src/library/scala/reflect/macro/Context.scala | 36 - src/library/scala/reflect/makro/Aliases.scala | 26 + .../scala/reflect/makro/CapturedVariables.scala | 20 + src/library/scala/reflect/makro/Context.scala | 59 + src/library/scala/reflect/makro/Enclosures.scala | 53 + .../scala/reflect/makro/Infrastructure.scala | 73 ++ src/library/scala/reflect/makro/Names.scala | 14 + src/library/scala/reflect/makro/Reifiers.scala | 82 ++ src/library/scala/reflect/makro/Reporters.scala | 39 + src/library/scala/reflect/makro/Settings.scala | 38 + src/library/scala/reflect/makro/Symbols.scala | 17 + src/library/scala/reflect/makro/Typers.scala | 85 ++ src/library/scala/reflect/makro/Util.scala | 31 + .../scala/reflect/makro/internal/macroImpl.scala | 5 + .../scala/reflect/makro/internal/typeTagImpl.scala | 133 ++ src/library/scala/reflect/package.scala | 43 +- src/library/scala/runtime/ScalaRunTime.scala | 2 +- src/library/scala/util/Marshal.scala | 3 +- .../tools/partest/nest/ConsoleFileManager.scala | 1 + .../scala/tools/partest/nest/TestFile.scala | 4 +- src/partest/scala/tools/partest/nest/Worker.scala | 16 +- test/files/codelib/code.jar.desired.sha1 | 2 +- test/files/jvm/interpreter.check | 738 +++++------ test/files/jvm/interpreter.scala | 9 +- test/files/jvm/manifests.check | 55 - .../files/jvm/manifests.check.temporarily.disabled | 55 + test/files/jvm/manifests.scala | 119 -- .../files/jvm/manifests.scala.temporarily.disabled | 109 ++ test/files/macros/Printf.scala | 39 - test/files/macros/Test.scala | 8 - test/files/macros/macros_v0001.bat | 40 - test/files/macros/macros_v0001.sh | 30 - test/files/neg/checksensible.check | 200 +-- test/files/neg/classtags_contextbound_a.check | 4 + test/files/neg/classtags_contextbound_a.scala | 4 + test/files/neg/classtags_contextbound_b.check | 4 + test/files/neg/classtags_contextbound_b.scala | 5 + test/files/neg/classtags_contextbound_c.check | 4 + test/files/neg/classtags_contextbound_c.scala | 5 + .../neg/macro-argtype-mismatch/Macros_1.scala | 3 - test/files/neg/macro-argtype-mismatch/Test_2.scala | 4 - test/files/neg/macro-basic-mamdmi.check | 5 + test/files/neg/macro-basic-mamdmi.flags | 1 + .../macro-basic-mamdmi/Impls_Macros_Test_1.scala | 37 + test/files/neg/macro-cyclic.check | 4 + test/files/neg/macro-cyclic.flags | 1 + test/files/neg/macro-cyclic/Impls_Macros_1.scala | 25 + ...cro-deprecate-dont-touch-backquotedidents.check | 14 + .../Macros_Bind_12.scala | 6 + .../Macros_Class_4.scala | 3 + .../Macros_Class_5.scala | 3 + .../Macros_Def_13.scala | 3 + .../Macros_Object_6.scala | 3 + .../Macros_Object_7.scala | 3 + .../Macros_Package_10.scala | 3 + .../Macros_Package_11.scala | 3 + .../Macros_Trait_8.scala | 3 + .../Macros_Trait_9.scala | 3 + .../Macros_Type_3.scala | 3 + .../Macros_Val_1.scala | 3 + .../Macros_Var_2.scala | 3 + .../Main.scala | 2 + test/files/neg/macro-deprecate-idents.check | 50 + .../macro-deprecate-idents/Macros_Bind_12.scala | 6 + .../macro-deprecate-idents/Macros_Class_4.scala | 3 + .../macro-deprecate-idents/Macros_Class_5.scala | 3 + .../neg/macro-deprecate-idents/Macros_Def_13.scala | 3 + .../macro-deprecate-idents/Macros_Object_6.scala | 3 + .../macro-deprecate-idents/Macros_Object_7.scala | 3 + .../macro-deprecate-idents/Macros_Package_10.scala | 3 + .../macro-deprecate-idents/Macros_Package_11.scala | 3 + .../macro-deprecate-idents/Macros_Trait_8.scala | 3 + .../macro-deprecate-idents/Macros_Trait_9.scala | 3 + .../neg/macro-deprecate-idents/Macros_Type_3.scala | 3 + .../neg/macro-deprecate-idents/Macros_Val_1.scala | 3 + .../neg/macro-deprecate-idents/Macros_Var_2.scala | 3 + test/files/neg/macro-deprecate-idents/Main.scala | 2 + test/files/neg/macro-invalidimpl-a.check | 4 + test/files/neg/macro-invalidimpl-a.flags | 1 + test/files/neg/macro-invalidimpl-a/Impls_1.scala | 5 + .../neg/macro-invalidimpl-a/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-b.check | 4 + test/files/neg/macro-invalidimpl-b.flags | 1 + test/files/neg/macro-invalidimpl-b/Impls_1.scala | 5 + .../neg/macro-invalidimpl-b/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-c.check | 4 + test/files/neg/macro-invalidimpl-c.flags | 1 + .../neg/macro-invalidimpl-c/Impls_Macros_1.scala | 9 + test/files/neg/macro-invalidimpl-c/Test_2.scala | 3 + test/files/neg/macro-invalidimpl-d.check | 4 + test/files/neg/macro-invalidimpl-d.flags | 1 + test/files/neg/macro-invalidimpl-d/Impls_1.scala | 7 + .../neg/macro-invalidimpl-d/Macros_Test_2.scala | 7 + test/files/neg/macro-invalidimpl-e.check | 13 + test/files/neg/macro-invalidimpl-e.flags | 1 + test/files/neg/macro-invalidimpl-e/Impls_1.scala | 6 + .../neg/macro-invalidimpl-e/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-f.check | 7 + test/files/neg/macro-invalidimpl-f.flags | 1 + test/files/neg/macro-invalidimpl-f/Impls_1.scala | 11 + .../neg/macro-invalidimpl-f/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-g.check | 7 + test/files/neg/macro-invalidimpl-g.flags | 1 + test/files/neg/macro-invalidimpl-g/Impls_1.scala | 11 + .../neg/macro-invalidimpl-g/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidimpl-h.check | 4 + test/files/neg/macro-invalidimpl-h.flags | 1 + test/files/neg/macro-invalidimpl-h/Impls_1.scala | 5 + .../neg/macro-invalidimpl-h/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidret-nontree.check | 7 + test/files/neg/macro-invalidret-nontree.flags | 1 + .../neg/macro-invalidret-nontree/Impls_1.scala | 5 + .../macro-invalidret-nontree/Macros_Test_2.scala | 8 + .../neg/macro-invalidret-nonuniversetree.check | 7 + .../neg/macro-invalidret-nonuniversetree.flags | 1 + .../macro-invalidret-nonuniversetree/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-a.check | 6 + test/files/neg/macro-invalidshape-a.flags | 1 + test/files/neg/macro-invalidshape-a/Impls_1.scala | 5 + .../neg/macro-invalidshape-a/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-b.check | 6 + test/files/neg/macro-invalidshape-b.flags | 1 + test/files/neg/macro-invalidshape-b/Impls_1.scala | 5 + .../neg/macro-invalidshape-b/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-c.check | 6 + test/files/neg/macro-invalidshape-c.flags | 1 + test/files/neg/macro-invalidshape-c/Impls_1.scala | 5 + .../neg/macro-invalidshape-c/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-d.check | 4 + test/files/neg/macro-invalidshape-d.flags | 1 + test/files/neg/macro-invalidshape-d/Impls_1.scala | 5 + .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-context-bounds.check | 4 + .../neg/macro-invalidsig-context-bounds.flags | 1 + .../macro-invalidsig-context-bounds/Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-badargc.check | 7 + test/files/neg/macro-invalidsig-ctx-badargc.flags | 1 + .../neg/macro-invalidsig-ctx-badargc/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-badtype.check | 7 + test/files/neg/macro-invalidsig-ctx-badtype.flags | 1 + .../neg/macro-invalidsig-ctx-badtype/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-ctx-badvarargs.check | 7 + .../neg/macro-invalidsig-ctx-badvarargs.flags | 1 + .../macro-invalidsig-ctx-badvarargs/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-noctx.check | 7 + test/files/neg/macro-invalidsig-ctx-noctx.flags | 1 + .../neg/macro-invalidsig-ctx-noctx/Impls_1.scala | 5 + .../macro-invalidsig-ctx-noctx/Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-implicit-params.check | 4 + .../neg/macro-invalidsig-implicit-params.flags | 1 + .../Impls_Macros_1.scala | 18 + .../macro-invalidsig-implicit-params/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badargc.check | 7 + .../neg/macro-invalidsig-params-badargc.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-invalidsig-params-badargc/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badtype.check | 7 + .../neg/macro-invalidsig-params-badtype.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-invalidsig-params-badtype/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badvarargs.check | 7 + .../neg/macro-invalidsig-params-badvarargs.flags | 1 + .../Impls_Macros_1.scala | 9 + .../Test_2.scala | 4 + .../neg/macro-invalidsig-params-namemismatch.check | 7 + .../neg/macro-invalidsig-params-namemismatch.flags | 1 + .../Impls_Macros_1.scala | 9 + .../Test_2.scala | 4 + .../neg/macro-invalidsig-tparams-badtype.check | 7 + .../neg/macro-invalidsig-tparams-badtype.flags | 1 + .../macro-invalidsig-tparams-badtype/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-bounds-a.check | 4 + .../neg/macro-invalidsig-tparams-bounds-a.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-bounds-b.check | 4 + .../neg/macro-invalidsig-tparams-bounds-b.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-notparams-a.check | 4 + .../neg/macro-invalidsig-tparams-notparams-a.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-notparams-b.check | 4 + .../neg/macro-invalidsig-tparams-notparams-b.flags | 1 + .../Impls_1.scala | 11 + .../Macros_Test_2.scala | 11 + .../neg/macro-invalidsig-tparams-notparams-c.check | 4 + .../neg/macro-invalidsig-tparams-notparams-c.flags | 1 + .../Impls_1.scala | 11 + .../Macros_Test_2.scala | 11 + test/files/neg/macro-invalidusage-badargs.check | 6 + test/files/neg/macro-invalidusage-badargs.flags | 1 + .../neg/macro-invalidusage-badargs/Impls_1.scala | 5 + .../macro-invalidusage-badargs/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidusage-badbounds.check | 4 + test/files/neg/macro-invalidusage-badbounds.flags | 1 + .../neg/macro-invalidusage-badbounds/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidusage-badtargs.check | 4 + test/files/neg/macro-invalidusage-badtargs.flags | 1 + .../neg/macro-invalidusage-badtargs/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidusage-methodvaluesyntax.check | 4 + .../neg/macro-invalidusage-methodvaluesyntax.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-keyword.check | 49 + test/files/neg/macro-keyword.flags | 1 + test/files/neg/macro-keyword/Macros_Bind_12.scala | 6 + test/files/neg/macro-keyword/Macros_Class_4.scala | 3 + test/files/neg/macro-keyword/Macros_Class_5.scala | 3 + test/files/neg/macro-keyword/Macros_Def_13.scala | 3 + test/files/neg/macro-keyword/Macros_Object_6.scala | 3 + test/files/neg/macro-keyword/Macros_Object_7.scala | 3 + .../neg/macro-keyword/Macros_Package_10.scala | 3 + .../neg/macro-keyword/Macros_Package_11.scala | 3 + test/files/neg/macro-keyword/Macros_Trait_8.scala | 3 + test/files/neg/macro-keyword/Macros_Trait_9.scala | 3 + test/files/neg/macro-keyword/Macros_Type_3.scala | 3 + test/files/neg/macro-keyword/Macros_Val_1.scala | 3 + test/files/neg/macro-keyword/Macros_Var_2.scala | 3 + test/files/neg/macro-noexpand.check | 2 +- test/files/neg/macro-noexpand/Impls_1.scala | 5 + test/files/neg/macro-noexpand/Macros_1.scala | 3 - test/files/neg/macro-noexpand/Macros_Test_2.scala | 8 + test/files/neg/macro-noexpand/Test_2.scala | 4 - .../files/neg/macro-noncompilertree/Macros_1.scala | 3 - test/files/neg/macro-nontree/Macros_1.scala | 3 - test/files/neg/macro-nontypeablebody.check | 4 + test/files/neg/macro-nontypeablebody.flags | 1 + test/files/neg/macro-nontypeablebody/Impls_1.scala | 5 + .../neg/macro-nontypeablebody/Macros_Test_2.scala | 8 + ...verride-macro-overrides-abstract-method-a.check | 5 + ...verride-macro-overrides-abstract-method-a.flags | 1 + .../Impls_Macros_1.scala | 13 + .../Test_2.scala | 4 + ...verride-macro-overrides-abstract-method-b.check | 5 + ...verride-macro-overrides-abstract-method-b.flags | 1 + .../Impls_Macros_1.scala | 13 + .../Test_2.scala | 4 + .../macro-override-method-overrides-macro.check | 5 + .../macro-override-method-overrides-macro.flags | 1 + .../Impls_1.scala | 15 + .../Macros_Test_2.scala | 15 + ...o-reify-groundtypetag-hktypeparams-notags.check | 7 + .../Test.scala | 9 + ...cro-reify-groundtypetag-typeparams-notags.check | 7 + .../Test.scala | 9 + .../neg/macro-reify-groundtypetag-usetypetag.check | 7 + .../Test.scala | 9 + test/files/neg/macro-without-xmacros-a.check | 10 + .../neg/macro-without-xmacros-a/Impls_1.scala | 18 + .../neg/macro-without-xmacros-a/Macros_2.scala | 12 + .../files/neg/macro-without-xmacros-a/Test_3.scala | 4 + test/files/neg/macro-without-xmacros-b.check | 10 + .../neg/macro-without-xmacros-b/Impls_1.scala | 18 + .../neg/macro-without-xmacros-b/Macros_2.scala | 10 + .../files/neg/macro-without-xmacros-b/Test_3.scala | 4 + test/files/neg/reify_ann2a.check | 4 - test/files/neg/reify_ann2a.scala | 30 - test/files/neg/reify_ann2b.check | 11 +- test/files/neg/reify_ann2b.scala | 11 +- test/files/neg/t2386.check | 8 +- test/files/neg/t2775.check | 8 +- test/files/neg/t3507.check | 8 +- test/files/neg/t3692.check | 15 +- test/files/neg/t5334_1.check | 4 + test/files/neg/t5334_1.scala | 8 + test/files/neg/t5334_2.check | 4 + test/files/neg/t5334_2.scala | 8 + test/files/pos/implicits.scala | 89 -- .../files/pos/implicits.scala.temporarily.disabled | 89 ++ test/files/pos/liftcode_polymorphic.scala | 4 +- test/files/pos/macros.flags | 1 - test/files/pos/macros.scala | 8 - test/files/pos/manifest1.scala | 21 - .../files/pos/manifest1.scala.temporarily.disabled | 21 + test/files/pos/t5223.scala | 6 +- test/files/pos/t531.scala | 5 +- test/files/pos/t532.scala | 5 +- test/files/run/classtags_contextbound.check | 1 + test/files/run/classtags_contextbound.scala | 5 + test/files/run/classtags_core.check | 30 + test/files/run/classtags_core.scala | 32 + test/files/run/existentials3.check | 22 - .../run/existentials3.check.temporarily.disabled | 22 + test/files/run/existentials3.scala | 73 -- .../run/existentials3.scala.temporarily.disabled | 73 ++ test/files/run/groundtypetags_core.check | 30 + test/files/run/groundtypetags_core.scala | 32 + test/files/run/macro-abort-fresh.check | 6 + test/files/run/macro-abort-fresh.flags | 1 + test/files/run/macro-abort-fresh/Macros_1.scala | 15 + test/files/run/macro-abort-fresh/Test_2.scala | 6 + test/files/run/macro-basic-ma-md-mi.check | 1 + test/files/run/macro-basic-ma-md-mi.flags | 1 + test/files/run/macro-basic-ma-md-mi/Impls_1.scala | 21 + test/files/run/macro-basic-ma-md-mi/Macros_2.scala | 10 + test/files/run/macro-basic-ma-md-mi/Test_3.scala | 4 + test/files/run/macro-basic-ma-mdmi.check | 1 + test/files/run/macro-basic-ma-mdmi.flags | 1 + .../run/macro-basic-ma-mdmi/Impls_Macros_1.scala | 32 + test/files/run/macro-basic-ma-mdmi/Test_2.scala | 4 + test/files/run/macro-basic-mamd-mi.check | 1 + test/files/run/macro-basic-mamd-mi.flags | 1 + test/files/run/macro-basic-mamd-mi/Impls_1.scala | 19 + .../run/macro-basic-mamd-mi/Macros_Test_2.scala | 15 + test/files/run/macro-basic.check | 1 - test/files/run/macro-basic.flags | 1 - test/files/run/macro-basic/Macros_1.scala | 10 - test/files/run/macro-basic/Test_2.scala | 4 - test/files/run/macro-bodyexpandstoimpl.check | 1 + test/files/run/macro-bodyexpandstoimpl.flags | 1 + .../run/macro-bodyexpandstoimpl/Impls_1.scala | 12 + .../macro-bodyexpandstoimpl/Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-annotation.check | 1 + test/files/run/macro-declared-in-annotation.flags | 1 + .../run/macro-declared-in-annotation/Impls_1.scala | 11 + .../macro-declared-in-annotation/Macros_2.scala | 8 + .../run/macro-declared-in-annotation/Test_3.scala | 3 + test/files/run/macro-declared-in-anonymous.check | 2 + test/files/run/macro-declared-in-anonymous.flags | 1 + .../run/macro-declared-in-anonymous/Impls_1.scala | 11 + .../Macros_Test_2.scala | 4 + test/files/run/macro-declared-in-block.check | 2 + test/files/run/macro-declared-in-block.flags | 1 + .../run/macro-declared-in-block/Impls_1.scala | 11 + .../macro-declared-in-block/Macros_Test_2.scala | 6 + test/files/run/macro-declared-in-class-class.check | 2 + test/files/run/macro-declared-in-class-class.flags | 1 + .../macro-declared-in-class-class/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../files/run/macro-declared-in-class-object.check | 2 + .../files/run/macro-declared-in-class-object.flags | 1 + .../macro-declared-in-class-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-class.check | 2 + test/files/run/macro-declared-in-class.flags | 1 + .../run/macro-declared-in-class/Impls_1.scala | 11 + .../macro-declared-in-class/Macros_Test_2.scala | 7 + .../run/macro-declared-in-default-param.check | 5 + .../run/macro-declared-in-default-param.flags | 1 + .../macro-declared-in-default-param/Impls_1.scala | 11 + .../Macros_Test_2.scala | 7 + .../run/macro-declared-in-implicit-class.check | 2 + .../run/macro-declared-in-implicit-class.flags | 1 + .../Impls_Macros_1.scala | 19 + .../macro-declared-in-implicit-class/Test_2.scala | 4 + test/files/run/macro-declared-in-method.check | 2 + test/files/run/macro-declared-in-method.flags | 1 + .../run/macro-declared-in-method/Impls_1.scala | 11 + .../macro-declared-in-method/Macros_Test_2.scala | 8 + .../files/run/macro-declared-in-object-class.check | 2 + .../files/run/macro-declared-in-object-class.flags | 1 + .../macro-declared-in-object-class/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../run/macro-declared-in-object-object.check | 2 + .../run/macro-declared-in-object-object.flags | 1 + .../macro-declared-in-object-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-object.check | 2 + test/files/run/macro-declared-in-object.flags | 1 + .../run/macro-declared-in-object/Impls_1.scala | 11 + .../macro-declared-in-object/Macros_Test_2.scala | 7 + .../run/macro-declared-in-package-object.check | 2 + .../run/macro-declared-in-package-object.flags | 1 + .../macro-declared-in-package-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 8 + test/files/run/macro-declared-in-refinement.check | 2 + test/files/run/macro-declared-in-refinement.flags | 1 + .../run/macro-declared-in-refinement/Impls_1.scala | 11 + .../Macros_Test_2.scala | 6 + test/files/run/macro-declared-in-trait.check | 15 + test/files/run/macro-declared-in-trait.flags | 1 + .../run/macro-declared-in-trait/Impls_1.scala | 11 + .../macro-declared-in-trait/Macros_Test_2.scala | 13 + test/files/run/macro-def-infer-return-type-a.check | 1 + test/files/run/macro-def-infer-return-type-a.flags | 1 + .../macro-def-infer-return-type-a/Impls_1.scala | 5 + .../Macros_Test_2.scala | 4 + test/files/run/macro-def-infer-return-type-b.check | 6 + test/files/run/macro-def-infer-return-type-b.flags | 1 + .../Impls_Macros_1.scala | 10 + .../run/macro-def-infer-return-type-b/Test_2.scala | 6 + test/files/run/macro-def-infer-return-type-c.check | 1 + test/files/run/macro-def-infer-return-type-c.flags | 1 + .../macro-def-infer-return-type-c/Impls_1.scala | 5 + .../Macros_Test_2.scala | 4 + test/files/run/macro-def-path-dependent-a.check | 1 + test/files/run/macro-def-path-dependent-a.flags | 1 + .../Impls_Macros_1.scala | 21 + .../run/macro-def-path-dependent-a/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-b.check | 1 + test/files/run/macro-def-path-dependent-b.flags | 1 + .../Impls_Macros_1.scala | 20 + .../run/macro-def-path-dependent-b/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-c.check | 1 + test/files/run/macro-def-path-dependent-c.flags | 1 + .../Impls_Macros_1.scala | 20 + .../run/macro-def-path-dependent-c/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-d.check | 1 + test/files/run/macro-def-path-dependent-d.flags | 1 + .../Impls_Macros_1.scala | 8 + .../run/macro-def-path-dependent-d/Test_2.scala | 3 + .../macro-expand-implicit-macro-has-implicit.check | 1 + .../macro-expand-implicit-macro-has-implicit.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 5 + .../macro-expand-implicit-macro-is-implicit.check | 2 + .../macro-expand-implicit-macro-is-implicit.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 10 + .../run/macro-expand-implicit-macro-is-val.check | 1 + .../run/macro-expand-implicit-macro-is-val.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 5 + .../run/macro-expand-implicit-macro-is-view.check | 1 + .../run/macro-expand-implicit-macro-is-view.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 9 + .../files/run/macro-expand-multiple-arglists.check | 1 + .../files/run/macro-expand-multiple-arglists.flags | 1 + .../macro-expand-multiple-arglists/Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-nullary-generic.check | 6 + test/files/run/macro-expand-nullary-generic.flags | 1 + .../run/macro-expand-nullary-generic/Impls_1.scala | 14 + .../Macros_Test_2.scala | 15 + .../run/macro-expand-nullary-nongeneric.check | 6 + .../run/macro-expand-nullary-nongeneric.flags | 1 + .../macro-expand-nullary-nongeneric/Impls_1.scala | 14 + .../Macros_Test_2.scala | 15 + test/files/run/macro-expand-overload.check | 6 + test/files/run/macro-expand-overload.flags | 1 + test/files/run/macro-expand-overload/Impls_1.scala | 15 + .../run/macro-expand-overload/Macros_Test_2.scala | 20 + test/files/run/macro-expand-override.check | 15 + test/files/run/macro-expand-override.flags | 1 + test/files/run/macro-expand-override/Impls_1.scala | 15 + .../run/macro-expand-override/Macros_Test_2.scala | 43 + test/files/run/macro-expand-recursive.check | 1 + test/files/run/macro-expand-recursive.flags | 1 + .../files/run/macro-expand-recursive/Impls_1.scala | 15 + .../run/macro-expand-recursive/Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-bounds-a.check | 0 test/files/run/macro-expand-tparams-bounds-a.flags | 1 + .../macro-expand-tparams-bounds-a/Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-bounds-b.check | 0 test/files/run/macro-expand-tparams-bounds-b.flags | 1 + .../macro-expand-tparams-bounds-b/Impls_1.scala | 10 + .../Macros_Test_2.scala | 10 + test/files/run/macro-expand-tparams-explicit.check | 1 + test/files/run/macro-expand-tparams-explicit.flags | 1 + .../macro-expand-tparams-explicit/Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-tparams-implicit.check | 2 + test/files/run/macro-expand-tparams-implicit.flags | 1 + .../macro-expand-tparams-implicit/Impls_1.scala | 10 + .../Macros_Test_2.scala | 5 + .../run/macro-expand-tparams-only-in-impl.flags | 1 + .../Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-optional.check | 1 + test/files/run/macro-expand-tparams-optional.flags | 1 + .../macro-expand-tparams-optional/Impls_1.scala | 9 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-tparams-prefix-a.check | 4 + test/files/run/macro-expand-tparams-prefix-a.flags | 1 + .../macro-expand-tparams-prefix-a/Impls_1.scala | 10 + .../Macros_Test_2.scala | 10 + test/files/run/macro-expand-tparams-prefix-b.check | 2 + test/files/run/macro-expand-tparams-prefix-b.flags | 1 + .../macro-expand-tparams-prefix-b/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../files/run/macro-expand-tparams-prefix-c1.check | 3 + .../files/run/macro-expand-tparams-prefix-c1.flags | 1 + .../macro-expand-tparams-prefix-c1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 11 + .../files/run/macro-expand-tparams-prefix-c2.check | 3 + .../files/run/macro-expand-tparams-prefix-c2.flags | 1 + .../Impls_Macros_1.scala | 18 + .../macro-expand-tparams-prefix-c2/Test_2.scala | 5 + .../files/run/macro-expand-tparams-prefix-d1.check | 3 + .../files/run/macro-expand-tparams-prefix-d1.flags | 1 + .../macro-expand-tparams-prefix-d1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 11 + ...pand-varargs-explicit-over-nonvarargs-bad.check | 4 + ...pand-varargs-explicit-over-nonvarargs-bad.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 10 + ...and-varargs-explicit-over-nonvarargs-good.check | 1 + ...and-varargs-explicit-over-nonvarargs-good.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 8 + ...acro-expand-varargs-explicit-over-varargs.check | 1 + ...acro-expand-varargs-explicit-over-varargs.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 8 + ...o-expand-varargs-implicit-over-nonvarargs.check | 1 + ...o-expand-varargs-implicit-over-nonvarargs.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 7 + ...acro-expand-varargs-implicit-over-varargs.check | 1 + ...acro-expand-varargs-implicit-over-varargs.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 7 + test/files/run/macro-impl-default-params.check | 5 + test/files/run/macro-impl-default-params.flags | 1 + .../macro-impl-default-params/Impls_Macros_1.scala | 20 + .../run/macro-impl-default-params/Test_2.scala | 4 + test/files/run/macro-impl-rename-context.check | 2 + test/files/run/macro-impl-rename-context.flags | 1 + .../macro-impl-rename-context/Impls_Macros_1.scala | 15 + .../run/macro-impl-rename-context/Test_2.scala | 4 + ...-invalidret-doesnt-conform-to-def-rettype.check | 5 + ...-invalidret-doesnt-conform-to-def-rettype.flags | 1 + .../Impls_Macros_1.scala | 12 + .../Test_2.scala | 6 + ...invalidret-doesnt-conform-to-impl-rettype.check | 0 ...invalidret-doesnt-conform-to-impl-rettype.flags | 1 + test/files/run/macro-invalidret-nontypeable.check | 3 + test/files/run/macro-invalidret-nontypeable.flags | 1 + .../Impls_Macros_1.scala | 13 + .../run/macro-invalidret-nontypeable/Test_2.scala | 6 + test/files/run/macro-invalidusage-badret.check | 5 + test/files/run/macro-invalidusage-badret.flags | 1 + .../macro-invalidusage-badret/Impls_Macros_1.scala | 9 + .../run/macro-invalidusage-badret/Test_2.scala | 6 + .../macro-invalidusage-partialapplication.check | 3 + .../macro-invalidusage-partialapplication.flags | 1 + .../Impls_Macros_1.scala | 14 + .../Test_2.scala | 6 + test/files/run/macro-openmacros.check | 3 + test/files/run/macro-openmacros.flags | 1 + .../run/macro-openmacros/Impls_Macros_1.scala | 26 + test/files/run/macro-openmacros/Test_2.scala | 3 + test/files/run/macro-quasiinvalidbody-c.check | 1 + test/files/run/macro-quasiinvalidbody-c.flags | 1 + .../macro-quasiinvalidbody-c/Impls_Macros_1.scala | 9 + .../run/macro-quasiinvalidbody-c/Test_2.scala | 4 + test/files/run/macro-range/Common_1.scala | 48 + .../run/macro-range/Expansion_Impossible_2.scala | 53 + .../run/macro-range/Expansion_Possible_3.scala | 7 + test/files/run/macro-range/macro_range_1.scala | 99 -- test/files/run/macro-range/macro_range_2.scala | 99 -- .../run/macro-reflective-ma-normal-mdmi.check | 1 + .../run/macro-reflective-ma-normal-mdmi.flags | 1 + .../Impls_Macros_1.scala | 13 + .../macro-reflective-ma-normal-mdmi/Test_2.scala | 5 + .../run/macro-reflective-mamd-normal-mi.check | 1 + .../run/macro-reflective-mamd-normal-mi.flags | 0 .../macro-reflective-mamd-normal-mi/Impls_1.scala | 9 + .../Macros_Test_2.scala | 16 + test/files/run/macro-reify-basic.check | 1 + test/files/run/macro-reify-basic.flags | 1 + test/files/run/macro-reify-basic/Macros_1.scala | 11 + test/files/run/macro-reify-basic/Test_2.scala | 3 + test/files/run/macro-reify-eval-eval.check | 1 + test/files/run/macro-reify-eval-eval.flags | 1 + .../files/run/macro-reify-eval-eval/Macros_1.scala | 12 + test/files/run/macro-reify-eval-eval/Test_2.scala | 3 + .../files/run/macro-reify-eval-outside-reify.check | 1 + .../files/run/macro-reify-eval-outside-reify.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-reify-eval-outside-reify/Test_2.scala | 5 + test/files/run/macro-reify-freevars.check | 3 + test/files/run/macro-reify-freevars.flags | 1 + test/files/run/macro-reify-freevars/Macros_1.scala | 19 + test/files/run/macro-reify-freevars/Test_2.scala | 9 + .../macro-reify-groundtypetag-notypeparams.check | 2 + .../Test.scala | 6 + ...macro-reify-groundtypetag-typeparams-tags.check | 2 + .../Test.scala | 9 + test/files/run/macro-reify-nested-a.check | 0 test/files/run/macro-reify-nested-a.flags | 1 + .../run/macro-reify-nested-a/Impls_Macros_1.scala | 43 + test/files/run/macro-reify-nested-a/Test_2.scala | 4 + test/files/run/macro-reify-nested-b.check | 0 test/files/run/macro-reify-nested-b.flags | 1 + .../run/macro-reify-nested-b/Impls_Macros_1.scala | 43 + test/files/run/macro-reify-nested-b/Test_2.scala | 4 + .../files/run/macro-reify-ref-to-packageless.check | 1 + .../files/run/macro-reify-ref-to-packageless.flags | 1 + .../macro-reify-ref-to-packageless/Impls_1.scala | 6 + .../macro-reify-ref-to-packageless/Test_2.scala | 4 + test/files/run/macro-reify-tagful-a.check | 1 + test/files/run/macro-reify-tagful-a.flags | 1 + test/files/run/macro-reify-tagful-a/Macros_1.scala | 11 + test/files/run/macro-reify-tagful-a/Test_2.scala | 4 + test/files/run/macro-reify-tagless-a.check | 3 + test/files/run/macro-reify-tagless-a.flags | 1 + .../run/macro-reify-tagless-a/Impls_Macros_1.scala | 11 + test/files/run/macro-reify-tagless-a/Test_2.scala | 12 + .../run/macro-reify-typetag-notypeparams.check | 2 + .../macro-reify-typetag-notypeparams/Test.scala | 6 + .../macro-reify-typetag-typeparams-notags.check | 2 + .../Test.scala | 9 + .../run/macro-reify-typetag-typeparams-tags.check | 2 + .../macro-reify-typetag-typeparams-tags/Test.scala | 9 + .../run/macro-reify-typetag-usegroundtypetag.check | 2 + .../Test.scala | 9 + test/files/run/macro-reify-unreify.check | 1 + test/files/run/macro-reify-unreify.flags | 1 + test/files/run/macro-reify-unreify/Macros_1.scala | 19 + test/files/run/macro-reify-unreify/Test_2.scala | 3 + .../run/macro-reify-value-outside-reify.check | 1 + .../run/macro-reify-value-outside-reify.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-reify-value-outside-reify/Test_2.scala | 6 + test/files/run/macro-repl-basic.check | 34 +- test/files/run/macro-repl-basic.scala | 27 +- test/files/run/macro-repl-dontexpand.check | 5 +- test/files/run/macro-repl-dontexpand.scala | 3 +- .../run/macro-rettype-mismatch/Macros_1.scala | 3 - test/files/run/macro-rettype-mismatch/Test_2.scala | 16 - test/files/run/macro-settings.check | 1 + test/files/run/macro-settings.flags | 1 + test/files/run/macro-settings/Impls_Macros_1.scala | 11 + test/files/run/macro-settings/Test_2.scala | 3 + test/files/run/macro-sip19-revised.check | 5 + test/files/run/macro-sip19-revised.flags | 1 + .../run/macro-sip19-revised/Impls_Macros_1.scala | 34 + test/files/run/macro-sip19-revised/Test_2.scala | 12 + test/files/run/macro-sip19.check | 5 + test/files/run/macro-sip19.flags | 1 + test/files/run/macro-sip19/Impls_Macros_1.scala | 25 + test/files/run/macro-sip19/Test_2.scala | 16 + .../run/macro-typecheck-implicitsdisabled.check | 2 + .../run/macro-typecheck-implicitsdisabled.flags | 1 + .../Impls_Macros_1.scala | 28 + .../macro-typecheck-implicitsdisabled/Test_2.scala | 4 + .../files/run/macro-typecheck-macrosdisabled.check | 5 + .../files/run/macro-typecheck-macrosdisabled.flags | 1 + .../Impls_Macros_1.scala | 36 + .../macro-typecheck-macrosdisabled/Test_2.scala | 4 + test/files/run/macro-undetparams-consfromsls.check | 5 + test/files/run/macro-undetparams-consfromsls.flags | 1 + .../Impls_Macros_1.scala | 17 + .../run/macro-undetparams-consfromsls/Test_2.scala | 7 + test/files/run/macro-undetparams-implicitval.check | 1 + test/files/run/macro-undetparams-implicitval.flags | 1 + .../run/macro-undetparams-implicitval/Test.scala | 4 + test/files/run/macro-undetparams-macroitself.check | 2 + test/files/run/macro-undetparams-macroitself.flags | 1 + .../Impls_Macros_1.scala | 7 + .../run/macro-undetparams-macroitself/Test_2.scala | 4 + test/files/run/manifests.scala | 71 +- test/files/run/primitive-sigs-2.check | 14 +- test/files/run/reify_ann1a.check | 60 +- test/files/run/reify_ann1a.scala | 11 +- test/files/run/reify_ann1b.check | 60 +- test/files/run/reify_ann1b.scala | 11 +- test/files/run/reify_ann2a.check | 44 + test/files/run/reify_ann2a.scala | 25 + test/files/run/reify_ann3.check | 21 + test/files/run/reify_ann3.scala | 19 + test/files/run/reify_ann4.check | 32 + test/files/run/reify_ann4.scala | 23 + test/files/run/reify_ann5.check | 22 + test/files/run/reify_ann5.scala | 20 + test/files/run/reify_anonymous.scala | 12 +- test/files/run/reify_classfileann_a.check | 36 +- test/files/run/reify_classfileann_a.scala | 11 +- test/files/run/reify_classfileann_b.check | 20 + test/files/run/reify_classfileann_b.scala | 23 + test/files/run/reify_closure1.scala | 9 +- test/files/run/reify_closure2a.scala | 9 +- test/files/run/reify_closure3a.scala | 9 +- test/files/run/reify_closure4a.scala | 9 +- test/files/run/reify_closure5a.scala | 17 +- test/files/run/reify_closure6.scala | 17 +- test/files/run/reify_closure7.scala | 17 +- test/files/run/reify_closure8a.scala | 10 +- test/files/run/reify_closure8b.check | 3 + test/files/run/reify_closure8b.scala | 18 + test/files/run/reify_closures10.scala | 10 +- test/files/run/reify_complex.scala | 12 +- test/files/run/reify_extendbuiltins.scala | 12 +- test/files/run/reify_for1.scala | 12 +- test/files/run/reify_fors.scala | 12 +- test/files/run/reify_generic.scala | 12 +- test/files/run/reify_generic2.scala | 12 +- test/files/run/reify_getter.scala | 11 +- test/files/run/reify_implicits.scala | 12 +- test/files/run/reify_inheritance.scala | 12 +- test/files/run/reify_inner1.scala | 12 +- test/files/run/reify_inner2.scala | 12 +- test/files/run/reify_inner3.scala | 12 +- test/files/run/reify_inner4.scala | 12 +- test/files/run/reify_maps.scala | 12 +- .../reify_metalevel_breach_+0_refers_to_1.check | 1 + .../reify_metalevel_breach_+0_refers_to_1.scala | 13 + .../reify_metalevel_breach_-1_refers_to_0_a.check | 1 + .../reify_metalevel_breach_-1_refers_to_0_a.scala | 11 + .../reify_metalevel_breach_-1_refers_to_0_b.check | 1 + .../reify_metalevel_breach_-1_refers_to_0_b.scala | 15 + .../reify_metalevel_breach_-1_refers_to_1.check | 1 + .../reify_metalevel_breach_-1_refers_to_1.scala | 13 + .../run/reify_nested_inner_refers_to_global.check | 1 + .../run/reify_nested_inner_refers_to_global.scala | 14 + .../run/reify_nested_inner_refers_to_local.check | 1 + .../run/reify_nested_inner_refers_to_local.scala | 12 + .../run/reify_nested_outer_refers_to_global.check | 1 + .../run/reify_nested_outer_refers_to_global.scala | 16 + .../run/reify_nested_outer_refers_to_local.check | 1 + .../run/reify_nested_outer_refers_to_local.scala | 16 + test/files/run/reify_newimpl_01.check | 1 + test/files/run/reify_newimpl_01.scala | 11 + test/files/run/reify_newimpl_02.check | 1 + test/files/run/reify_newimpl_02.scala | 11 + test/files/run/reify_newimpl_03.check | 1 + test/files/run/reify_newimpl_03.scala | 11 + test/files/run/reify_newimpl_04.check | 1 + test/files/run/reify_newimpl_04.scala | 11 + test/files/run/reify_newimpl_05.check | 1 + test/files/run/reify_newimpl_05.scala | 12 + test/files/run/reify_newimpl_06.check | 1 + test/files/run/reify_newimpl_06.scala | 11 + test/files/run/reify_newimpl_09.check | 1 + test/files/run/reify_newimpl_09.scala | 11 + test/files/run/reify_newimpl_10.check | 1 + test/files/run/reify_newimpl_10.scala | 12 + test/files/run/reify_newimpl_11.check | 2 + test/files/run/reify_newimpl_11.scala | 17 + test/files/run/reify_newimpl_12.check | 1 + test/files/run/reify_newimpl_12.scala | 12 + test/files/run/reify_newimpl_13.check | 2 + test/files/run/reify_newimpl_13.scala | 19 + test/files/run/reify_newimpl_14.check | 1 + test/files/run/reify_newimpl_14.scala | 14 + test/files/run/reify_newimpl_15.check | 1 + test/files/run/reify_newimpl_15.scala | 13 + test/files/run/reify_newimpl_16.check | 1 + test/files/run/reify_newimpl_16.scala | 15 + test/files/run/reify_newimpl_17.check | 2 + test/files/run/reify_newimpl_17.scala | 18 + test/files/run/reify_newimpl_18.check | 1 + test/files/run/reify_newimpl_18.scala | 13 + test/files/run/reify_newimpl_19.check | 2 + test/files/run/reify_newimpl_19.scala | 18 + test/files/run/reify_newimpl_20.check | 1 + test/files/run/reify_newimpl_20.scala | 14 + test/files/run/reify_newimpl_21.check | 1 + test/files/run/reify_newimpl_21.scala | 18 + test/files/run/reify_newimpl_22.check | 23 + test/files/run/reify_newimpl_22.scala | 15 + test/files/run/reify_newimpl_23.check | 22 + test/files/run/reify_newimpl_23.scala | 14 + test/files/run/reify_newimpl_24.check | 24 + test/files/run/reify_newimpl_24.scala | 16 + test/files/run/reify_newimpl_25.check | 21 + test/files/run/reify_newimpl_25.scala | 13 + test/files/run/reify_newimpl_26.check | 23 + test/files/run/reify_newimpl_26.scala | 13 + test/files/run/reify_newimpl_27.check | 1 + test/files/run/reify_newimpl_27.scala | 13 + test/files/run/reify_newimpl_28.check | 1 + test/files/run/reify_newimpl_28.scala | 15 + test/files/run/reify_newimpl_29.check | 1 + test/files/run/reify_newimpl_29.scala | 13 + test/files/run/reify_newimpl_30.check | 1 + test/files/run/reify_newimpl_30.scala | 15 + test/files/run/reify_newimpl_31.check | 1 + test/files/run/reify_newimpl_31.scala | 13 + test/files/run/reify_newimpl_32.check | 1 + test/files/run/reify_newimpl_32.scala | 15 + test/files/run/reify_newimpl_33.check | 1 + test/files/run/reify_newimpl_33.scala | 14 + test/files/run/reify_newimpl_34.check | 1 + test/files/run/reify_newimpl_34.scala | 16 + test/files/run/reify_newimpl_36.check | 1 + test/files/run/reify_newimpl_36.scala | 14 + test/files/run/reify_newimpl_37.check | 1 + test/files/run/reify_newimpl_37.scala | 15 + test/files/run/reify_newimpl_38.check | 1 + test/files/run/reify_newimpl_38.scala | 14 + test/files/run/reify_newimpl_39.check | 1 + test/files/run/reify_newimpl_39.scala | 15 + test/files/run/reify_newimpl_40.check | 1 + test/files/run/reify_newimpl_40.scala | 15 + test/files/run/reify_newimpl_41.check | 3 + test/files/run/reify_newimpl_41.scala | 17 + test/files/run/reify_newimpl_42.check | 3 + test/files/run/reify_newimpl_42.scala | 16 + test/files/run/reify_newimpl_43.check | 2 + test/files/run/reify_newimpl_43.scala | 15 + test/files/run/reify_newimpl_44.check | 2 + test/files/run/reify_newimpl_44.scala | 15 + test/files/run/reify_newimpl_45.check | 2 + test/files/run/reify_newimpl_45.scala | 12 + test/files/run/reify_newimpl_47.check | 1 + test/files/run/reify_newimpl_47.scala | 15 + test/files/run/reify_newimpl_48.check | 1 + test/files/run/reify_newimpl_48.scala | 20 + test/files/run/reify_newimpl_49.check | 3 + test/files/run/reify_newimpl_49.scala | 15 + test/files/run/reify_newimpl_50.check | 3 + test/files/run/reify_newimpl_50.scala | 14 + test/files/run/reify_newimpl_51.check | 3 + test/files/run/reify_newimpl_51.scala | 17 + test/files/run/reify_newimpl_52.check | 3 + test/files/run/reify_newimpl_52.scala | 17 + test/files/run/reify_printf.scala | 11 +- test/files/run/reify_sort.scala | 12 +- test/files/run/reify_sort1.scala | 12 +- test/files/run/reify_this.scala | 25 +- test/files/run/reify_timeofday.scala | 12 +- test/files/run/reify_typerefs_1a.check | 1 + test/files/run/reify_typerefs_1a.scala | 15 + test/files/run/reify_typerefs_1b.check | 1 + test/files/run/reify_typerefs_1b.scala | 15 + test/files/run/reify_typerefs_2a.check | 1 + test/files/run/reify_typerefs_2a.scala | 17 + test/files/run/reify_typerefs_2b.check | 1 + test/files/run/reify_typerefs_2b.scala | 17 + test/files/run/reify_typerefs_3a.check | 1 + test/files/run/reify_typerefs_3a.scala | 17 + test/files/run/reify_typerefs_3b.check | 1 + test/files/run/reify_typerefs_3b.scala | 17 + test/files/run/reify_varargs.scala | 12 +- test/files/run/repl-power.check | 64 +- test/files/run/t1195.check | 6 - test/files/run/t1195.check.temporarily.disabled | 6 + test/files/run/t1195.scala | 26 - test/files/run/t1195.scala.temporarily.disabled | 26 + test/files/run/t3758.check | 6 + test/files/run/t3758.scala | 12 +- test/files/run/t4110.check | 2 - test/files/run/t4110.check.temporarily.disabled | 2 + test/files/run/t4110.scala | 11 - test/files/run/t4110.scala.temporarily.disabled | 11 + test/files/run/t5224.check | 18 +- test/files/run/t5224.scala | 5 +- test/files/run/t5225_1.check | 8 +- test/files/run/t5225_1.scala | 5 +- test/files/run/t5225_2.check | 8 +- test/files/run/t5225_2.scala | 5 +- test/files/run/t5229_1.scala | 12 +- test/files/run/t5229_2.scala | 9 +- test/files/run/t5230.scala | 9 +- test/files/run/t5258a.check | 1 - test/files/run/t5258a.scala | 13 - test/files/run/t5266_1.scala | 9 +- test/files/run/t5266_2.scala | 9 +- test/files/run/t5269.scala | 12 +- test/files/run/t5270.scala | 12 +- test/files/run/t5271_1.check | 22 +- test/files/run/t5271_1.scala | 9 +- test/files/run/t5271_2.check | 24 +- test/files/run/t5271_2.scala | 9 +- test/files/run/t5271_3.check | 38 +- test/files/run/t5271_3.scala | 9 +- test/files/run/t5271_4.scala | 12 +- test/files/run/t5272_1.scala | 12 +- test/files/run/t5272_2.scala | 12 +- test/files/run/t5273_1.scala | 12 +- test/files/run/t5273_2a.scala | 12 +- test/files/run/t5273_2b.scala | 12 +- test/files/run/t5274_1.scala | 12 +- test/files/run/t5274_2.scala | 12 +- test/files/run/t5275.scala | 12 +- test/files/run/t5276_1a.scala | 12 +- test/files/run/t5276_1b.scala | 12 +- test/files/run/t5276_2a.scala | 12 +- test/files/run/t5276_2b.scala | 12 +- test/files/run/t5277_1.scala | 12 +- test/files/run/t5277_2.scala | 12 +- test/files/run/t5279.scala | 12 +- test/files/run/t5334_1.scala | 12 +- test/files/run/t5334_2.scala | 12 +- test/files/run/t5335.scala | 12 +- test/files/run/t5415.scala | 10 +- test/files/run/t5419.check | 2 +- test/files/run/t5419.scala | 5 +- test/files/run/t5423.scala | 3 - test/files/run/toolbox_console_reporter.check | 0 test/files/run/toolbox_console_reporter.scala | 16 + .../run/toolbox_default_reporter_is_silent.check | 1 + .../run/toolbox_default_reporter_is_silent.scala | 13 + test/files/run/toolbox_silent_reporter.check | 4 + test/files/run/toolbox_silent_reporter.scala | 16 + .../run/toolbox_typecheck_implicitsdisabled.check | 5 + .../run/toolbox_typecheck_implicitsdisabled.scala | 24 + .../run/toolbox_typecheck_macrosdisabled.check | 5 + .../run/toolbox_typecheck_macrosdisabled.scala | 17 + test/files/run/treePrint.check | 5 - .../files/run/treePrint.check.temporarily.disabled | 5 + test/files/run/treePrint.scala | 42 - .../files/run/treePrint.scala.temporarily.disabled | 42 + test/files/run/typetags_core.check | 30 + test/files/run/typetags_core.scala | 32 + test/pending/neg/reify_packed.check | 4 + test/pending/neg/reify_packed.scala | 10 + test/pending/run/macro-expand-default.flags | 1 + .../pending/run/macro-expand-default/Impls_1.scala | 10 + .../run/macro-expand-default/Macros_Test_2.scala | 8 + ...o-expand-implicit-macro-has-context-bound.check | 1 + ...o-expand-implicit-macro-has-context-bound.flags | 1 + .../Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/pending/run/macro-expand-named.flags | 1 + test/pending/run/macro-expand-named/Impls_1.scala | 10 + .../run/macro-expand-named/Macros_Test_2.scala | 5 + .../run/macro-expand-tparams-prefix-e1.check | 3 + .../run/macro-expand-tparams-prefix-e1.flags | 1 + .../macro-expand-tparams-prefix-e1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 13 + .../run/macro-expand-tparams-prefix-f1.check | 3 + .../run/macro-expand-tparams-prefix-f1.flags | 1 + .../macro-expand-tparams-prefix-f1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 13 + test/pending/run/macro-overload.check | 4 - test/pending/run/macro-overload.flags | 1 - test/pending/run/macro-overload/Macros_1.scala | 9 - test/pending/run/macro-overload/Test_2.scala | 6 - test/pending/run/macro-quasiinvalidbody-a.check | 1 + test/pending/run/macro-quasiinvalidbody-a.flags | 1 + .../run/macro-quasiinvalidbody-a/Impls_1.scala | 5 + .../macro-quasiinvalidbody-a/Macros_Test_2.scala | 10 + test/pending/run/macro-quasiinvalidbody-b.check | 1 + test/pending/run/macro-quasiinvalidbody-b.flags | 1 + .../run/macro-quasiinvalidbody-b/Impls_1.scala | 7 + .../macro-quasiinvalidbody-b/Macros_Test_2.scala | 10 + test/pending/run/macro-reify-array.flags | 1 + test/pending/run/macro-reify-array/Macros_1.scala | 11 + test/pending/run/macro-reify-array/Test_2.scala | 4 + test/pending/run/macro-reify-eval-vs-value.flags | 1 + .../run/macro-reify-eval-vs-value/Macros_1.scala | 25 + .../run/macro-reify-eval-vs-value/Test_2.scala | 5 + ...cro-reify-groundtypetag-hktypeparams-tags.check | 2 + .../Test.scala | 9 + test/pending/run/macro-reify-tagful-b.check | 1 + test/pending/run/macro-reify-tagful-b.flags | 1 + .../run/macro-reify-tagful-b/Macros_1.scala | 11 + test/pending/run/macro-reify-tagful-b/Test_2.scala | 4 + test/pending/run/macro-reify-tagless-b.check | 3 + test/pending/run/macro-reify-tagless-b.flags | 1 + .../run/macro-reify-tagless-b/Impls_Macros_1.scala | 11 + .../pending/run/macro-reify-tagless-b/Test_2.scala | 11 + .../macro-reify-typetag-hktypeparams-notags.check | 2 + .../Test.scala | 9 + .../macro-reify-typetag-hktypeparams-tags.check | 2 + .../Test.scala | 9 + test/pending/run/reify_addressbook.scala | 12 +- test/pending/run/reify_brainf_ck.scala | 12 +- test/pending/run/reify_callccinterpreter.scala | 12 +- test/pending/run/reify_classfileann_b.check | 0 test/pending/run/reify_classfileann_b.scala | 24 - test/pending/run/reify_closure2b.scala | 9 +- test/pending/run/reify_closure3b.scala | 9 +- test/pending/run/reify_closure4b.scala | 9 +- test/pending/run/reify_closure5b.scala | 9 +- test/pending/run/reify_closure8b.check | 1 - test/pending/run/reify_closure8b.scala | 16 - test/pending/run/reify_closure9a.scala | 11 +- test/pending/run/reify_closure9b.scala | 11 +- test/pending/run/reify_closures11.scala | 11 +- test/pending/run/reify_csv.scala | 12 +- test/pending/run/reify_gadts.scala | 12 +- test/pending/run/reify_lazyevaluation.scala | 12 +- test/pending/run/reify_newimpl_07.scala | 13 + test/pending/run/reify_newimpl_08.scala | 15 + test/pending/run/reify_newimpl_35.scala | 10 + test/pending/run/reify_newimpl_46.scala | 12 + test/pending/run/reify_newimpl_53.scala | 15 + test/pending/run/reify_properties.scala | 12 +- test/pending/run/reify_simpleinterpreter.scala | 12 +- test/pending/run/t5258a.check | 1 + test/pending/run/t5258a.scala | 5 + test/pending/run/t5258b.scala | 12 +- test/pending/run/t5258c.scala | 12 +- test/pending/run/t5271_1.scala | 12 +- test/pending/run/t5271_2.scala | 12 +- test/pending/run/t5271_3.scala | 12 +- test/pending/run/t5418.scala | 12 +- 1134 files changed, 15211 insertions(+), 5479 deletions(-) create mode 100644 src/compiler/scala/reflect/internal/CapturedVariables.scala create mode 100644 src/compiler/scala/reflect/internal/FreeVars.scala create mode 100644 src/compiler/scala/reflect/internal/Reporters.scala create mode 100644 src/compiler/scala/reflect/internal/TreeBuildUtil.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Aliases.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Context.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Enclosures.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Errors.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Infrastructure.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Names.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Reifiers.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Reporters.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Settings.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Symbols.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Typers.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Util.scala create mode 100644 src/compiler/scala/reflect/reify/Errors.scala create mode 100644 src/compiler/scala/reflect/reify/NodePrinters.scala create mode 100644 src/compiler/scala/reflect/reify/Phases.scala create mode 100644 src/compiler/scala/reflect/reify/Reifiers.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Names.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Positions.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Symbols.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Trees.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Types.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Util.scala create mode 100644 src/compiler/scala/reflect/reify/package.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Calculate.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Metalevels.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Reify.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Reshape.scala create mode 100644 src/compiler/scala/reflect/runtime/ClassLoaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/Loaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/Memoizer.scala delete mode 100644 src/compiler/scala/reflect/runtime/RuntimeTypes.scala create mode 100644 src/compiler/scala/reflect/runtime/SymbolLoaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/TreeBuildUtil.scala create mode 100644 src/compiler/scala/reflect/runtime/package.scala create mode 100644 src/compiler/scala/tools/nsc/ClassLoaders.scala delete mode 100644 src/compiler/scala/tools/nsc/MacroContext.scala create mode 100644 src/compiler/scala/tools/nsc/ToolBoxes.scala create mode 100644 src/compiler/scala/tools/nsc/ast/FreeVars.scala create mode 100644 src/compiler/scala/tools/nsc/ast/Positions.scala delete mode 100644 src/compiler/scala/tools/nsc/ast/Reifiers.scala delete mode 100644 src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala delete mode 100644 src/compiler/scala/tools/nsc/symtab/Positions.scala create mode 100644 src/library/scala/reflect/ArrayTags.scala delete mode 100644 src/library/scala/reflect/ClassManifest.scala create mode 100644 src/library/scala/reflect/ClassTags.scala delete mode 100644 src/library/scala/reflect/Manifest.scala delete mode 100644 src/library/scala/reflect/NoManifest.scala delete mode 100644 src/library/scala/reflect/OptManifest.scala create mode 100644 src/library/scala/reflect/TagMaterialization.scala create mode 100644 src/library/scala/reflect/api/Attachments.scala create mode 100644 src/library/scala/reflect/api/ClassLoaders.scala create mode 100644 src/library/scala/reflect/api/Exprs.scala create mode 100644 src/library/scala/reflect/api/FreeVars.scala create mode 100644 src/library/scala/reflect/api/Importers.scala create mode 100644 src/library/scala/reflect/api/Reporters.scala delete mode 100644 src/library/scala/reflect/api/RuntimeTypes.scala create mode 100644 src/library/scala/reflect/api/ToolBoxes.scala create mode 100644 src/library/scala/reflect/api/TypeTags.scala delete mode 100644 src/library/scala/reflect/macro/Context.scala create mode 100644 src/library/scala/reflect/makro/Aliases.scala create mode 100644 src/library/scala/reflect/makro/CapturedVariables.scala create mode 100644 src/library/scala/reflect/makro/Context.scala create mode 100644 src/library/scala/reflect/makro/Enclosures.scala create mode 100644 src/library/scala/reflect/makro/Infrastructure.scala create mode 100644 src/library/scala/reflect/makro/Names.scala create mode 100644 src/library/scala/reflect/makro/Reifiers.scala create mode 100644 src/library/scala/reflect/makro/Reporters.scala create mode 100644 src/library/scala/reflect/makro/Settings.scala create mode 100644 src/library/scala/reflect/makro/Symbols.scala create mode 100644 src/library/scala/reflect/makro/Typers.scala create mode 100644 src/library/scala/reflect/makro/Util.scala create mode 100644 src/library/scala/reflect/makro/internal/macroImpl.scala create mode 100644 src/library/scala/reflect/makro/internal/typeTagImpl.scala delete mode 100644 test/files/jvm/manifests.check create mode 100644 test/files/jvm/manifests.check.temporarily.disabled delete mode 100644 test/files/jvm/manifests.scala create mode 100644 test/files/jvm/manifests.scala.temporarily.disabled delete mode 100644 test/files/macros/Printf.scala delete mode 100644 test/files/macros/Test.scala delete mode 100644 test/files/macros/macros_v0001.bat delete mode 100644 test/files/macros/macros_v0001.sh create mode 100644 test/files/neg/classtags_contextbound_a.check create mode 100644 test/files/neg/classtags_contextbound_a.scala create mode 100644 test/files/neg/classtags_contextbound_b.check create mode 100644 test/files/neg/classtags_contextbound_b.scala create mode 100644 test/files/neg/classtags_contextbound_c.check create mode 100644 test/files/neg/classtags_contextbound_c.scala delete mode 100644 test/files/neg/macro-argtype-mismatch/Macros_1.scala delete mode 100644 test/files/neg/macro-argtype-mismatch/Test_2.scala create mode 100644 test/files/neg/macro-basic-mamdmi.check create mode 100644 test/files/neg/macro-basic-mamdmi.flags create mode 100644 test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala create mode 100644 test/files/neg/macro-cyclic.check create mode 100644 test/files/neg/macro-cyclic.flags create mode 100644 test/files/neg/macro-cyclic/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.check create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala create mode 100644 test/files/neg/macro-deprecate-idents.check create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_4.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_5.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Def_13.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_6.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_7.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_10.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_11.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Type_3.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Val_1.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Var_2.scala create mode 100644 test/files/neg/macro-deprecate-idents/Main.scala create mode 100644 test/files/neg/macro-invalidimpl-a.check create mode 100644 test/files/neg/macro-invalidimpl-a.flags create mode 100644 test/files/neg/macro-invalidimpl-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-b.check create mode 100644 test/files/neg/macro-invalidimpl-b.flags create mode 100644 test/files/neg/macro-invalidimpl-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-c.check create mode 100644 test/files/neg/macro-invalidimpl-c.flags create mode 100644 test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidimpl-c/Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-d.check create mode 100644 test/files/neg/macro-invalidimpl-d.flags create mode 100644 test/files/neg/macro-invalidimpl-d/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-e.check create mode 100644 test/files/neg/macro-invalidimpl-e.flags create mode 100644 test/files/neg/macro-invalidimpl-e/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-f.check create mode 100644 test/files/neg/macro-invalidimpl-f.flags create mode 100644 test/files/neg/macro-invalidimpl-f/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-g.check create mode 100644 test/files/neg/macro-invalidimpl-g.flags create mode 100644 test/files/neg/macro-invalidimpl-g/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-h.check create mode 100644 test/files/neg/macro-invalidimpl-h.flags create mode 100644 test/files/neg/macro-invalidimpl-h/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidret-nontree.check create mode 100644 test/files/neg/macro-invalidret-nontree.flags create mode 100644 test/files/neg/macro-invalidret-nontree/Impls_1.scala create mode 100644 test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidret-nonuniversetree.check create mode 100644 test/files/neg/macro-invalidret-nonuniversetree.flags create mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala create mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-a.check create mode 100644 test/files/neg/macro-invalidshape-a.flags create mode 100644 test/files/neg/macro-invalidshape-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-b.check create mode 100644 test/files/neg/macro-invalidshape-b.flags create mode 100644 test/files/neg/macro-invalidshape-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-c.check create mode 100644 test/files/neg/macro-invalidshape-c.flags create mode 100644 test/files/neg/macro-invalidshape-c/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-c/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-d.check create mode 100644 test/files/neg/macro-invalidshape-d.flags create mode 100644 test/files/neg/macro-invalidshape-d/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-context-bounds.check create mode 100644 test/files/neg/macro-invalidsig-context-bounds.flags create mode 100644 test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx.check create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-implicit-params.check create mode 100644 test/files/neg/macro-invalidsig-implicit-params.flags create mode 100644 test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-implicit-params/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badargc.check create mode 100644 test/files/neg/macro-invalidsig-params-badargc.flags create mode 100644 test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badargc/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badtype.check create mode 100644 test/files/neg/macro-invalidsig-params-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badtype/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs.check create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs.flags create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch.check create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch.flags create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype.check create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a.check create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b.check create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badargs.check create mode 100644 test/files/neg/macro-invalidusage-badargs.flags create mode 100644 test/files/neg/macro-invalidusage-badargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds.check create mode 100644 test/files/neg/macro-invalidusage-badbounds.flags create mode 100644 test/files/neg/macro-invalidusage-badbounds/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badtargs.check create mode 100644 test/files/neg/macro-invalidusage-badtargs.flags create mode 100644 test/files/neg/macro-invalidusage-badtargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax.check create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax.flags create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala create mode 100644 test/files/neg/macro-keyword.check create mode 100644 test/files/neg/macro-keyword.flags create mode 100644 test/files/neg/macro-keyword/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-keyword/Macros_Class_4.scala create mode 100644 test/files/neg/macro-keyword/Macros_Class_5.scala create mode 100644 test/files/neg/macro-keyword/Macros_Def_13.scala create mode 100644 test/files/neg/macro-keyword/Macros_Object_6.scala create mode 100644 test/files/neg/macro-keyword/Macros_Object_7.scala create mode 100644 test/files/neg/macro-keyword/Macros_Package_10.scala create mode 100644 test/files/neg/macro-keyword/Macros_Package_11.scala create mode 100644 test/files/neg/macro-keyword/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-keyword/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-keyword/Macros_Type_3.scala create mode 100644 test/files/neg/macro-keyword/Macros_Val_1.scala create mode 100644 test/files/neg/macro-keyword/Macros_Var_2.scala create mode 100644 test/files/neg/macro-noexpand/Impls_1.scala delete mode 100644 test/files/neg/macro-noexpand/Macros_1.scala create mode 100644 test/files/neg/macro-noexpand/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-noexpand/Test_2.scala delete mode 100644 test/files/neg/macro-noncompilertree/Macros_1.scala delete mode 100644 test/files/neg/macro-nontree/Macros_1.scala create mode 100644 test/files/neg/macro-nontypeablebody.check create mode 100644 test/files/neg/macro-nontypeablebody.flags create mode 100644 test/files/neg/macro-nontypeablebody/Impls_1.scala create mode 100644 test/files/neg/macro-nontypeablebody/Macros_Test_2.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a.check create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a.flags create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b.check create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b.flags create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala create mode 100644 test/files/neg/macro-override-method-overrides-macro.check create mode 100644 test/files/neg/macro-override-method-overrides-macro.flags create mode 100644 test/files/neg/macro-override-method-overrides-macro/Impls_1.scala create mode 100644 test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check create mode 100644 test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-typeparams-notags.check create mode 100644 test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-usetypetag.check create mode 100644 test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala create mode 100644 test/files/neg/macro-without-xmacros-a.check create mode 100644 test/files/neg/macro-without-xmacros-a/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Test_3.scala create mode 100644 test/files/neg/macro-without-xmacros-b.check create mode 100644 test/files/neg/macro-without-xmacros-b/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Test_3.scala delete mode 100644 test/files/neg/reify_ann2a.check delete mode 100644 test/files/neg/reify_ann2a.scala create mode 100644 test/files/neg/t5334_1.check create mode 100644 test/files/neg/t5334_1.scala create mode 100644 test/files/neg/t5334_2.check create mode 100644 test/files/neg/t5334_2.scala delete mode 100644 test/files/pos/implicits.scala create mode 100644 test/files/pos/implicits.scala.temporarily.disabled delete mode 100644 test/files/pos/macros.flags delete mode 100644 test/files/pos/macros.scala delete mode 100644 test/files/pos/manifest1.scala create mode 100644 test/files/pos/manifest1.scala.temporarily.disabled create mode 100644 test/files/run/classtags_contextbound.check create mode 100644 test/files/run/classtags_contextbound.scala create mode 100644 test/files/run/classtags_core.check create mode 100644 test/files/run/classtags_core.scala delete mode 100644 test/files/run/existentials3.check create mode 100644 test/files/run/existentials3.check.temporarily.disabled delete mode 100644 test/files/run/existentials3.scala create mode 100644 test/files/run/existentials3.scala.temporarily.disabled create mode 100644 test/files/run/groundtypetags_core.check create mode 100644 test/files/run/groundtypetags_core.scala create mode 100644 test/files/run/macro-abort-fresh.check create mode 100644 test/files/run/macro-abort-fresh.flags create mode 100644 test/files/run/macro-abort-fresh/Macros_1.scala create mode 100644 test/files/run/macro-abort-fresh/Test_2.scala create mode 100644 test/files/run/macro-basic-ma-md-mi.check create mode 100644 test/files/run/macro-basic-ma-md-mi.flags create mode 100644 test/files/run/macro-basic-ma-md-mi/Impls_1.scala create mode 100644 test/files/run/macro-basic-ma-md-mi/Macros_2.scala create mode 100644 test/files/run/macro-basic-ma-md-mi/Test_3.scala create mode 100644 test/files/run/macro-basic-ma-mdmi.check create mode 100644 test/files/run/macro-basic-ma-mdmi.flags create mode 100644 test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala create mode 100644 test/files/run/macro-basic-ma-mdmi/Test_2.scala create mode 100644 test/files/run/macro-basic-mamd-mi.check create mode 100644 test/files/run/macro-basic-mamd-mi.flags create mode 100644 test/files/run/macro-basic-mamd-mi/Impls_1.scala create mode 100644 test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala delete mode 100644 test/files/run/macro-basic.check delete mode 100644 test/files/run/macro-basic.flags delete mode 100644 test/files/run/macro-basic/Macros_1.scala delete mode 100644 test/files/run/macro-basic/Test_2.scala create mode 100644 test/files/run/macro-bodyexpandstoimpl.check create mode 100644 test/files/run/macro-bodyexpandstoimpl.flags create mode 100644 test/files/run/macro-bodyexpandstoimpl/Impls_1.scala create mode 100644 test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-annotation.check create mode 100644 test/files/run/macro-declared-in-annotation.flags create mode 100644 test/files/run/macro-declared-in-annotation/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-annotation/Macros_2.scala create mode 100644 test/files/run/macro-declared-in-annotation/Test_3.scala create mode 100644 test/files/run/macro-declared-in-anonymous.check create mode 100644 test/files/run/macro-declared-in-anonymous.flags create mode 100644 test/files/run/macro-declared-in-anonymous/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-block.check create mode 100644 test/files/run/macro-declared-in-block.flags create mode 100644 test/files/run/macro-declared-in-block/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-block/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class-class.check create mode 100644 test/files/run/macro-declared-in-class-class.flags create mode 100644 test/files/run/macro-declared-in-class-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class-object.check create mode 100644 test/files/run/macro-declared-in-class-object.flags create mode 100644 test/files/run/macro-declared-in-class-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class.check create mode 100644 test/files/run/macro-declared-in-class.flags create mode 100644 test/files/run/macro-declared-in-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-default-param.check create mode 100644 test/files/run/macro-declared-in-default-param.flags create mode 100644 test/files/run/macro-declared-in-default-param/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-default-param/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-implicit-class.check create mode 100644 test/files/run/macro-declared-in-implicit-class.flags create mode 100644 test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala create mode 100644 test/files/run/macro-declared-in-implicit-class/Test_2.scala create mode 100644 test/files/run/macro-declared-in-method.check create mode 100644 test/files/run/macro-declared-in-method.flags create mode 100644 test/files/run/macro-declared-in-method/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-method/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object-class.check create mode 100644 test/files/run/macro-declared-in-object-class.flags create mode 100644 test/files/run/macro-declared-in-object-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object-object.check create mode 100644 test/files/run/macro-declared-in-object-object.flags create mode 100644 test/files/run/macro-declared-in-object-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object.check create mode 100644 test/files/run/macro-declared-in-object.flags create mode 100644 test/files/run/macro-declared-in-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-package-object.check create mode 100644 test/files/run/macro-declared-in-package-object.flags create mode 100644 test/files/run/macro-declared-in-package-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-package-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-refinement.check create mode 100644 test/files/run/macro-declared-in-refinement.flags create mode 100644 test/files/run/macro-declared-in-refinement/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-refinement/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-trait.check create mode 100644 test/files/run/macro-declared-in-trait.flags create mode 100644 test/files/run/macro-declared-in-trait/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-trait/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-a.check create mode 100644 test/files/run/macro-def-infer-return-type-a.flags create mode 100644 test/files/run/macro-def-infer-return-type-a/Impls_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-b.check create mode 100644 test/files/run/macro-def-infer-return-type-b.flags create mode 100644 test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-b/Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-c.check create mode 100644 test/files/run/macro-def-infer-return-type-c.flags create mode 100644 test/files/run/macro-def-infer-return-type-c/Impls_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-a.check create mode 100644 test/files/run/macro-def-path-dependent-a.flags create mode 100644 test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-a/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-b.check create mode 100644 test/files/run/macro-def-path-dependent-b.flags create mode 100644 test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-b/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-c.check create mode 100644 test/files/run/macro-def-path-dependent-c.flags create mode 100644 test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-c/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-d.check create mode 100644 test/files/run/macro-def-path-dependent-d.flags create mode 100644 test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-d/Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit.check create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit.flags create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-val.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-val.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-view.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-view.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-multiple-arglists.check create mode 100644 test/files/run/macro-expand-multiple-arglists.flags create mode 100644 test/files/run/macro-expand-multiple-arglists/Impls_1.scala create mode 100644 test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-nullary-generic.check create mode 100644 test/files/run/macro-expand-nullary-generic.flags create mode 100644 test/files/run/macro-expand-nullary-generic/Impls_1.scala create mode 100644 test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-nullary-nongeneric.check create mode 100644 test/files/run/macro-expand-nullary-nongeneric.flags create mode 100644 test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala create mode 100644 test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-overload.check create mode 100644 test/files/run/macro-expand-overload.flags create mode 100644 test/files/run/macro-expand-overload/Impls_1.scala create mode 100644 test/files/run/macro-expand-overload/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-override.check create mode 100644 test/files/run/macro-expand-override.flags create mode 100644 test/files/run/macro-expand-override/Impls_1.scala create mode 100644 test/files/run/macro-expand-override/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-recursive.check create mode 100644 test/files/run/macro-expand-recursive.flags create mode 100644 test/files/run/macro-expand-recursive/Impls_1.scala create mode 100644 test/files/run/macro-expand-recursive/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-a.check create mode 100644 test/files/run/macro-expand-tparams-bounds-a.flags create mode 100644 test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-b.check create mode 100644 test/files/run/macro-expand-tparams-bounds-b.flags create mode 100644 test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-explicit.check create mode 100644 test/files/run/macro-expand-tparams-explicit.flags create mode 100644 test/files/run/macro-expand-tparams-explicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-implicit.check create mode 100644 test/files/run/macro-expand-tparams-implicit.flags create mode 100644 test/files/run/macro-expand-tparams-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-only-in-impl.flags create mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-optional.check create mode 100644 test/files/run/macro-expand-tparams-optional.flags create mode 100644 test/files/run/macro-expand-tparams-optional/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-a.check create mode 100644 test/files/run/macro-expand-tparams-prefix-a.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-b.check create mode 100644 test/files/run/macro-expand-tparams-prefix-b.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c1.check create mode 100644 test/files/run/macro-expand-tparams-prefix-c1.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c2.check create mode 100644 test/files/run/macro-expand-tparams-prefix-c2.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-d1.check create mode 100644 test/files/run/macro-expand-tparams-prefix-d1.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs.check create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs.flags create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-impl-default-params.check create mode 100644 test/files/run/macro-impl-default-params.flags create mode 100644 test/files/run/macro-impl-default-params/Impls_Macros_1.scala create mode 100644 test/files/run/macro-impl-default-params/Test_2.scala create mode 100644 test/files/run/macro-impl-rename-context.check create mode 100644 test/files/run/macro-impl-rename-context.flags create mode 100644 test/files/run/macro-impl-rename-context/Impls_Macros_1.scala create mode 100644 test/files/run/macro-impl-rename-context/Test_2.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags create mode 100644 test/files/run/macro-invalidret-nontypeable.check create mode 100644 test/files/run/macro-invalidret-nontypeable.flags create mode 100644 test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidret-nontypeable/Test_2.scala create mode 100644 test/files/run/macro-invalidusage-badret.check create mode 100644 test/files/run/macro-invalidusage-badret.flags create mode 100644 test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidusage-badret/Test_2.scala create mode 100644 test/files/run/macro-invalidusage-partialapplication.check create mode 100644 test/files/run/macro-invalidusage-partialapplication.flags create mode 100644 test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidusage-partialapplication/Test_2.scala create mode 100644 test/files/run/macro-openmacros.check create mode 100644 test/files/run/macro-openmacros.flags create mode 100644 test/files/run/macro-openmacros/Impls_Macros_1.scala create mode 100644 test/files/run/macro-openmacros/Test_2.scala create mode 100644 test/files/run/macro-quasiinvalidbody-c.check create mode 100644 test/files/run/macro-quasiinvalidbody-c.flags create mode 100644 test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala create mode 100644 test/files/run/macro-quasiinvalidbody-c/Test_2.scala create mode 100644 test/files/run/macro-range/Common_1.scala create mode 100644 test/files/run/macro-range/Expansion_Impossible_2.scala create mode 100644 test/files/run/macro-range/Expansion_Possible_3.scala delete mode 100644 test/files/run/macro-range/macro_range_1.scala delete mode 100644 test/files/run/macro-range/macro_range_2.scala create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi.check create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi.flags create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi.check create mode 100644 test/files/run/macro-reflective-mamd-normal-mi.flags create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala create mode 100644 test/files/run/macro-reify-basic.check create mode 100644 test/files/run/macro-reify-basic.flags create mode 100644 test/files/run/macro-reify-basic/Macros_1.scala create mode 100644 test/files/run/macro-reify-basic/Test_2.scala create mode 100644 test/files/run/macro-reify-eval-eval.check create mode 100644 test/files/run/macro-reify-eval-eval.flags create mode 100644 test/files/run/macro-reify-eval-eval/Macros_1.scala create mode 100644 test/files/run/macro-reify-eval-eval/Test_2.scala create mode 100644 test/files/run/macro-reify-eval-outside-reify.check create mode 100644 test/files/run/macro-reify-eval-outside-reify.flags create mode 100644 test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-eval-outside-reify/Test_2.scala create mode 100644 test/files/run/macro-reify-freevars.check create mode 100644 test/files/run/macro-reify-freevars.flags create mode 100644 test/files/run/macro-reify-freevars/Macros_1.scala create mode 100644 test/files/run/macro-reify-freevars/Test_2.scala create mode 100644 test/files/run/macro-reify-groundtypetag-notypeparams.check create mode 100644 test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala create mode 100644 test/files/run/macro-reify-groundtypetag-typeparams-tags.check create mode 100644 test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala create mode 100644 test/files/run/macro-reify-nested-a.check create mode 100644 test/files/run/macro-reify-nested-a.flags create mode 100644 test/files/run/macro-reify-nested-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-nested-a/Test_2.scala create mode 100644 test/files/run/macro-reify-nested-b.check create mode 100644 test/files/run/macro-reify-nested-b.flags create mode 100644 test/files/run/macro-reify-nested-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-nested-b/Test_2.scala create mode 100644 test/files/run/macro-reify-ref-to-packageless.check create mode 100644 test/files/run/macro-reify-ref-to-packageless.flags create mode 100644 test/files/run/macro-reify-ref-to-packageless/Impls_1.scala create mode 100644 test/files/run/macro-reify-ref-to-packageless/Test_2.scala create mode 100644 test/files/run/macro-reify-tagful-a.check create mode 100644 test/files/run/macro-reify-tagful-a.flags create mode 100644 test/files/run/macro-reify-tagful-a/Macros_1.scala create mode 100644 test/files/run/macro-reify-tagful-a/Test_2.scala create mode 100644 test/files/run/macro-reify-tagless-a.check create mode 100644 test/files/run/macro-reify-tagless-a.flags create mode 100644 test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-tagless-a/Test_2.scala create mode 100644 test/files/run/macro-reify-typetag-notypeparams.check create mode 100644 test/files/run/macro-reify-typetag-notypeparams/Test.scala create mode 100644 test/files/run/macro-reify-typetag-typeparams-notags.check create mode 100644 test/files/run/macro-reify-typetag-typeparams-notags/Test.scala create mode 100644 test/files/run/macro-reify-typetag-typeparams-tags.check create mode 100644 test/files/run/macro-reify-typetag-typeparams-tags/Test.scala create mode 100644 test/files/run/macro-reify-typetag-usegroundtypetag.check create mode 100644 test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala create mode 100644 test/files/run/macro-reify-unreify.check create mode 100644 test/files/run/macro-reify-unreify.flags create mode 100644 test/files/run/macro-reify-unreify/Macros_1.scala create mode 100644 test/files/run/macro-reify-unreify/Test_2.scala create mode 100644 test/files/run/macro-reify-value-outside-reify.check create mode 100644 test/files/run/macro-reify-value-outside-reify.flags create mode 100644 test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-value-outside-reify/Test_2.scala delete mode 100644 test/files/run/macro-rettype-mismatch/Macros_1.scala delete mode 100644 test/files/run/macro-rettype-mismatch/Test_2.scala create mode 100644 test/files/run/macro-settings.check create mode 100644 test/files/run/macro-settings.flags create mode 100644 test/files/run/macro-settings/Impls_Macros_1.scala create mode 100644 test/files/run/macro-settings/Test_2.scala create mode 100644 test/files/run/macro-sip19-revised.check create mode 100644 test/files/run/macro-sip19-revised.flags create mode 100644 test/files/run/macro-sip19-revised/Impls_Macros_1.scala create mode 100644 test/files/run/macro-sip19-revised/Test_2.scala create mode 100644 test/files/run/macro-sip19.check create mode 100644 test/files/run/macro-sip19.flags create mode 100644 test/files/run/macro-sip19/Impls_Macros_1.scala create mode 100644 test/files/run/macro-sip19/Test_2.scala create mode 100644 test/files/run/macro-typecheck-implicitsdisabled.check create mode 100644 test/files/run/macro-typecheck-implicitsdisabled.flags create mode 100644 test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala create mode 100644 test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled.check create mode 100644 test/files/run/macro-typecheck-macrosdisabled.flags create mode 100644 test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled/Test_2.scala create mode 100644 test/files/run/macro-undetparams-consfromsls.check create mode 100644 test/files/run/macro-undetparams-consfromsls.flags create mode 100644 test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala create mode 100644 test/files/run/macro-undetparams-consfromsls/Test_2.scala create mode 100644 test/files/run/macro-undetparams-implicitval.check create mode 100644 test/files/run/macro-undetparams-implicitval.flags create mode 100644 test/files/run/macro-undetparams-implicitval/Test.scala create mode 100644 test/files/run/macro-undetparams-macroitself.check create mode 100644 test/files/run/macro-undetparams-macroitself.flags create mode 100644 test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala create mode 100644 test/files/run/macro-undetparams-macroitself/Test_2.scala create mode 100644 test/files/run/reify_ann2a.check create mode 100644 test/files/run/reify_ann2a.scala create mode 100644 test/files/run/reify_ann3.check create mode 100644 test/files/run/reify_ann3.scala create mode 100644 test/files/run/reify_ann4.check create mode 100644 test/files/run/reify_ann4.scala create mode 100644 test/files/run/reify_ann5.check create mode 100644 test/files/run/reify_ann5.scala create mode 100644 test/files/run/reify_classfileann_b.check create mode 100644 test/files/run/reify_classfileann_b.scala create mode 100644 test/files/run/reify_closure8b.check create mode 100644 test/files/run/reify_closure8b.scala create mode 100644 test/files/run/reify_metalevel_breach_+0_refers_to_1.check create mode 100644 test/files/run/reify_metalevel_breach_+0_refers_to_1.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_1.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_1.scala create mode 100644 test/files/run/reify_nested_inner_refers_to_global.check create mode 100644 test/files/run/reify_nested_inner_refers_to_global.scala create mode 100644 test/files/run/reify_nested_inner_refers_to_local.check create mode 100644 test/files/run/reify_nested_inner_refers_to_local.scala create mode 100644 test/files/run/reify_nested_outer_refers_to_global.check create mode 100644 test/files/run/reify_nested_outer_refers_to_global.scala create mode 100644 test/files/run/reify_nested_outer_refers_to_local.check create mode 100644 test/files/run/reify_nested_outer_refers_to_local.scala create mode 100644 test/files/run/reify_newimpl_01.check create mode 100644 test/files/run/reify_newimpl_01.scala create mode 100644 test/files/run/reify_newimpl_02.check create mode 100644 test/files/run/reify_newimpl_02.scala create mode 100644 test/files/run/reify_newimpl_03.check create mode 100644 test/files/run/reify_newimpl_03.scala create mode 100644 test/files/run/reify_newimpl_04.check create mode 100644 test/files/run/reify_newimpl_04.scala create mode 100644 test/files/run/reify_newimpl_05.check create mode 100644 test/files/run/reify_newimpl_05.scala create mode 100644 test/files/run/reify_newimpl_06.check create mode 100644 test/files/run/reify_newimpl_06.scala create mode 100644 test/files/run/reify_newimpl_09.check create mode 100644 test/files/run/reify_newimpl_09.scala create mode 100644 test/files/run/reify_newimpl_10.check create mode 100644 test/files/run/reify_newimpl_10.scala create mode 100644 test/files/run/reify_newimpl_11.check create mode 100644 test/files/run/reify_newimpl_11.scala create mode 100644 test/files/run/reify_newimpl_12.check create mode 100644 test/files/run/reify_newimpl_12.scala create mode 100644 test/files/run/reify_newimpl_13.check create mode 100644 test/files/run/reify_newimpl_13.scala create mode 100644 test/files/run/reify_newimpl_14.check create mode 100644 test/files/run/reify_newimpl_14.scala create mode 100644 test/files/run/reify_newimpl_15.check create mode 100644 test/files/run/reify_newimpl_15.scala create mode 100644 test/files/run/reify_newimpl_16.check create mode 100644 test/files/run/reify_newimpl_16.scala create mode 100644 test/files/run/reify_newimpl_17.check create mode 100644 test/files/run/reify_newimpl_17.scala create mode 100644 test/files/run/reify_newimpl_18.check create mode 100644 test/files/run/reify_newimpl_18.scala create mode 100644 test/files/run/reify_newimpl_19.check create mode 100644 test/files/run/reify_newimpl_19.scala create mode 100644 test/files/run/reify_newimpl_20.check create mode 100644 test/files/run/reify_newimpl_20.scala create mode 100644 test/files/run/reify_newimpl_21.check create mode 100644 test/files/run/reify_newimpl_21.scala create mode 100644 test/files/run/reify_newimpl_22.check create mode 100644 test/files/run/reify_newimpl_22.scala create mode 100644 test/files/run/reify_newimpl_23.check create mode 100644 test/files/run/reify_newimpl_23.scala create mode 100644 test/files/run/reify_newimpl_24.check create mode 100644 test/files/run/reify_newimpl_24.scala create mode 100644 test/files/run/reify_newimpl_25.check create mode 100644 test/files/run/reify_newimpl_25.scala create mode 100644 test/files/run/reify_newimpl_26.check create mode 100644 test/files/run/reify_newimpl_26.scala create mode 100644 test/files/run/reify_newimpl_27.check create mode 100644 test/files/run/reify_newimpl_27.scala create mode 100644 test/files/run/reify_newimpl_28.check create mode 100644 test/files/run/reify_newimpl_28.scala create mode 100644 test/files/run/reify_newimpl_29.check create mode 100644 test/files/run/reify_newimpl_29.scala create mode 100644 test/files/run/reify_newimpl_30.check create mode 100644 test/files/run/reify_newimpl_30.scala create mode 100644 test/files/run/reify_newimpl_31.check create mode 100644 test/files/run/reify_newimpl_31.scala create mode 100644 test/files/run/reify_newimpl_32.check create mode 100644 test/files/run/reify_newimpl_32.scala create mode 100644 test/files/run/reify_newimpl_33.check create mode 100644 test/files/run/reify_newimpl_33.scala create mode 100644 test/files/run/reify_newimpl_34.check create mode 100644 test/files/run/reify_newimpl_34.scala create mode 100644 test/files/run/reify_newimpl_36.check create mode 100644 test/files/run/reify_newimpl_36.scala create mode 100644 test/files/run/reify_newimpl_37.check create mode 100644 test/files/run/reify_newimpl_37.scala create mode 100644 test/files/run/reify_newimpl_38.check create mode 100644 test/files/run/reify_newimpl_38.scala create mode 100644 test/files/run/reify_newimpl_39.check create mode 100644 test/files/run/reify_newimpl_39.scala create mode 100644 test/files/run/reify_newimpl_40.check create mode 100644 test/files/run/reify_newimpl_40.scala create mode 100644 test/files/run/reify_newimpl_41.check create mode 100644 test/files/run/reify_newimpl_41.scala create mode 100644 test/files/run/reify_newimpl_42.check create mode 100644 test/files/run/reify_newimpl_42.scala create mode 100644 test/files/run/reify_newimpl_43.check create mode 100644 test/files/run/reify_newimpl_43.scala create mode 100644 test/files/run/reify_newimpl_44.check create mode 100644 test/files/run/reify_newimpl_44.scala create mode 100644 test/files/run/reify_newimpl_45.check create mode 100644 test/files/run/reify_newimpl_45.scala create mode 100644 test/files/run/reify_newimpl_47.check create mode 100644 test/files/run/reify_newimpl_47.scala create mode 100644 test/files/run/reify_newimpl_48.check create mode 100644 test/files/run/reify_newimpl_48.scala create mode 100644 test/files/run/reify_newimpl_49.check create mode 100644 test/files/run/reify_newimpl_49.scala create mode 100644 test/files/run/reify_newimpl_50.check create mode 100644 test/files/run/reify_newimpl_50.scala create mode 100644 test/files/run/reify_newimpl_51.check create mode 100644 test/files/run/reify_newimpl_51.scala create mode 100644 test/files/run/reify_newimpl_52.check create mode 100644 test/files/run/reify_newimpl_52.scala create mode 100644 test/files/run/reify_typerefs_1a.check create mode 100644 test/files/run/reify_typerefs_1a.scala create mode 100644 test/files/run/reify_typerefs_1b.check create mode 100644 test/files/run/reify_typerefs_1b.scala create mode 100644 test/files/run/reify_typerefs_2a.check create mode 100644 test/files/run/reify_typerefs_2a.scala create mode 100644 test/files/run/reify_typerefs_2b.check create mode 100644 test/files/run/reify_typerefs_2b.scala create mode 100644 test/files/run/reify_typerefs_3a.check create mode 100644 test/files/run/reify_typerefs_3a.scala create mode 100644 test/files/run/reify_typerefs_3b.check create mode 100644 test/files/run/reify_typerefs_3b.scala delete mode 100644 test/files/run/t1195.check create mode 100644 test/files/run/t1195.check.temporarily.disabled delete mode 100644 test/files/run/t1195.scala create mode 100644 test/files/run/t1195.scala.temporarily.disabled create mode 100644 test/files/run/t3758.check delete mode 100644 test/files/run/t4110.check create mode 100644 test/files/run/t4110.check.temporarily.disabled delete mode 100644 test/files/run/t4110.scala create mode 100644 test/files/run/t4110.scala.temporarily.disabled delete mode 100644 test/files/run/t5258a.check delete mode 100644 test/files/run/t5258a.scala create mode 100644 test/files/run/toolbox_console_reporter.check create mode 100644 test/files/run/toolbox_console_reporter.scala create mode 100644 test/files/run/toolbox_default_reporter_is_silent.check create mode 100644 test/files/run/toolbox_default_reporter_is_silent.scala create mode 100644 test/files/run/toolbox_silent_reporter.check create mode 100644 test/files/run/toolbox_silent_reporter.scala create mode 100644 test/files/run/toolbox_typecheck_implicitsdisabled.check create mode 100644 test/files/run/toolbox_typecheck_implicitsdisabled.scala create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled.check create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled.scala delete mode 100644 test/files/run/treePrint.check create mode 100644 test/files/run/treePrint.check.temporarily.disabled delete mode 100644 test/files/run/treePrint.scala create mode 100644 test/files/run/treePrint.scala.temporarily.disabled create mode 100644 test/files/run/typetags_core.check create mode 100644 test/files/run/typetags_core.scala create mode 100644 test/pending/neg/reify_packed.check create mode 100644 test/pending/neg/reify_packed.scala create mode 100644 test/pending/run/macro-expand-default.flags create mode 100644 test/pending/run/macro-expand-default/Impls_1.scala create mode 100644 test/pending/run/macro-expand-default/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound.check create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound.flags create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-named.flags create mode 100644 test/pending/run/macro-expand-named/Impls_1.scala create mode 100644 test/pending/run/macro-expand-named/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1.check create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1.flags create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1.check create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1.flags create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala delete mode 100644 test/pending/run/macro-overload.check delete mode 100644 test/pending/run/macro-overload.flags delete mode 100644 test/pending/run/macro-overload/Macros_1.scala delete mode 100644 test/pending/run/macro-overload/Test_2.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-a.check create mode 100644 test/pending/run/macro-quasiinvalidbody-a.flags create mode 100644 test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-b.check create mode 100644 test/pending/run/macro-quasiinvalidbody-b.flags create mode 100644 test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala create mode 100644 test/pending/run/macro-reify-array.flags create mode 100644 test/pending/run/macro-reify-array/Macros_1.scala create mode 100644 test/pending/run/macro-reify-array/Test_2.scala create mode 100644 test/pending/run/macro-reify-eval-vs-value.flags create mode 100644 test/pending/run/macro-reify-eval-vs-value/Macros_1.scala create mode 100644 test/pending/run/macro-reify-eval-vs-value/Test_2.scala create mode 100644 test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check create mode 100644 test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala create mode 100644 test/pending/run/macro-reify-tagful-b.check create mode 100644 test/pending/run/macro-reify-tagful-b.flags create mode 100644 test/pending/run/macro-reify-tagful-b/Macros_1.scala create mode 100644 test/pending/run/macro-reify-tagful-b/Test_2.scala create mode 100644 test/pending/run/macro-reify-tagless-b.check create mode 100644 test/pending/run/macro-reify-tagless-b.flags create mode 100644 test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala create mode 100644 test/pending/run/macro-reify-tagless-b/Test_2.scala create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-notags.check create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-tags.check create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala delete mode 100644 test/pending/run/reify_classfileann_b.check delete mode 100644 test/pending/run/reify_classfileann_b.scala delete mode 100644 test/pending/run/reify_closure8b.check delete mode 100644 test/pending/run/reify_closure8b.scala create mode 100644 test/pending/run/reify_newimpl_07.scala create mode 100644 test/pending/run/reify_newimpl_08.scala create mode 100644 test/pending/run/reify_newimpl_35.scala create mode 100644 test/pending/run/reify_newimpl_46.scala create mode 100644 test/pending/run/reify_newimpl_53.scala create mode 100644 test/pending/run/t5258a.check create mode 100644 test/pending/run/t5258a.scala (limited to 'test/files/run') diff --git a/build.xml b/build.xml index 6a3bc1d4c7..29c84cd610 100644 --- a/build.xml +++ b/build.xml @@ -170,7 +170,7 @@ PROPERTIES - + diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index 0bbbea1e7b..d74b6353d9 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -f9fcb59f3dbe1b060f8c57d4463dde5e0796951f ?scala-compiler.jar +d2808836aef2cbee506f9b0b0e346c749cac9ad8 ?scala-compiler.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 703eb006da..78e9f0b593 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -1d53671b52f2052c0690fcef9c9989150d8a4704 ?scala-library.jar +752baeeb4a01c7c50ac0dc6e0f59f5598696a223 ?scala-library.jar diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala index 9a7c79d856..b86c62661a 100644 --- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala +++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala @@ -116,7 +116,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => // Classfile annot: args empty. Scala annot: assocs empty. assert(args.isEmpty || assocs.isEmpty, atp) - // @xeno.by: necessary for reification, see Reifiers.scala for more info + // necessary for reification, see Reifiers.scala for more info private var orig: Tree = EmptyTree def original = orig def setOriginal(t: Tree): this.type = { orig = t; this } @@ -168,24 +168,15 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => * * `assocs` stores arguments to classfile annotations as name-value pairs. */ - sealed abstract class AnnotationInfo extends Product3[Type, List[Tree], List[(Name, ClassfileAnnotArg)]] { + sealed abstract class AnnotationInfo { def atp: Type def args: List[Tree] def assocs: List[(Name, ClassfileAnnotArg)] - // @xeno.by: necessary for reification, see Reifiers.scala for more info + // necessary for reification, see Reifiers.scala for more info def original: Tree def setOriginal(t: Tree): this.type - /** Hand rolling Product. */ - def _1 = atp - def _2 = args - def _3 = assocs - // @xeno.by: original hasn't become a product member for backward compatibility purposes - // def _4 = original - def canEqual(other: Any) = other.isInstanceOf[AnnotationInfo] - override def productPrefix = "AnnotationInfo" - // see annotationArgRewriter lazy val isTrivial = atp.isTrivial && !hasArgWhich(_.isInstanceOf[This]) @@ -270,7 +261,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => } lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] = - reflect.ClassManifest.classType(classOf[ClassfileAnnotArg]) + reflect.ClassManifest[ClassfileAnnotArg](classOf[ClassfileAnnotArg]) object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil) } diff --git a/src/compiler/scala/reflect/internal/CapturedVariables.scala b/src/compiler/scala/reflect/internal/CapturedVariables.scala new file mode 100644 index 0000000000..77909d9157 --- /dev/null +++ b/src/compiler/scala/reflect/internal/CapturedVariables.scala @@ -0,0 +1,36 @@ +package scala.reflect +package internal + +import Flags._ + +trait CapturedVariables { self: SymbolTable => + + import definitions._ + + /** Mark a variable as captured; i.e. force boxing in a *Ref type. + */ + def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED + + /** Mark given identifier as a reference to a captured variable itself + * suppressing dereferencing with the `elem` field. + */ + def referenceCapturedVariable(vble: Symbol): Tree = ReferenceToBoxed(Ident(vble)) + + /** Convert type of a captured variable to *Ref type. + */ + def capturedVariableType(vble: Symbol): Type = + capturedVariableType(vble, NoType, false) + + /** Convert type of a captured variable to *Ref type. + */ + def capturedVariableType(vble: Symbol, tpe: Type = NoType, erasedTypes: Boolean = false): Type = { + val tpe1 = if (tpe == NoType) vble.tpe else tpe + val symClass = tpe1.typeSymbol + def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) = + if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe + else if (erasedTypes) objectRefClass.tpe + else appliedType(objectRefClass, tpe) + if (vble.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass) + else refType(refClass, ObjectRefClass) + } +} diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala index c328cc49cb..135d18d5ad 100644 --- a/src/compiler/scala/reflect/internal/Constants.scala +++ b/src/compiler/scala/reflect/internal/Constants.scala @@ -26,7 +26,7 @@ trait Constants extends api.Constants { final val DoubleTag = 9 final val StringTag = 10 final val NullTag = 11 - final val ClassTag = 12 + final val ClazzTag = 12 // For supporting java enumerations inside java annotations (see ClassfileParser) final val EnumTag = 13 @@ -43,7 +43,7 @@ trait Constants extends api.Constants { case x: Double => DoubleTag case x: String => StringTag case x: Char => CharTag - case x: Type => ClassTag + case x: Type => ClazzTag case x: Symbol => EnumTag case _ => throw new Error("bad constant value: " + value + " of class " + value.getClass) } @@ -70,7 +70,7 @@ trait Constants extends api.Constants { case DoubleTag => DoubleClass.tpe case StringTag => StringClass.tpe case NullTag => NullClass.tpe - case ClassTag => ClassType(value.asInstanceOf[Type]) + case ClazzTag => ClassType(value.asInstanceOf[Type]) case EnumTag => // given (in java): "class A { enum E { VAL1 } }" // - symbolValue: the symbol of the actual enumeration value (VAL1) @@ -201,7 +201,7 @@ trait Constants extends api.Constants { def stringValue: String = if (value == null) "null" - else if (tag == ClassTag) signature(typeValue) + else if (tag == ClazzTag) signature(typeValue) else value.toString() @switch def escapedChar(ch: Char): String = ch match { @@ -221,7 +221,7 @@ trait Constants extends api.Constants { tag match { case NullTag => "null" case StringTag => "\"" + escape(stringValue) + "\"" - case ClassTag => "classOf[" + signature(typeValue) + "]" + case ClazzTag => "classOf[" + signature(typeValue) + "]" case CharTag => "'" + escapedChar(charValue) + "'" case LongTag => longValue.toString() + "L" case _ => String.valueOf(value) diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 6ef6751720..b1c822ed97 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -10,10 +10,29 @@ import annotation.{ switch } import scala.collection.{ mutable, immutable } import Flags._ import PartialFunction._ +import scala.reflect.{ mirror => rm } trait Definitions extends reflect.api.StandardDefinitions { self: SymbolTable => + // [Eugene] find a way to make these non-lazy + lazy val ByteTpe = definitions.ByteClass.asType + lazy val ShortTpe = definitions.ShortClass.asType + lazy val CharTpe = definitions.CharClass.asType + lazy val IntTpe = definitions.IntClass.asType + lazy val LongTpe = definitions.LongClass.asType + lazy val FloatTpe = definitions.FloatClass.asType + lazy val DoubleTpe = definitions.DoubleClass.asType + lazy val BooleanTpe = definitions.BooleanClass.asType + lazy val UnitTpe = definitions.UnitClass.asType + lazy val AnyTpe = definitions.AnyClass.asType + lazy val ObjectTpe = definitions.ObjectClass.asType + lazy val AnyValTpe = definitions.AnyValClass.asType + lazy val AnyRefTpe = definitions.AnyRefClass.asType + lazy val NothingTpe = definitions.NothingClass.asType + lazy val NullTpe = definitions.NullClass.asType + lazy val StringTpe = definitions.StringClass.asType + /** Since both the value parameter types and the result type may * require access to the type parameter symbols, we model polymorphic * creation as a function from those symbols to (formal types, result type). @@ -129,6 +148,7 @@ trait Definitions extends reflect.api.StandardDefinitions { DoubleClass ) def ScalaValueClassCompanions: List[Symbol] = ScalaValueClasses map (_.companionSymbol) + def ScalaPrimitiveValueClasses: List[Symbol] = ScalaValueClasses } object definitions extends AbsDefinitions with ValueClassDefinitions { @@ -446,19 +466,38 @@ trait Definitions extends reflect.api.StandardDefinitions { def methodCache_add = getMember(MethodCacheClass, nme.add_) // scala.reflect - lazy val ReflectApiUniverse = getRequiredClass("scala.reflect.api.Universe") - lazy val ReflectMacroContext = getRequiredClass("scala.reflect.macro.Context") - lazy val ReflectRuntimeMirror = getRequiredModule("scala.reflect.runtime.Mirror") - def freeValueMethod = getMember(ReflectRuntimeMirror, nme.freeValue) + lazy val ReflectPackageClass = getMember(ScalaPackageClass, nme.reflect) lazy val ReflectPackage = getPackageObject("scala.reflect") def Reflect_mirror = getMember(ReflectPackage, nme.mirror) - lazy val PartialManifestClass = getRequiredClass("scala.reflect.ClassManifest") - lazy val PartialManifestModule = getRequiredModule("scala.reflect.ClassManifest") - lazy val FullManifestClass = getRequiredClass("scala.reflect.Manifest") - lazy val FullManifestModule = getRequiredModule("scala.reflect.Manifest") - lazy val OptManifestClass = getRequiredClass("scala.reflect.OptManifest") - lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest") + lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr) + def ExprTree = getMember(ExprClass, nme.tree) + def ExprTpe = getMember(ExprClass, nme.tpe) + def ExprEval = getMember(ExprClass, nme.eval) + def ExprValue = getMember(ExprClass, nme.value) + lazy val ExprModule = getMember(getRequiredClass("scala.reflect.api.Exprs"), nme.Expr) + + lazy val ClassTagClass = getRequiredClass("scala.reflect.ClassTag") + def ClassTagErasure = getMember(ClassTagClass, nme.erasure) + def ClassTagTpe = getMember(ClassTagClass, nme.tpe) + lazy val ClassTagModule = getRequiredModule("scala.reflect.ClassTag") + lazy val TypeTagsClass = getRequiredClass("scala.reflect.api.TypeTags") + lazy val TypeTagClass = getMember(TypeTagsClass, tpnme.TypeTag) + def TypeTagTpe = getMember(TypeTagClass, nme.tpe) + lazy val TypeTagModule = getMember(TypeTagsClass, nme.TypeTag) + lazy val GroundTypeTagClass = getMember(TypeTagsClass, tpnme.GroundTypeTag) + lazy val GroundTypeTagModule = getMember(TypeTagsClass, nme.GroundTypeTag) + + lazy val MacroContextClass = getRequiredClass("scala.reflect.makro.Context") + def MacroContextPrefix = getMember(MacroContextClass, nme.prefix) + def MacroContextPrefixType = getMember(MacroContextClass, tpnme.PrefixType) + def MacroContextMirror = getMember(MacroContextClass, nme.mirror) + def MacroContextReify = getMember(MacroContextClass, nme.reify) + lazy val MacroImplAnnotation = getRequiredClass("scala.reflect.makro.internal.macroImpl") + lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal") + def MacroInternal_materializeClassTag = getMember(MacroInternalPackage, nme.materializeClassTag) + def MacroInternal_materializeTypeTag = getMember(MacroInternalPackage, nme.materializeTypeTag) + def MacroInternal_materializeGroundTypeTag = getMember(MacroInternalPackage, nme.materializeGroundTypeTag) lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature") lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature") @@ -467,33 +506,15 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val OptionClass: Symbol = getRequiredClass("scala.Option") lazy val SomeClass: Symbol = getRequiredClass("scala.Some") lazy val NoneModule: Symbol = getRequiredModule("scala.None") + lazy val SomeModule: Symbol = getRequiredModule("scala.Some") - /** Note: don't use this manifest/type function for anything important, - * as it is incomplete. Would love to have things like existential types - * working, but very unfortunately the manifests just stuff the relevant - * information into the toString method. - */ - def manifestToType(m: OptManifest[_]): Type = m match { - case m: ClassManifest[_] => - val sym = manifestToSymbol(m) - val args = m.typeArguments + // [Eugene] how do I make this work without casts? + // private lazy val importerFromRm = self.mkImporter(rm) + private lazy val importerFromRm = self.mkImporter(rm).asInstanceOf[self.Importer { val from: rm.type }] - if ((sym eq NoSymbol) || args.isEmpty) sym.tpe - else appliedType(sym, args map manifestToType: _*) - case _ => - NoType - } + def manifestToType(m: Manifest[_]): Type = importerFromRm.importType(m.tpe) - def manifestToSymbol(m: ClassManifest[_]): Symbol = m match { - case x: scala.reflect.AnyValManifest[_] => - getMember(ScalaPackageClass, newTypeName("" + x)) - case _ => - val name = m.erasure.getName - if (name endsWith nme.MODULE_SUFFIX_STRING) - getModuleIfDefined(name stripSuffix nme.MODULE_SUFFIX_STRING) - else - getClassIfDefined(name) - } + def manifestToSymbol(m: Manifest[_]): Symbol = importerFromRm.importSymbol(m.tpe.typeSymbol) // The given symbol represents either String.+ or StringAdd.+ def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+ @@ -527,11 +548,6 @@ trait Definitions extends reflect.api.StandardDefinitions { } val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22 - /** The maximal dimensions of a generic array creation. - * I.e. new Array[Array[Array[Array[Array[T]]]]] creates a 5 times - * nested array. More is not allowed. - */ - val MaxArrayDims = 5 lazy val ProductClass = { val arr = mkArityArray("Product", MaxProductArity) ; arr(0) = UnitClass ; arr } lazy val TupleClass = mkArityArray("Tuple", MaxTupleArity) lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0) @@ -993,7 +1009,7 @@ trait Definitions extends reflect.api.StandardDefinitions { } def getDeclIfDefined(owner: Symbol, name: Name): Symbol = owner.info.nonPrivateDecl(name) - + def packageExists(packageName: String): Boolean = getModuleIfDefined(packageName).isPackage diff --git a/src/compiler/scala/reflect/internal/FreeVars.scala b/src/compiler/scala/reflect/internal/FreeVars.scala new file mode 100644 index 0000000000..8b6e8b61f3 --- /dev/null +++ b/src/compiler/scala/reflect/internal/FreeVars.scala @@ -0,0 +1,60 @@ +package scala.reflect +package internal + +trait FreeVars extends api.FreeVars { + self: SymbolTable => + + object FreeTerm extends FreeTermExtractor { + def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] = + Some(freeTerm.name, freeTerm.info, freeTerm.value, freeTerm.origin) + } + + object FreeType extends FreeTypeExtractor { + def unapply(freeType: FreeType): Option[(TypeName, Type, String)] = + Some(freeType.name, freeType.info, freeType.origin) + } + + // [Eugene] am I doing this right? + def freeTerms(tree: Tree): List[FreeTerm] = { + def isFreeTermSym(sym: Symbol) = sym != null && sym.isFreeTerm + def isFreeTermTpe(t: Type) = t != null && isFreeTermSym(t.termSymbol) + + val buf = collection.mutable.Set[Symbol]() + tree foreach (sub => { + if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTermTpe(tpe) => tpe.typeSymbol }) + if (sub.symbol != null && isFreeTermSym(sub.symbol)) buf += sub.symbol + }) + + buf.toList.collect{ case fty: FreeTerm => fty } + } + + // [Eugene] am I doing this right? + def freeTypes(tree: Tree): List[FreeType] = { + def isFreeTypeSym(sym: Symbol) = sym != null && sym.isFreeType + def isFreeTypeTpe(t: Type) = t != null && isFreeTypeSym(t.typeSymbol) + + val buf = collection.mutable.Set[Symbol]() + tree foreach (sub => { + if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTypeTpe(tpe) => tpe.typeSymbol }) + if (sub.symbol != null && isFreeTypeSym(sub.symbol)) buf += sub.symbol + }) + + buf.toList.collect{ case fty: FreeType => fty } + } + + // todo. also update tpe's of dependent free vars + // e.g. if we substitute free$C, then free$C$this should have its info updated + // todo. should also transform typetags of types dependent on that free type? + // [Eugene] how do I check that the substitution is legal w.r.t fty.info? + def substituteFreeTypes(tree0: Tree, subs: Map[FreeType, Type]): Tree = { + val tree = tree0.duplicate + new TreeTypeSubstituter(subs.keys.toList, subs.values.toList).traverse(tree) + tree + } + + // [Eugene] how do I check that the substitution is legal w.r.t fty.info? + def substituteFreeTypes(tpe0: Type, subs: Map[FreeType, Type]): Type = { + val tpe = tpe0 // [Eugene] tpe0.duplicate? + tpe.subst(subs.keys.toList, subs.values.toList) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index c9336e8cf1..ab5e19fca9 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -4,7 +4,24 @@ import scala.collection.mutable.WeakHashMap trait Importers { self: SymbolTable => - abstract class Importer { + // [Eugene] possible to make this less cast-heavy? + def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( + if (self eq from0) { + new Importer { + val from = from0 + val reverse = this.asInstanceOf[from.Importer{ val from: self.type }] + def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol] + def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type] + def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree] + } + } else { + // todo. fix this loophole + assert(from0.isInstanceOf[SymbolTable], "`from` should be an instance of scala.reflect.internal.SymbolTable") + new StandardImporter { val from = from0.asInstanceOf[SymbolTable] } + } + ).asInstanceOf[Importer { val from: from0.type }] + + abstract class StandardImporter extends Importer { val from: SymbolTable @@ -24,13 +41,15 @@ trait Importers { self: SymbolTable => } } - object reverse extends from.Importer { + object reverse extends from.StandardImporter { val from: self.type = self - for ((fromsym, mysym) <- Importer.this.symMap) symMap += ((mysym, fromsym)) - for ((fromtpe, mytpe) <- Importer.this.tpeMap) tpeMap += ((mytpe, fromtpe)) + for ((fromsym, mysym) <- StandardImporter.this.symMap) symMap += ((mysym, fromsym)) + for ((fromtpe, mytpe) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, fromtpe)) } - def importPosition(pos: from.Position): Position = NoPosition + // todo. careful import of positions + def importPosition(pos: from.Position): Position = + pos.asInstanceOf[Position] def importSymbol(sym0: from.Symbol): Symbol = { def doImport(sym: from.Symbol): Symbol = { @@ -51,8 +70,10 @@ trait Importers { self: SymbolTable => linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol) case x: from.ModuleSymbol => linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) - case x: from.FreeVar => - newFreeVar(importName(x.name).toTermName, importType(x.tpe), x.value, myflags) + case x: from.FreeTerm => + newFreeTerm(importName(x.name).toTermName, importType(x.info), x.value, x.origin, myflags) + case x: from.FreeType => + newFreeType(importName(x.name).toTypeName, importType(x.info), x.value, x.origin, myflags) case x: from.TermSymbol => linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) case x: from.TypeSkolem => @@ -374,6 +395,8 @@ trait Importers { self: SymbolTable => case _ => new Ident(importName(name)) } + case from.ReferenceToBoxed(ident) => + new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident }) case from.Literal(constant @ from.Constant(_)) => new Literal(importConstant(constant)) case from.TypeTree() => @@ -425,7 +448,7 @@ trait Importers { self: SymbolTable => def importIdent(tree: from.Ident): Ident = importTree(tree).asInstanceOf[Ident] def importCaseDef(tree: from.CaseDef): CaseDef = importTree(tree).asInstanceOf[CaseDef] def importConstant(constant: from.Constant): Constant = new Constant(constant.tag match { - case ClassTag => importType(constant.value.asInstanceOf[from.Type]) + case ClazzTag => importType(constant.value.asInstanceOf[from.Type]) case EnumTag => importSymbol(constant.value.asInstanceOf[from.Symbol]) case _ => constant.value }) diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala index 05578a2042..ac22017569 100644 --- a/src/compiler/scala/reflect/internal/NameManglers.scala +++ b/src/compiler/scala/reflect/internal/NameManglers.scala @@ -128,12 +128,7 @@ trait NameManglers { else name ) - def macroMethodName(name: Name) = { - val base = if (name.isTypeName) nme.TYPEkw else nme.DEFkw - base append nme.MACRO append name - } - - /** Return the original name and the types on which this name + /** Return the original name and the types on which this name * is specialized. For example, * {{{ * splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D") diff --git a/src/compiler/scala/reflect/internal/Positions.scala b/src/compiler/scala/reflect/internal/Positions.scala index 78de8d0ff2..5ec2659098 100644 --- a/src/compiler/scala/reflect/internal/Positions.scala +++ b/src/compiler/scala/reflect/internal/Positions.scala @@ -3,9 +3,8 @@ package internal trait Positions extends api.Positions { self: SymbolTable => - def focusPos(pos: Position): Position - def isRangePos(pos: Position): Boolean - def showPos(pos: Position): String + type Position = scala.tools.nsc.util.Position + val NoPosition = scala.tools.nsc.util.NoPosition /** A position that wraps a set of trees. * The point of the wrapping position is the point of the default position. @@ -27,4 +26,37 @@ trait Positions extends api.Positions { self: SymbolTable => * to some of the nodes in `tree`. */ def ensureNonOverlapping(tree: Tree, others: List[Tree]) {} + + trait PosAssigner extends Traverser { + var pos: Position + } + protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner + + protected class DefaultPosAssigner extends PosAssigner { + var pos: Position = _ + override def traverse(t: Tree) { + if (t eq EmptyTree) () + else if (t.pos == NoPosition) { + t.setPos(pos) + super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if? + // @PP: it's pruning whenever it encounters a node with a + // position, which I interpret to mean that (in the author's + // mind at least) either the children of a positioned node will + // already be positioned, or the children of a positioned node + // do not merit positioning. + // + // Whatever the author's rationale, it does seem like a bad idea + // to press on through a positioned node to find unpositioned + // children beneath it and then to assign whatever happens to + // be in `pos` to such nodes. There are supposed to be some + // position invariants which I can't imagine surviving that. + } + } + } + + def atPos[T <: Tree](pos: Position)(tree: T): T = { + posAssigner.pos = pos + posAssigner.traverse(tree) + tree + } } \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/Reporters.scala b/src/compiler/scala/reflect/internal/Reporters.scala new file mode 100644 index 0000000000..20d4a1d026 --- /dev/null +++ b/src/compiler/scala/reflect/internal/Reporters.scala @@ -0,0 +1,74 @@ +package scala.reflect +package internal + +trait Reporters { self: SymbolTable => + + import self.{Reporter => ApiReporter} + import scala.tools.nsc.reporters._ + import scala.tools.nsc.reporters.{Reporter => NscReporter} + import scala.tools.nsc.Settings + + def mkConsoleReporter(minSeverity: Int = 1): ApiReporter = { + val settings = new Settings() + if (minSeverity <= 0) settings.verbose.value = true + if (minSeverity > 1) settings.nowarn.value = true + wrapNscReporter(new ConsoleReporter(settings)) + } + + abstract class ApiToNscReporterProxy(val apiReporter: ApiReporter) extends AbstractReporter { + import apiReporter.{Severity => ApiSeverity} + val API_INFO = apiReporter.INFO + val API_WARNING = apiReporter.WARNING + val API_ERROR = apiReporter.ERROR + + type NscSeverity = Severity + val NSC_INFO = INFO + val NSC_WARNING = WARNING + val NSC_ERROR = ERROR + + def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit = + apiReporter.log(pos, msg, nscSeverity match { + case NSC_INFO => API_INFO + case NSC_WARNING => API_WARNING + case NSC_ERROR => API_ERROR + }) + + def displayPrompt(): Unit = + apiReporter.interactive() + } + + def wrapApiReporter(apiReporter: ApiReporter): NscReporter = new ApiToNscReporterProxy(apiReporter) { + val settings = new Settings() + settings.verbose.value = true + settings.nowarn.value = false + } + + class NscToApiReporterProxy(val nscReporter: NscReporter) extends ApiReporter { + val API_INFO = INFO + val API_WARNING = WARNING + val API_ERROR = ERROR + + def display(info: Info): Unit = info.severity match { + case API_INFO => nscReporter.info(info.pos, info.msg, false) + case API_WARNING => nscReporter.warning(info.pos, info.msg) + case API_ERROR => nscReporter.error(info.pos, info.msg) + } + + def interactive(): Unit = nscReporter match { + case nscReporter: AbstractReporter => nscReporter.displayPrompt() + case _ => // do nothing + } + + override def flush(): Unit = { + super.flush() + nscReporter.flush() + } + + override def reset(): Unit = { + super.reset() + nscReporter.reset() + } + } + + def wrapNscReporter(nscReporter: NscReporter): ApiReporter = new NscToApiReporterProxy(nscReporter) +} diff --git a/src/compiler/scala/reflect/internal/Required.scala b/src/compiler/scala/reflect/internal/Required.scala index 1bf1a2e97e..ba6d65a306 100644 --- a/src/compiler/scala/reflect/internal/Required.scala +++ b/src/compiler/scala/reflect/internal/Required.scala @@ -12,8 +12,6 @@ trait Required { self: SymbolTable => def picklerPhase: Phase - val gen: TreeGen { val global: Required.this.type } - def settings: MutableSettings def forInteractive: Boolean diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 0cd3616ba9..b72610f1e0 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -44,6 +44,7 @@ trait StdNames extends NameManglers { self: SymbolTable => final val IMPLICITkw: TermName = kw("implicit") final val IMPORTkw: TermName = kw("import") final val LAZYkw: TermName = kw("lazy") + final val MACROkw: TermName = kw("macro") final val MATCHkw: TermName = kw("match") final val NEWkw: TermName = kw("new") final val NULLkw: TermName = kw("null") @@ -123,6 +124,9 @@ trait StdNames extends NameManglers { self: SymbolTable => final val List: NameType = "List" final val Seq: NameType = "Seq" final val Symbol: NameType = "Symbol" + final val ClassTag: NameType = "ClassTag" + final val TypeTag : NameType = "TypeTag" + final val GroundTypeTag: NameType = "GroundTypeTag" // fictions we use as both types and terms final val ERROR: NameType = "" @@ -140,10 +144,12 @@ trait StdNames extends NameManglers { self: SymbolTable => final val Any: NameType = "Any" final val AnyVal: NameType = "AnyVal" + final val Expr: NameType = "Expr" final val Nothing: NameType = "Nothing" final val Null: NameType = "Null" final val Object: NameType = "Object" final val PartialFunction: NameType = "PartialFunction" + final val PrefixType: NameType = "PrefixType" final val Product: NameType = "Product" final val Serializable: NameType = "Serializable" final val Singleton: NameType = "Singleton" @@ -185,32 +191,34 @@ trait StdNames extends NameManglers { self: SymbolTable => trait TermNames extends Keywords with CommonNames { // Compiler internal names - val EXPAND_SEPARATOR_STRING = "$$" - - val ANYNAME: NameType = "" - val CONSTRUCTOR: NameType = "" - val FAKE_LOCAL_THIS: NameType = "this$" - val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something? - val LAZY_LOCAL: NameType = "$lzy" - val LOCAL_SUFFIX_STRING = " " - val MACRO: NameType = "macro$" - val MIRROR_PREFIX: NameType = "$mr." - val MIRROR_SHORT: NameType = "$mr" - val MIXIN_CONSTRUCTOR: NameType = "$init$" - val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" - val OUTER: NameType = "$outer" - val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space - val OUTER_SYNTH: NameType = "" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter - val SELECTOR_DUMMY: NameType = "" - val SELF: NameType = "$this" - val SPECIALIZED_INSTANCE: NameType = "specInstance$" - val STAR: NameType = "*" - val THIS: NameType = "_$this" - - final val Nil: NameType = "Nil" - final val Predef: NameType = "Predef" - final val ScalaRunTime: NameType = "ScalaRunTime" - final val Some: NameType = "Some" + val EXPAND_SEPARATOR_STRING = "$$" + + val ANYNAME: NameType = "" + val CONSTRUCTOR: NameType = "" + val FAKE_LOCAL_THIS: NameType = "this$" + val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something? + val LAZY_LOCAL: NameType = "$lzy" + val LOCAL_SUFFIX_STRING = " " + val MIRROR_PREFIX: NameType = "$mr." + val MIRROR_SHORT: NameType = "$mr" + val MIRROR_FREE_PREFIX: NameType = "free$" + val MIRROR_FREE_THIS_SUFFIX: NameType = "$this" + val MIRROR_FREE_VALUE_SUFFIX: NameType = "$value" + val MIXIN_CONSTRUCTOR: NameType = "$init$" + val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" + val OUTER: NameType = "$outer" + val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space + val OUTER_SYNTH: NameType = "" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter + val SELECTOR_DUMMY: NameType = "" + val SELF: NameType = "$this" + val SPECIALIZED_INSTANCE: NameType = "specInstance$" + val STAR: NameType = "*" + val THIS: NameType = "_$this" + + final val Nil: NameType = "Nil" + final val Predef: NameType = "Predef" + final val ScalaRunTime: NameType = "ScalaRunTime" + final val Some: NameType = "Some" val _1 : NameType = "_1" val _2 : NameType = "_2" @@ -260,6 +268,8 @@ trait StdNames extends NameManglers { self: SymbolTable => case _ => newTermName("x$" + i) } + // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here + val QQQ = ??? val ??? = encode("???") val wrapRefArray: NameType = "wrapRefArray" @@ -275,12 +285,38 @@ trait StdNames extends NameManglers { self: SymbolTable => val genericWrapArray: NameType = "genericWrapArray" // Compiler utilized names - // val productElementName: NameType = "productElementName" + + val AnnotatedType: NameType = "AnnotatedType" + val AnnotationInfo: NameType = "AnnotationInfo" + val Any: NameType = "Any" + val AnyVal: NameType = "AnyVal" + val Apply: NameType = "Apply" + val ArrayAnnotArg: NameType = "ArrayAnnotArg" + val ConstantType: NameType = "ConstantType" + val EmptyPackage: NameType = "EmptyPackage" + val EmptyPackageClass: NameType = "EmptyPackageClass" + val Expr: NameType = "Expr" val Ident: NameType = "Ident" + val Import: NameType = "Import" + val Literal: NameType = "Literal" + val LiteralAnnotArg: NameType = "LiteralAnnotArg" + val NestedAnnotArg: NameType = "NestedAnnotArg" + val NoPrefix: NameType = "NoPrefix" + val NoSymbol: NameType = "NoSymbol" + val Nothing: NameType = "Nothing" + val NoType: NameType = "NoType" + val Null: NameType = "Null" + val Object: NameType = "Object" + val RootPackage: NameType = "RootPackage" + val RootClass: NameType = "RootClass" + val Select: NameType = "Select" val StringContext: NameType = "StringContext" val This: NameType = "This" val Tree : NameType = "Tree" + val Tuple2: NameType = "Tuple2" val TYPE_ : NameType = "TYPE" + val TypeApply: NameType = "TypeApply" + val TypeRef: NameType = "TypeRef" val TypeTree: NameType = "TypeTree" val UNIT : NameType = "UNIT" val add_ : NameType = "add" @@ -311,6 +347,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure val conforms: NameType = "conforms" val copy: NameType = "copy" + val definitions: NameType = "definitions" val delayedInit: NameType = "delayedInit" val delayedInitArg: NameType = "delayedInit$body" val drop: NameType = "drop" @@ -322,7 +359,9 @@ trait StdNames extends NameManglers { self: SymbolTable => val equalsNumNum : NameType = "equalsNumNum" val equalsNumObject : NameType = "equalsNumObject" val equals_ : NameType = if (forMSIL) "Equals" else "equals" + val erasure: NameType = "erasure" val error: NameType = "error" + val eval: NameType = "eval" val ex: NameType = "ex" val false_ : NameType = "false" val filter: NameType = "filter" @@ -330,7 +369,6 @@ trait StdNames extends NameManglers { self: SymbolTable => val find_ : NameType = "find" val flatMap: NameType = "flatMap" val foreach: NameType = "foreach" - val freeValue : NameType = "freeValue" val genericArrayOps: NameType = "genericArrayOps" val get: NameType = "get" val getOrElse: NameType = "getOrElse" @@ -339,6 +377,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val hash_ : NameType = "hash" val head: NameType = "head" val identity: NameType = "identity" + val info: NameType = "info" val inlinedEquals: NameType = "inlinedEquals" val isArray: NameType = "isArray" val isDefinedAt: NameType = "isDefinedAt" @@ -350,36 +389,54 @@ trait StdNames extends NameManglers { self: SymbolTable => val lang: NameType = "lang" val length: NameType = "length" val lengthCompare: NameType = "lengthCompare" - val lift_ : NameType = "lift" - val macro_ : NameType = "macro" val macroThis : NameType = "_this" - val macroContext : NameType = "_context" + val macroContext : NameType = "c" val main: NameType = "main" + val manifest: NameType = "manifest" val map: NameType = "map" + val materializeClassTag: NameType = "materializeClassTag" + val materializeTypeTag: NameType = "materializeTypeTag" + val materializeGroundTypeTag: NameType = "materializeGroundTypeTag" val mirror : NameType = "mirror" + val moduleClass : NameType = "moduleClass" + val name: NameType = "name" val ne: NameType = "ne" val newArray: NameType = "newArray" + val newFreeTerm: NameType = "newFreeTerm" + val newFreeType: NameType = "newFreeType" + val newNestedSymbol: NameType = "newNestedSymbol" val newScopeWith: NameType = "newScopeWith" + val nmeNewTermName: NameType = "newTermName" + val nmeNewTypeName: NameType = "newTypeName" val next: NameType = "next" val notifyAll_ : NameType = "notifyAll" val notify_ : NameType = "notify" val null_ : NameType = "null" val ofDim: NameType = "ofDim" + val origin: NameType = "origin" + val prefix : NameType = "prefix" val productArity: NameType = "productArity" val productElement: NameType = "productElement" val productIterator: NameType = "productIterator" val productPrefix: NameType = "productPrefix" val readResolve: NameType = "readResolve" + val reflect : NameType = "reflect" + val reify : NameType = "reify" val runOrElse: NameType = "runOrElse" val runtime: NameType = "runtime" val sameElements: NameType = "sameElements" val scala_ : NameType = "scala" + val selectOverloadedMethod: NameType = "selectOverloadedMethod" + val selectTerm: NameType = "selectTerm" + val selectType: NameType = "selectType" val self: NameType = "self" val setAccessible: NameType = "setAccessible" val setAnnotations: NameType = "setAnnotations" val setSymbol: NameType = "setSymbol" val setType: NameType = "setType" val setTypeSignature: NameType = "setTypeSignature" + val staticClass : NameType = "staticClass" + val staticModule : NameType = "staticModule" val synchronized_ : NameType = "synchronized" val tail: NameType = "tail" val thisModuleType: NameType = "thisModuleType" @@ -390,6 +447,8 @@ trait StdNames extends NameManglers { self: SymbolTable => val toObjectArray : NameType = "toObjectArray" val toSeq: NameType = "toSeq" val toString_ : NameType = if (forMSIL) "ToString" else "toString" + val tpe : NameType = "tpe" + val tree : NameType = "tree" val true_ : NameType = "true" val typedProductIterator: NameType = "typedProductIterator" val unapply: NameType = "unapply" @@ -582,9 +641,14 @@ trait StdNames extends NameManglers { self: SymbolTable => val ZOR = encode("||") // unary operators + // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here + val UNARY_TILDE = UNARY_~ val UNARY_~ = encode("unary_~") + val UNARY_PLUS = UNARY_+ val UNARY_+ = encode("unary_+") + val UNARY_MINUS = UNARY_- val UNARY_- = encode("unary_-") + val UNARY_NOT = UNARY_! val UNARY_! = encode("unary_!") // Grouped here so Cleanup knows what tests to perform. diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 83a24dce68..ffc8178528 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -16,6 +16,7 @@ abstract class SymbolTable extends api.Universe with SymbolCreations with Symbols with SymbolFlags + with FreeVars with Types with Kinds with ExistentialsAndSkolems @@ -34,6 +35,9 @@ abstract class SymbolTable extends api.Universe with TypeDebugging with Importers with Required + with TreeBuildUtil + with Reporters + with CapturedVariables { def rootLoader: LazyType def log(msg: => AnyRef): Unit @@ -158,7 +162,7 @@ abstract class SymbolTable extends api.Universe try op finally popPhase(saved) } - + /** Since when it is to be "at" a phase is inherently ambiguous, * a couple unambiguously named methods. diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 04bdb0f4ad..fc94e96acd 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -45,10 +45,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => m } - /** Create a new free variable. Its owner is NoSymbol. + /** Create a new free term. Its owner is NoSymbol. */ - def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar = - new FreeVar(name, value) initFlags newFlags setInfo tpe + def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeTerm = + new FreeTerm(name, value, origin) initFlags newFlags setInfo info + + /** Create a new free type. Its owner is NoSymbol. + */ + def newFreeType(name: TypeName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeType = + new FreeType(name, value, origin) initFlags newFlags setInfo info /** The original owner of a class. Used by the backend to generate * EnclosingMethod attributes. @@ -58,6 +63,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol => + def kind: String = kindString + def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags) @@ -324,7 +331,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = { var cnt = 0 def freshName() = { cnt += 1; nme.syntheticParamName(cnt) } - mmap(argtypess)(tp => newValueParameter(freshName(), focusPos(owner.pos), SYNTHETIC) setInfo tp) + mmap(argtypess)(tp => newValueParameter(freshName(), owner.pos.focus, SYNTHETIC) setInfo tp) } def newSyntheticTypeParam(): Symbol = newSyntheticTypeParam("T0", 0L) @@ -543,6 +550,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isTypeParameter = false def isTypeParameterOrSkolem = false def isTypeSkolem = false + def isTypeMacro = false + def isFreeType = false /** Qualities of Terms, always false for TypeSymbols. */ @@ -563,13 +572,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isValueParameter = false def isVariable = false override def hasDefault = false + def isTermMacro = false + def isFreeTerm = false /** Qualities of MethodSymbols, always false for TypeSymbols * and other TermSymbols. */ def isCaseAccessorMethod = false def isLiftedMethod = false - def isMacro = false def isMethod = false def isSourceMethod = false def isVarargsMethod = false @@ -613,11 +623,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => @inline final override def hasFlag(mask: Long): Boolean = (flags & mask) != 0 /** Does symbol have ALL the flags in `mask` set? */ @inline final override def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask - + override def setFlag(mask: Long): this.type = { _rawflags |= mask ; this } override def resetFlag(mask: Long): this.type = { _rawflags &= ~mask ; this } override def resetFlags() { rawflags &= (TopLevelCreationFlags | alwaysHasFlags) } - + /** Default implementation calls the generic string function, which * will print overloaded flags as . Subclasses * of Symbol refine. @@ -632,7 +642,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => _rawflags = mask this } - + final def flags: Long = { val fs = _rawflags & phase.flagMask (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift) @@ -780,7 +790,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) final def isModuleVar = hasFlag(MODULEVAR) - /** Is this symbol static (i.e. with no outer instance)? */ + /** Is this symbol static (i.e. with no outer instance)? + * Q: When exactly is a sym marked as STATIC? + * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep. + * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6 + */ def isStatic = (this hasFlag STATIC) || owner.isStaticOwner /** Is this symbol a static constructor? */ @@ -865,6 +879,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isInitialized: Boolean = validTo != NoPeriod + // [Eugene] is this correct? + /** Determines whether this symbol can be loaded by subsequent reflective compilation */ + final def isLocatable: Boolean = { + if (this == NoSymbol) return false + if (isRoot || isRootPackage) return true + + if (!owner.isLocatable) return false + if (owner.isTerm) return false + + if (isType && isNonClassType) return false + return true + } + + // [Eugene] is it a good idea to add ``dealias'' to Symbol? + /** Expands type aliases */ + def dealias: Symbol = this + /** The variance of this symbol as an integer */ final def variance: Int = if (isCovariant) 1 @@ -1292,7 +1323,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * which immediately follows any of parser, namer, typer, or erasure. * In effect that means this will return one of: * - * - packageobjects (follows namer) + * - packageobjects (follows namer) * - superaccessors (follows typer) * - lazyvals (follows erasure) * - null @@ -1946,7 +1977,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Remove private modifier from symbol `sym`s definition. If `sym` is a * is not a constructor nor a static module rename it by expanding its name to avoid name clashes - * @param base the fully qualified name of this class will be appended if name expansion is needed + * @param base the fully qualified name of this class will be appended if name expansion is needed */ final def makeNotPrivate(base: Symbol) { if (this.isPrivate) { @@ -2032,8 +2063,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => private case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) private def symbolKind: SymbolKind = { - val kind = - if (isInstanceOf[FreeVar]) ("free variable", "free variable", "FV") + var kind = + if (isTermMacro) ("macro method", "macro method", "MAC") + else if (isInstanceOf[FreeTerm]) ("free term", "free term", "FTE") + else if (isInstanceOf[FreeType]) ("free type", "free type", "FTY") else if (isPackage) ("package", "package", "PK") else if (isPackageClass) ("package class", "package", "PKC") else if (isPackageObject) ("package object", "package", "PKO") @@ -2054,6 +2087,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (isSourceMethod) ("method", "method", "METH") else if (isTerm) ("value", "value", "VAL") else ("", "", "???") + if (isSkolem) kind = (kind._1, kind._2, kind._3 + "#SKO") SymbolKind(kind._1, kind._2, kind._3) } @@ -2216,8 +2250,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Term symbols with the exception of static parts of Java classes and packages. */ - override def isValue = !(isModule && hasFlag(PACKAGE | JAVA)) - override def isVariable = isMutable && !isMethod + override def isValue = !(isModule && hasFlag(PACKAGE | JAVA)) + override def isVariable = isMutable && !isMethod + override def isTermMacro = hasFlag(MACRO) // interesting only for lambda lift. Captured variables are accessed from inner lambdas. override def isCapturedVariable = hasAllFlags(MUTABLE | CAPTURED) && !hasFlag(METHOD) @@ -2406,7 +2441,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isMethod = true override def isLabel = this hasFlag LABEL - override def isMacro = this hasFlag MACRO override def isVarargsMethod = this hasFlag VARARGS override def isLiftedMethod = this hasFlag LIFTED @@ -2438,6 +2472,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => extends TypeSymbol(initOwner, initPos, initName) { type TypeOfClonedSymbol = TypeSymbol final override def isAliasType = true + final override def dealias = info.typeSymbol.dealias override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSymbol = owner.newNonClassSymbol(name, pos, newFlags) } @@ -2469,7 +2504,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => final override def isType = true override def isNonClassType = true - + override def isTypeMacro = hasFlag(MACRO) + override def resolveOverloadedFlag(flag: Long) = flag match { case TRAIT => "" // DEFAULTPARAM case EXISTENTIAL => "" // MIXEDIN @@ -2877,7 +2913,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => abort("Can't rename a package object to " + name) } } - + trait ImplClassSymbol extends ClassSymbol { override def sourceModule = companionModule // override def isImplClass = true @@ -2913,12 +2949,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) } - class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) { - override def hashCode = if (value == null) 0 else value.hashCode - override def equals(other: Any): Boolean = other match { - case that: FreeVar => this.value.asInstanceOf[AnyRef] eq that.value.asInstanceOf[AnyRef] - case _ => false - } + class FreeTerm(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) { + def value = value0 + override def isFreeTerm = true + } + + // [Eugene] the NoSymbol origin works for type parameters. what about existential free types? + class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) { + def value = value0 + override def isFreeType = true } /** An object representing a missing symbol */ @@ -3068,7 +3107,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def toString() = "TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")" - + def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) } } diff --git a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala new file mode 100644 index 0000000000..fbcd5043bc --- /dev/null +++ b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala @@ -0,0 +1,62 @@ +package scala.reflect +package internal + +trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable => + + // ``staticClass'' and ``staticModule'' rely on ClassLoaders + // which are implementation-specific for different Universes + + def staticClassIfDefined(fullName: String): Symbol = + try staticClass(fullName) + catch { case _: MissingRequirementError => NoSymbol } + + def staticModuleIfDefined(fullName: String): Symbol = + try staticModule(fullName) + catch { case _: MissingRequirementError => NoSymbol } + + def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType + + def selectType(owner: Symbol, name: String): Symbol = + owner.info.decl(newTypeName(name)) orElse { + MissingRequirementError.notFound("type %s in %s".format(name, owner.fullName)) + } + + def selectTypeIfDefined(owner: Symbol, name: String): Symbol = + try selectType(owner, name) + catch { case _: MissingRequirementError => NoSymbol } + +// try getModule(fullname.toTermName) +// catch { case _: MissingRequirementError => NoSymbol } + + def selectTerm(owner: Symbol, name: String): Symbol = { + val sym = owner.info.decl(newTermName(name)) + val result = + if (sym.isOverloaded) sym suchThat (!_.isMethod) + else sym + result orElse { + MissingRequirementError.notFound("term %s in %s".format(name, owner.fullName)) + } + } + + def selectTermIfDefined(owner: Symbol, name: String): Symbol = + try selectTerm(owner, name) + catch { case _: MissingRequirementError => NoSymbol } + + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol = + owner.info.decl(newTermName(name)).alternatives(index) orElse { + MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName)) + } + + def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol = + try selectOverloadedMethod(owner, name, index) + catch { case _: MissingRequirementError => NoSymbol } + + def newFreeTerm(name: String, info: Type, value: => Any, origin: String) = newFreeTerm(newTermName(name), info, value, origin) + + def newFreeType(name: String, info: Type, value: => Any, origin: String) = newFreeType(newTypeName(name), info, value, origin) + + def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers = + Modifiers(flags, privateWithin, annotations) + + val gen: TreeGen { val global: TreeBuildUtil.this.type } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala index 141ff12f8a..1a374b6e59 100644 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ b/src/compiler/scala/reflect/internal/TreeGen.scala @@ -1,7 +1,7 @@ package scala.reflect package internal -abstract class TreeGen { +abstract class TreeGen extends api.AbsTreeGen { val global: SymbolTable import global._ diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index ce3de94335..ed22cad730 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -531,4 +531,198 @@ abstract class TreeInfo { case _ => None } } + + // domain-specific extractors for reification + + import definitions._ + + object TypedOrAnnotated { + def unapply(tree: Tree): Option[Tree] = tree match { + case ty @ Typed(_, _) => + Some(ty) + case at @ Annotated(_, _) => + Some(at) + case _ => + None + } + } + + object TreeSplice { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(splicee, _) if tree.symbol == ExprEval || tree.symbol == ExprValue => + Some(splicee) + case _ => + None + } + } + + object EvalSplice { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(splicee, _) if tree.symbol == ExprEval => + Some(splicee) + case _ => + None + } + } + + object ValueSplice { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(splicee, _) if tree.symbol == ExprValue => + Some(splicee) + case _ => + None + } + } + + object Reified { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + case ReifiedTree(reifee, symbolTable, reified, _) => + Some(reifee, symbolTable, reified) + case ReifiedType(reifee, symbolTable, reified) => + Some(reifee, symbolTable, reified) + case _ => + None + } + } + + object ReifiedTree { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match { + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, List(tpe))))) if mrDef.name == nme.MIRROR_SHORT => + Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tree, tpe) + case _ => + None + } + } + + object InlineableTreeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree, Symbol)] = tree match { + case select @ Select(ReifiedTree(splicee, symbolTable, tree, tpe), _) if select.symbol == ExprEval || select.symbol == ExprValue => + Some(splicee, symbolTable, tree, tpe, select.symbol) + case _ => + None + } + } + + object InlinedTreeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match { + case Select(ReifiedTree(splicee, symbolTable, tree, tpe), name) if name == ExprTree.name => + Some(splicee, symbolTable, tree, tpe) + case _ => + None + } + } + + object ReifiedType { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, List(tpe))) if mrDef.name == nme.MIRROR_SHORT => + Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tpe) + case _ => + None + } + } + + object InlinedTypeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match { + case Select(ReifiedType(splicee, symbolTable, tpe), name) if name == TypeTagTpe.name => + Some(splicee, symbolTable, tpe) + case _ => + None + } + } + + object FreeDef { + def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { + case FreeTermDef(mrRef, name, binding, origin) => + Some(mrRef, name, binding, origin) + case FreeTypeDef(mrRef, name, binding, origin) => + Some(mrRef, name, binding, origin) + case _ => + None + } + } + + object FreeTermDef { + lazy val newFreeTermMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeTerm) + + def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(origin: String))))) + if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name => + Some(mrRef, name, binding, origin) + case _ => + None + } + } + + object FreeTypeDef { + lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType) + + def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match { + case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(origin: String))))) + if mrRef1.name == nme.MIRROR_SHORT && newFreeType == newFreeTypeMethod.name => + value match { + case Apply(TypeApply(Select(Select(mrRef2 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null)))) + if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag && apply == nme.apply => + Some(mrRef1, name, binding, origin) + case Apply(TypeApply(Select(mrRef2 @ Ident(_), typeTag), List(binding)), List(Literal(Constant(null)))) + if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag => + Some(mrRef1, name, binding, origin) + case _ => + throw new Error("unsupported free type def: " + showRaw(tree)) + } + case _ => + None + } + } + + object FreeRef { + def unapply(tree: Tree): Option[(Tree, TermName)] = tree match { + case Apply(Select(mrRef @ Ident(_), ident), List(Ident(name: TermName))) if ident == nme.Ident && name.startsWith(nme.MIRROR_FREE_PREFIX) => + Some(mrRef, name) + case _ => + None + } + } + + object TypeRefToFreeType { + def unapply(tree: Tree): Option[TermName] = tree match { + case Apply(Select(Select(mrRef @ Ident(_), typeRef), apply), List(Select(_, noSymbol), Ident(freeType: TermName), nil)) + if (mrRef.name == nme.MIRROR_SHORT && typeRef == nme.TypeRef && noSymbol == nme.NoSymbol && freeType.startsWith(nme.MIRROR_FREE_PREFIX)) => + Some(freeType) + case _ => + None + } + } + + object NestedExpr { + def unapply(tree: Tree): Option[(Tree, Tree, Tree)] = tree match { + case Apply(Apply(factory @ Select(expr, apply), List(tree)), List(typetag)) if expr.symbol == ExprModule && apply == nme.apply => + Some(factory, tree, typetag) + case _ => + None + } + } + + object BoundTerm { + def unapply(tree: Tree): Option[Tree] = tree match { + case Ident(name) if name.isTermName => + Some(tree) + case This(_) => + Some(tree) + case _ => + None + } + } + + object BoundType { + def unapply(tree: Tree): Option[Tree] = tree match { + case Select(_, name) if name.isTypeName => + Some(tree) + case SelectFromTypeTree(_, name) if name.isTypeName => + Some(tree) + case Ident(name) if name.isTypeName => + Some(tree) + case _ => + None + } + } } diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index 7a084304a8..9b4c18ce86 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -23,6 +23,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => else s } def quotedName(name: Name): String = quotedName(name, false) + def quotedName(name: String): String = quotedName(newTermName(name), false) private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = { val sym = tree.symbol @@ -31,7 +32,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => var suffix = "" if (settings.uniqid.value) suffix += ("#" + sym.id) if (settings.Yshowsymkinds.value) suffix += ("#" + sym.abbreviatedKindString) - prefix + tree.symbol.decodedName + suffix + prefix + quotedName(tree.symbol.decodedName) + suffix } else { quotedName(name, decoded) } @@ -64,7 +65,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable => def indent() = indentMargin += indentStep def undent() = indentMargin -= indentStep - def printPosition(tree: Tree) = if (doPrintPositions) print(showPos(tree.pos)) + def printPosition(tree: Tree) = if (doPrintPositions) print(tree.pos.show) def println() { out.println() diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index c0d6f54b1a..0d7e68aee3 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -184,7 +184,7 @@ trait Trees extends api.Trees { self: SymbolTable => def ValDef(sym: Symbol, rhs: Tree): ValDef = atPos(sym.pos) { ValDef(Modifiers(sym.flags), sym.name.toTermName, - TypeTree(sym.tpe) setPos focusPos(sym.pos), + TypeTree(sym.tpe) setPos sym.pos.focus, rhs) setSymbol sym } @@ -203,7 +203,7 @@ trait Trees extends api.Trees { self: SymbolTable => sym.name.toTermName, sym.typeParams map TypeDef, vparamss, - TypeTree(sym.tpe.finalResultType) setPos focusPos(sym.pos), + TypeTree(sym.tpe.finalResultType) setPos sym.pos.focus, rhs) setSymbol sym } @@ -235,7 +235,8 @@ trait Trees extends api.Trees { self: SymbolTable => } /** casedef shorthand */ - def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body) + def CaseDef(pat: Tree, body: Tree): CaseDef = + CaseDef(pat, EmptyTree, body) def Bind(sym: Symbol, body: Tree): Bind = Bind(sym.name, body) setSymbol sym @@ -249,10 +250,39 @@ trait Trees extends api.Trees { self: SymbolTable => def Apply(sym: Symbol, args: Tree*): Tree = Apply(Ident(sym), args.toList) + /** Factory method for object creation `new tpt(args_1)...(args_n)` + * A `New(t, as)` is expanded to: `(new t).(as)` + */ + def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { + case Nil => new ApplyConstructor(tpt, Nil) + case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply) + } + + /** 0-1 argument list new, based on a type. + */ + def New(tpe: Type, args: Tree*): Tree = + new ApplyConstructor(TypeTree(tpe), args.toList) + def New(sym: Symbol, args: Tree*): Tree = New(sym.tpe, args: _*) - def Super(sym: Symbol, mix: TypeName): Tree = Super(This(sym), mix) + def Super(sym: Symbol, mix: TypeName): Tree = + Super(This(sym), mix) + + def This(sym: Symbol): Tree = + This(sym.name.toTypeName) setSymbol sym + + def Select(qualifier: Tree, name: String): Select = + Select(qualifier, newTermName(name)) + + def Select(qualifier: Tree, sym: Symbol): Select = + Select(qualifier, sym.name) setSymbol sym + + def Ident(name: String): Ident = + Ident(newTermName(name)) + + def Ident(sym: Symbol): Ident = + Ident(sym.name) setSymbol sym /** Block factory that flattens directly nested blocks. */ @@ -266,6 +296,7 @@ trait Trees extends api.Trees { self: SymbolTable => } // --- specific traversers and transformers + // todo. move these into scala.reflect.api protected[scala] def duplicateTree(tree: Tree): Tree = duplicator transform tree @@ -273,44 +304,11 @@ trait Trees extends api.Trees { self: SymbolTable => override val treeCopy = newStrictTreeCopier override def transform(t: Tree) = { val t1 = super.transform(t) - if ((t1 ne t) && isRangePos(t1.pos)) t1 setPos focusPos(t.pos) + if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus t1 } } - trait PosAssigner extends Traverser { - var pos: Position - } - protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner - - protected class DefaultPosAssigner extends PosAssigner { - var pos: Position = _ - override def traverse(t: Tree) { - if (t eq EmptyTree) () - else if (t.pos == NoPosition) { - t.setPos(pos) - super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if? - // @PP: it's pruning whenever it encounters a node with a - // position, which I interpret to mean that (in the author's - // mind at least) either the children of a positioned node will - // already be positioned, or the children of a positioned node - // do not merit positioning. - // - // Whatever the author's rationale, it does seem like a bad idea - // to press on through a positioned node to find unpositioned - // children beneath it and then to assign whatever happens to - // be in `pos` to such nodes. There are supposed to be some - // position invariants which I can't imagine surviving that. - } - } - } - - def atPos[T <: Tree](pos: Position)(tree: T): T = { - posAssigner.pos = pos - posAssigner.traverse(tree) - tree - } - class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser { override def traverse(tree: Tree) { val t = if (pf isDefinedAt tree) pf(tree) else tree @@ -363,7 +361,7 @@ trait Trees extends api.Trees { self: SymbolTable => override def toString = substituterString("Symbol", "Tree", from, to) } - /** Substitute clazz.this with `to`. `to` must be an attributed tree. + /** Substitute clazz.this with `to`. `to` must be an attributed tree. */ class ThisSubstituter(clazz: Symbol, to: => Tree) extends Transformer { val newtpe = to.tpe @@ -430,4 +428,3 @@ trait Trees extends api.Trees { self: SymbolTable => override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to) } } - diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 575d84eab4..73a8f5c55c 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -254,7 +254,9 @@ trait Types extends api.Types { self: SymbolTable => case object UnmappableTree extends TermTree { override def toString = "" super.tpe_=(NoType) - override def tpe_=(t: Type) = if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for ") + override def tpe_=(t: Type) = if (t != NoType) { + throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for ") + } } abstract class AbsTypeImpl extends AbsType { this: Type => @@ -262,7 +264,7 @@ trait Types extends api.Types { self: SymbolTable => def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name) def declarations = decls def typeArguments = typeArgs - def erasedType = transformedType(this) + def erasure = transformedType(this) def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to) } @@ -723,6 +725,9 @@ trait Types extends api.Types { self: SymbolTable => /** Apply `f` to each part of this type */ def foreach(f: Type => Unit) { new ForEachTypeTraverser(f).traverse(this) } + /** Apply `pf' to each part of this type on which the function is defined */ + def collect[T](pf: PartialFunction[Type, T]): List[T] = new CollectTypeCollector(pf).collect(this) + /** Apply `f` to each part of this type; children get mapped before their parents */ def map(f: Type => Type): Type = new TypeMap { def apply(x: Type) = f(mapOver(x)) @@ -1194,6 +1199,8 @@ trait Types extends api.Types { self: SymbolTable => override def kind = "BoundedWildcardType" } + object BoundedWildcardType extends BoundedWildcardTypeExtractor + /** An object representing a non-existing type */ case object NoType extends Type { override def isTrivial: Boolean = true @@ -1822,7 +1829,35 @@ trait Types extends api.Types { self: SymbolTable => object ConstantType extends ConstantTypeExtractor { def apply(value: Constant): ConstantType = { - unique(new UniqueConstantType(value)).asInstanceOf[ConstantType] + val tpe = new UniqueConstantType(value) + if (value.tag == ClazzTag) { + // if we carry a classOf, we might be in trouble + // http://groups.google.com/group/scala-internals/browse_thread/thread/45185b341aeb6a30 + // I don't have time for a thorough fix, so I put a hacky workaround here + val alreadyThere = uniques findEntry tpe + if ((alreadyThere ne null) && (alreadyThere ne tpe) && (alreadyThere.toString != tpe.toString)) { + // we need to remove a stale type that has the same hashcode as we do + // HashSet doesn't support removal, and this makes our task non-trivial + // also we cannot simply recreate it, because that'd skew hashcodes (that change over time, omg!) + // the only solution I can see is getting into the underlying array and sneakily manipulating it + val ftable = uniques.getClass.getDeclaredFields().find(f => f.getName endsWith "table").get + ftable.setAccessible(true) + val table = ftable.get(uniques).asInstanceOf[Array[AnyRef]] + def overwrite(hc: Int, x: Type) { + def index(x: Int): Int = math.abs(x % table.length) + var h = index(hc) + var entry = table(h) + while (entry ne null) { + if (x == entry) + table(h) = x + h = index(h + 1) + entry = table(h) + } + } + overwrite(tpe.##, tpe) + } + } + unique(tpe).asInstanceOf[ConstantType] } } @@ -3751,6 +3786,8 @@ trait Types extends api.Types { self: SymbolTable => } } + // todo. move these into scala.reflect.api + /** A prototype for mapping a function over all possible types */ abstract class TypeMap extends (Type => Type) { @@ -4563,6 +4600,16 @@ trait Types extends api.Types { self: SymbolTable => } } + /** A map to implement the `collect` method. */ + class CollectTypeCollector[T](pf: PartialFunction[Type, T]) extends TypeCollector[List[T]](Nil) { + override def collect(tp: Type) = super.collect(tp).reverse + + def traverse(tp: Type) { + if (pf.isDefinedAt(tp)) result ::= pf(tp) + mapOver(tp) + } + } + class ForEachTypeTraverser(f: Type => Unit) extends TypeTraverser { def traverse(tp: Type) { f(tp) diff --git a/src/compiler/scala/reflect/makro/runtime/Aliases.scala b/src/compiler/scala/reflect/makro/runtime/Aliases.scala new file mode 100644 index 0000000000..a4f208ca34 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Aliases.scala @@ -0,0 +1,21 @@ +package scala.reflect.makro +package runtime + +trait Aliases { + self: Context => + + /** Aliases of mirror types */ + override type Symbol = mirror.Symbol + override type Type = mirror.Type + override type Name = mirror.Name + override type Tree = mirror.Tree + override type Position = mirror.Position + override type Scope = mirror.Scope + override type Modifiers = mirror.Modifiers + override type Expr[+T] = mirror.Expr[T] + override type TypeTag[T] = mirror.TypeTag[T] + + /** Creator/extractor objects for Expr and TypeTag values */ + override val TypeTag = mirror.TypeTag + override val Expr = mirror.Expr +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala new file mode 100644 index 0000000000..4e93d4e06d --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala @@ -0,0 +1,14 @@ +package scala.reflect.makro +package runtime + +trait CapturedVariables { + self: Context => + + import mirror._ + + def captureVariable(vble: Symbol): Unit = mirror.captureVariable(vble) + + def referenceCapturedVariable(vble: Symbol): Tree = mirror.referenceCapturedVariable(vble) + + def capturedVariableType(vble: Symbol): Type = mirror.capturedVariableType(vble) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala new file mode 100644 index 0000000000..184008658e --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Context.scala @@ -0,0 +1,26 @@ +package scala.reflect.makro +package runtime + +import scala.tools.nsc.Global + +abstract class Context extends scala.reflect.makro.Context + with Aliases + with CapturedVariables + with Infrastructure + with Enclosures + with Names + with Reifiers + with Reporters + with Settings + with Symbols + with Typers + with Util { + + val mirror: Global + + val callsiteTyper: mirror.analyzer.Typer + + val prefix: Expr[PrefixType] + + val expandee: Tree +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala new file mode 100644 index 0000000000..f9a6987e48 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala @@ -0,0 +1,36 @@ +package scala.reflect.makro +package runtime + +trait Enclosures { + self: Context => + + import mirror._ + + // vals are eager to simplify debugging + // after all we wouldn't save that much time by making them lazy + + val macroApplication: Tree = expandee + + val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros + + val enclosingImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits + + val enclosingPosition: Position = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition) + + val enclosingApplication: Tree = { + def loop(context: analyzer.Context): Tree = context match { + case analyzer.NoContext => EmptyTree + case context if context.tree.isInstanceOf[Apply] => context.tree + case context => loop(context.outer) + } + + val context = callsiteTyper.context + loop(context) + } + + val enclosingMethod: Tree = callsiteTyper.context.enclMethod.tree + + val enclosingClass: Tree = callsiteTyper.context.enclClass.tree + + val enclosingUnit: CompilationUnit = currentRun.currentUnit +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Errors.scala b/src/compiler/scala/reflect/makro/runtime/Errors.scala new file mode 100644 index 0000000000..d78eae9237 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Errors.scala @@ -0,0 +1,6 @@ +package scala.reflect.makro +package runtime + +import scala.reflect.api.Position + +class AbortMacroException(val pos: Position, val msg: String) extends Throwable(msg) diff --git a/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala new file mode 100644 index 0000000000..6d8e55cc35 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala @@ -0,0 +1,34 @@ +package scala.reflect.makro +package runtime + +trait Infrastructure { + self: Context => + + val forJVM: Boolean = mirror.forJVM + + val forMSIL: Boolean = mirror.forMSIL + + val forInteractive: Boolean = mirror.forInteractive + + val forScaladoc: Boolean = mirror.forScaladoc + + val currentRun: Run = mirror.currentRun + + type Run = mirror.Run + + object Run extends RunExtractor { + def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] = Some(run.currentUnit, run.units.toList) + } + + type CompilationUnit = mirror.CompilationUnit + + object CompilationUnit extends CompilationUnitExtractor { + def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] = Some(compilationUnit.source.file.file, compilationUnit.source.content, compilationUnit.body) + } + + val currentMacro: Symbol = expandee.symbol + + val globalCache: collection.mutable.Map[Any, Any] = mirror.analyzer.globalMacroCache + + val cache: collection.mutable.Map[Any, Any] = mirror.analyzer.perRunMacroCache.getOrElseUpdate(currentMacro, collection.mutable.Map[Any, Any]()) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Names.scala b/src/compiler/scala/reflect/makro/runtime/Names.scala new file mode 100644 index 0000000000..d8ecc2b89e --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Names.scala @@ -0,0 +1,20 @@ +package scala.reflect.makro +package runtime + +trait Names { + self: Context => + + lazy val freshNameCreator = callsiteTyper.context.unit.fresh + + def fresh(): String = { + freshNameCreator.newName() + } + + def fresh(name: String): String = { + freshNameCreator.newName(name) + } + + def fresh(name: Name): Name = { + name.mapName(freshNameCreator.newName(_)) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala new file mode 100644 index 0000000000..826fa7153f --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -0,0 +1,69 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Gilles Dubochet + */ + +package scala.reflect.makro +package runtime + +trait Reifiers { + self: Context => + + import mirror._ + + lazy val reflectMirrorPrefix: Tree = { + // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? + val prefix: Tree = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror")) + val prefixTpe = typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe + typeCheck(prefix) setType prefixTpe + } + + def reifyTree(prefix: Tree, tree: Tree): Tree = + reifyTopLevel(prefix, tree) + + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, noTypeVariablesInResult: Boolean = false): Tree = + reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, noTypeVariablesInResult) + + def unreifyTree(tree: Tree): Tree = + Select(tree, definitions.ExprEval) + + def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree = { + // [Eugene] the plumbing is not very pretty, but anyways factoring out the reifier seems like a necessary step to me + import scala.reflect.reify._ + val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireGroundTypeTag) + + try { + val result = reifier.reified + logFreeVars(expandee.pos, result) + result + } catch { + case ex: reifier.ReificationError => +// // this is a "soft" exception - it will normally be caught by the macro +// // consequently, we need to log the stack trace here, so that it doesn't get lost +// if (settings.Yreifydebug.value) { +// val message = new java.io.StringWriter() +// ex.printStackTrace(new java.io.PrintWriter(message)) +// println(scala.compat.Platform.EOL + message) +// } + val xlated = new ReificationError(ex.pos, ex.msg) + xlated.setStackTrace(ex.getStackTrace) + throw xlated + case ex: reifier.UnexpectedReificationError => + val xlated = new UnexpectedReificationError(ex.pos, ex.msg, ex.cause) + xlated.setStackTrace(ex.getStackTrace) + throw xlated + } + } + + class ReificationError(var pos: Position, val msg: String) extends Throwable(msg) + + object ReificationError extends ReificationErrorExtractor { + def unapply(error: ReificationError): Option[(Position, String)] = Some((error.pos, error.msg)) + } + + class UnexpectedReificationError(val pos: Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) + + object UnexpectedReificationError extends UnexpectedReificationErrorExtractor { + def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] = Some((error.pos, error.msg, error.cause)) + } +} diff --git a/src/compiler/scala/reflect/makro/runtime/Reporters.scala b/src/compiler/scala/reflect/makro/runtime/Reporters.scala new file mode 100644 index 0000000000..0fd037bdd2 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Reporters.scala @@ -0,0 +1,44 @@ +package scala.reflect.makro +package runtime + +trait Reporters { + self: Context => + + import mirror._ + + def reporter: mirror.Reporter = wrapNscReporter(mirror.reporter) + + def setReporter(reporter: mirror.Reporter): this.type = { + mirror.reporter = wrapApiReporter(reporter) + this + } + + def withReporter[T](reporter: Reporter)(op: => T): T = { + val old = mirror.reporter + setReporter(reporter) + try op + finally mirror.reporter = old + } + + def echo(pos: Position, msg: String): Unit = mirror.reporter.echo(pos, msg) + + def info(pos: Position, msg: String, force: Boolean): Unit = mirror.reporter.info(pos, msg, force) + + def hasWarnings: Boolean = mirror.reporter.hasErrors + + def hasErrors: Boolean = mirror.reporter.hasErrors + + def warning(pos: Position, msg: String): Unit = callsiteTyper.context.warning(pos, msg) + + def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg) + + def abort(pos: Position, msg: String): Nothing = { + callsiteTyper.context.error(pos, msg) + throw new AbortMacroException(pos, msg) + } + + def interactive(): Unit = mirror.reporter match { + case reporter: tools.nsc.reporters.AbstractReporter => reporter.displayPrompt() + case _ => () + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Settings.scala b/src/compiler/scala/reflect/makro/runtime/Settings.scala new file mode 100644 index 0000000000..32f7115db8 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Settings.scala @@ -0,0 +1,36 @@ +package scala.reflect.makro +package runtime + +trait Settings { + self: Context => + + def settings: List[String] = { + val optionName = mirror.settings.XmacroSettings.name + val settings = compilerSettings.find(opt => opt.startsWith(optionName)).map(opt => opt.substring(optionName.length + 1)).getOrElse("") + settings.split(",").toList + } + + def compilerSettings: List[String] = mirror.settings.recreateArgs + + def setCompilerSettings(options: String): this.type = + // todo. is not going to work with quoted arguments with embedded whitespaces + setCompilerSettings(options.split(" ").toList) + + def setCompilerSettings(options: List[String]): this.type = { + val settings = new tools.nsc.Settings(_ => ()) + // [Eugene] what settings should we exclude? + settings.copyInto(mirror.settings) + this + } + + def withCompilerSettings[T](options: String)(op: => T): T = + // todo. is not going to work with quoted arguments with embedded whitespaces + withCompilerSettings(options.split(" ").toList)(op) + + def withCompilerSettings[T](options: List[String])(op: => T): T = { + val old = options + setCompilerSettings(options) + try op + finally setCompilerSettings(old) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Symbols.scala b/src/compiler/scala/reflect/makro/runtime/Symbols.scala new file mode 100644 index 0000000000..552ad2a303 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Symbols.scala @@ -0,0 +1,8 @@ +package scala.reflect.makro +package runtime + +trait Symbols { + self: Context => + + def isLocatable(sym: Symbol) = sym.isLocatable +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala new file mode 100644 index 0000000000..38e819746d --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -0,0 +1,78 @@ +package scala.reflect.makro +package runtime + +trait Typers { + self: Context => + + val openMacros: List[Context] = this :: mirror.analyzer.openMacros + + val openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits + + def typeCheck(tree: Tree, pt: Type = mirror.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) + trace("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled)) + val wrapper1 = if (!withImplicitViewsDisabled) (callsiteTyper.context.withImplicitsEnabled[Tree] _) else (callsiteTyper.context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[Tree] _) else (callsiteTyper.context.withMacrosDisabled[Tree] _) + def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) + // if you get a "silent mode is not available past typer" here + // don't rush to change the typecheck not to use the silent method when the silent parameter is false + // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time + // I'd advise fixing the root cause: finding why the context is not set to report errors + // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) + wrapper(callsiteTyper.silent(_.typed(tree, mirror.analyzer.EXPRmode, pt)) match { + case mirror.analyzer.SilentResultValue(result) => + trace(result) + result + case error @ mirror.analyzer.SilentTypeError(_) => + trace(error.err.errMsg) + if (!silent) throw new mirror.TypeError(error.err.errPos, error.err.errMsg) + mirror.EmptyTree + }) + } + + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { + def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) + trace("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) + import mirror.analyzer.SearchResult + val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _) + def wrapper (inference: => SearchResult) = wrapper1(inference) + val context = callsiteTyper.context.makeImplicit(true) + wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match { + case failure if failure.tree.isEmpty => + trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") + if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) + mirror.EmptyTree + case success => + success.tree + } + } + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree = { + def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) + trace("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) + import mirror.analyzer.SearchResult + val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _) + def wrapper (inference: => SearchResult) = wrapper1(inference) + val fun1 = mirror.definitions.FunctionClass(1) + val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to)) + val context = callsiteTyper.context.makeImplicit(reportAmbiguous) + wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { + case failure if failure.tree.isEmpty => + trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") + if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) + mirror.EmptyTree + case success => + success.tree + } + } + + type TypeError = mirror.TypeError + + object TypeError extends TypeErrorExtractor { + def unapply(error: TypeError): Option[(Position, String)] = Some((error.pos, error.msg)) + } + + def resetAllAttrs[T <: Tree](tree: T): T = mirror.resetAllAttrs(tree) + + def resetLocalAttrs[T <: Tree](tree: T): T = mirror.resetLocalAttrs(tree) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/makro/runtime/Util.scala b/src/compiler/scala/reflect/makro/runtime/Util.scala new file mode 100644 index 0000000000..2671155721 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Util.scala @@ -0,0 +1,34 @@ +package scala.reflect.makro +package runtime + +trait Util { + self: Context => + + import mirror._ + + def literalNull = Expr[Null](Literal(Constant(null)))(TypeTag.Null) + + def literalUnit = Expr[Unit](Literal(Constant(())))(TypeTag.Unit) + + def literalTrue = Expr[Boolean](Literal(Constant(true)))(TypeTag.Boolean) + + def literalFalse = Expr[Boolean](Literal(Constant(false)))(TypeTag.Boolean) + + def literal(x: Boolean) = Expr[Boolean](Literal(Constant(x)))(TypeTag.Boolean) + + def literal(x: Byte) = Expr[Byte](Literal(Constant(x)))(TypeTag.Byte) + + def literal(x: Short) = Expr[Short](Literal(Constant(x)))(TypeTag.Short) + + def literal(x: Int) = Expr[Int](Literal(Constant(x)))(TypeTag.Int) + + def literal(x: Long) = Expr[Long](Literal(Constant(x)))(TypeTag.Long) + + def literal(x: Float) = Expr[Float](Literal(Constant(x)))(TypeTag.Float) + + def literal(x: Double) = Expr[Double](Literal(Constant(x)))(TypeTag.Double) + + def literal(x: String) = Expr[String](Literal(Constant(x)))(TypeTag.String) + + def literal(x: Char) = Expr[Char](Literal(Constant(x)))(TypeTag.Char) +} diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala new file mode 100644 index 0000000000..8bfe64621b --- /dev/null +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -0,0 +1,63 @@ +package scala.reflect +package reify + +import scala.tools.nsc.Global + +trait Errors { + self: Reifier => + + import mirror._ + import definitions._ + + class ReificationError(var pos: Position, val msg: String) extends Throwable(msg) + class UnexpectedReificationError(val pos: Position, val msg: String, val cause: Throwable = null) extends Throwable(msg) + + lazy val defaultErrorPosition: Position = + mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition) + + // expected errors: these can happen if the user casually writes whatever.reify(...) + // hence we don't crash here, but nicely report a typechecking error and bail out asap + + def CannotReifyReifeeThatHasTypeLocalToReifee(tree: Tree) = { + val msg = "implementation restriction: cannot reify block of type %s that involves a type declared inside the block being reified. consider casting the return value to a suitable type".format(tree.tpe) + throw new ReificationError(tree.pos, msg) + } + + def CannotReifyType(tpe: Type) = { + val msg = "implementation restriction: cannot reify type %s (%s)".format(tpe, tpe.kind) + throw new ReificationError(defaultErrorPosition, msg) + } + + def CannotReifySymbol(sym: Symbol) = { + val msg = "implementation restriction: cannot reify symbol %s (%s)".format(sym, sym.accurateKindString) + throw new ReificationError(defaultErrorPosition, msg) + } + + def CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe: Type) = { + val msg = "cannot reify GroundTypeTag having unresolved type parameter %s".format(tpe) + throw new ReificationError(defaultErrorPosition, msg) + } + + // unexpected errors: these can never happen under normal conditions unless there's a bug in the compiler (or in a compiler plugin or in a macro) + // hence, we fail fast and loudly and don't care about being nice - in this situation noone will appreciate our quiet nicety + + def CannotReifyUntypedPrefix(prefix: Tree) = { + val msg = "internal error: untyped prefixes are not supported, consider typechecking the prefix before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } + + def CannotReifyUntypedReifee(reifee: Any) = { + val msg = "internal error: untyped trees are not supported, consider typechecking the reifee before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } + + def CannotReifyErroneousPrefix(prefix: Tree) = { + val msg = "internal error: erroneous prefixes are not supported, make sure that your prefix has typechecked successfully before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } + + def CannotReifyErroneousReifee(reifee: Any) = { + val msg = "internal error: erroneous reifees are not supported, make sure that your reifee has typechecked successfully before passing it to the reifier" + throw new UnexpectedReificationError(defaultErrorPosition, msg) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/NodePrinters.scala b/src/compiler/scala/reflect/reify/NodePrinters.scala new file mode 100644 index 0000000000..eaca9a4968 --- /dev/null +++ b/src/compiler/scala/reflect/reify/NodePrinters.scala @@ -0,0 +1,111 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package reify + +import scala.Array.canBuildFrom +import scala.compat.Platform.EOL +import scala.tools.nsc.symtab.Flags +import scala.tools.nsc.Global + +trait NodePrinters { self: scala.tools.nsc.ast.NodePrinters => + + val global: Global + import global._ + + object reifiedNodeToString extends Function2[Tree, Tree, String] { + def apply(prefix: Tree, tree: Tree): String = { + import scala.reflect.api.Modifier + var modifierIsUsed = false + var flagsAreUsed = false + + // @PP: I fervently hope this is a test case or something, not anything being + // depended upon. Of more fragile code I cannot conceive. + // @Eugene: This stuff is only needed to debug-print out reifications in human-readable format + // Rolling a full-fledged, robust TreePrinter would be several times more code. + val (List(mirror), reified) = (for (line <- (tree.toString.split(EOL).toList drop 1 dropRight 1)) yield { + var s = line.trim + s = s.replace("$mr.", "") + s = s.replace(".apply", "") + s = s.replace("scala.collection.immutable.", "") + s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") + s = "List\\[.*?\\]".r.replaceAllIn(s, "List") + s = s.replace("immutable.this.Nil", "List()") + s = s.replace("modifiersFromInternalFlags", "Modifiers") + s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()") + s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => { + val buf = new collection.mutable.ListBuffer[String] + + val annotations = m.group(3) + if (buf.nonEmpty || annotations.nonEmpty) + buf.append("List(" + annotations + ")") + + val privateWithin = "" + m.group(2) + if (buf.nonEmpty || privateWithin != "") + buf.append("newTypeName(\"" + privateWithin + "\")") + + val flags = m.group(1).toLong + val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", " + if (buf.nonEmpty || s_flags != "") { + modifierIsUsed = true + buf.append("Set(" + s_flags + ")") + } + + "Modifiers(" + buf.reverse.mkString(", ") + ")" + }) + s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => { + flagsAreUsed = true + val flags = m.group(1).toLong + val mods = Flags.modifiersOfFlags(flags) map (_.sourceString) + "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))" + }) + + s + }) splitAt 1 + + val printout = collection.mutable.ListBuffer(mirror); + printout += "import " + nme.MIRROR_SHORT + "._" + if (modifierIsUsed) printout += "import scala.reflect.api.Modifier._" + if (flagsAreUsed) printout += "import scala.reflect.internal.Flags._" + val body = reified dropWhile (_.startsWith("val")) + if (body.length > 0 && body(0).startsWith("Expr[")) { + if (reified(0) startsWith "val") { + printout += "val code = {" + printout ++= (reified map (" " + _)) + printout += "}" + printout += "mkToolBox().runExpr(code)" + } else { + printout += "val code = " + reified(0) + printout ++= reified drop 1 + printout += "mkToolBox().runExpr(code)" + } + try { + val prefix = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror")) + val tree1 = new global.Transformer { + override def transform(tree: Tree) = super.transform(tree match { + case Block(ValDef(_, mr, _, _) :: Nil, expr) if mr == nme.MIRROR_SHORT => transform(expr) + case Block(ValDef(_, mr, _, _) :: symbolTable, expr) if mr == nme.MIRROR_SHORT => transform(Block(symbolTable, expr)) + case Select(Ident(mr), name) if mr == nme.MIRROR_SHORT => Select(prefix, name) + case tree => tree + }) + }.transform(tree) + val stringified = mkToolBox().runExpr(tree1).toString + if (settings.Yreifydebug.value) printout += "*****************************" + printout += stringified + } catch { + case ex: Throwable => +// val realex = ReflectionUtils.unwrapThrowable(ex) +// val message = new java.io.StringWriter() +// realex.printStackTrace(new java.io.PrintWriter(message)) +// println(message) + } + } else { + printout ++= reified + } + printout mkString EOL + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Phases.scala b/src/compiler/scala/reflect/reify/Phases.scala new file mode 100644 index 0000000000..49d5a45e8e --- /dev/null +++ b/src/compiler/scala/reflect/reify/Phases.scala @@ -0,0 +1,42 @@ +package scala.reflect +package reify + +import scala.reflect.reify.phases._ + +trait Phases extends Calculate + with Reshape + with Metalevels + with Reify { + + self: Reifier => + + import mirror._ + import definitions._ + + private var alreadyRun = false + + lazy val mkReificationPipeline: Tree => Tree = tree0 => { + assert(!alreadyRun, "reifier instance cannot be used more than once") + alreadyRun = true + + var tree = tree0 + + if (reifyDebug) println("[calculate phase]") + calculate.traverse(tree) + + if (reifyDebug) println("[reshape phase]") + tree = reshape.transform(tree) + + if (reifyDebug) println("[metalevels phase]") + tree = metalevels.transform(tree) + + if (reifyDebug) println("[interlude]") + if (reifyDebug) println("symbol table = " + (if (symbolTable.length == 0) "" else "")) + if (reifyDebug) symbolTable foreach (println(_)) + if (reifyDebug) println("reifee = " + (if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString)) + if (reifyDebug) println("[reify phase]") + var result = reify(tree) + + result + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Reifiers.scala b/src/compiler/scala/reflect/reify/Reifiers.scala new file mode 100644 index 0000000000..6854710949 --- /dev/null +++ b/src/compiler/scala/reflect/reify/Reifiers.scala @@ -0,0 +1,154 @@ +package scala.reflect +package reify + +import scala.tools.nsc.Global + +/** Given a tree or a type, generate a tree that when executed at runtime produces the original tree or type. + * See more info in the comments to ``reify'' in scala.reflect.api.Universe. + * + * @author Martin Odersky + * @version 2.10 + */ +abstract class Reifier extends Phases + with Errors { + + val mirror: Global + import mirror._ + import definitions._ + import treeInfo._ + + val typer: mirror.analyzer.Typer + val prefix: Tree + val reifee: Any + val dontSpliceAtTopLevel: Boolean + val requireGroundTypeTag: Boolean + + /** + * For ``reifee'' and other reification parameters, generate a tree of the form + * + * { + * val $mr = <[ prefix ]> + * $mr.Expr[T](rtree) // if data is a Tree + * $mr.TypeTag[T](rtree) // if data is a Type + * } + * + * where + * + * - `prefix` is the tree that represents the universe + * the result will be bound to + * - `rtree` is code that generates `reifee` at runtime. + * - `T` is the type that corresponds to `data`. + * + * This is not a method, but a value to indicate the fact that Reifier instances are a one-off. + */ + lazy val reified: Tree = { + try { + // [Eugene] conventional way of doing this? + if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix) + if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix) + + val rtree = reifee match { + case tree: Tree => + reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) + reifyTrace("reifee is located at: ")(tree.pos) + reifyTrace("prefix = ")(prefix) + // [Eugene] conventional way of doing this? + if (tree exists (_.isErroneous)) CannotReifyErroneousReifee(prefix) + if (tree.tpe == null) CannotReifyUntypedReifee(tree) + val pipeline = mkReificationPipeline + val rtree = pipeline(tree) + + // consider the following code snippet + // + // val x = reify { class C; new C } + // + // inferred type for x will be C + // but C ceases to exist after reification so this type is clearly incorrect + // however, reify is "just" a library function, so it cannot affect type inference + // + // hence we crash here even though the reification itself goes well + // fortunately, all that it takes to fix the error is to cast "new C" to Object + // so I'm not very much worried about introducing this restriction + if (tree.tpe exists (sub => sub.typeSymbol.isLocalToReifee)) + CannotReifyReifeeThatHasTypeLocalToReifee(tree) + + val manifestedType = typer.packedType(tree, NoSymbol) + val manifestedRtype = reifyType(manifestedType) + val tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) + Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype)))) + + case tpe: Type => + reifyTrace("reifying = ")(tpe.toString) + reifyTrace("prefix = ")(prefix) + val rtree = reify(tpe) + + val manifestedType = tpe + var tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) + Apply(ctor, List(rtree)) + + case _ => + throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString)) + } + + val mirrorAlias = ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(prefix), prefix) + val wrapped = Block(mirrorAlias :: symbolTable, rtree) + + // todo. why do we resetAllAttrs? + // + // typically we do some preprocessing before reification and + // the code emitted/moved around during preprocessing is very hard to typecheck, so we leave it as it is + // however this "as it is" sometimes doesn't make any sense + // + // ===example 1=== + // we move a freevar from a nested symbol table to a top-level symbol table, + // and then the reference to mr$ becomes screwed up, because nested symbol tables are already typechecked, + // so we have an mr$ symbol that points to the nested mr$ rather than to the top-level one. + // + // ===example 2=== + // we inline a freevar by replacing a reference to it, e.g. $mr.Apply($mr.Select($mr.Ident($mr.newTermName("$mr")), $mr.newTermName("Ident")), List($mr.Ident($mr.newTermName("free$x")))) + // with its original binding (e.g. $mr.Ident("x")) + // we'd love to typecheck the result, but we cannot do this easily, because $mr is external to this tree + // what's even worse, sometimes $mr can point to the top-level symbol table's $mr, which doesn't have any symbol/type yet - + // it's just a ValDef that will be emitted only after the reification is completed + // + // hence, the simplest solution is to erase all attrs so that invalid (as well as non-existent) bindings get rebound correctly + // this is ugly, but it's the best we can do + // + // todo. this is a common problem with non-trivial macros in our current macro system + // needs to be solved some day + // + // list of non-hygienic transformations: + // 1) local freetype inlining in Nested + // 2) external freevar moving in Nested + // 3) local freeterm inlining in Metalevels + // 4) trivial tree splice inlining in Reify (Trees.scala) + // 5) trivial type splice inlining in Reify (Types.scala) + val freevarBindings = symbolTable collect { case freedef @ FreeDef(_, _, binding, _) => binding.symbol } toSet + val untyped = resetAllAttrs(wrapped, leaveAlone = { + case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true + case tree if freevarBindings contains tree.symbol => true + case _ => false + }) + + if (reifyCopypaste) { + if (reifyDebug) println("=============================") + println(reifiedNodeToString(prefix, untyped)) + if (reifyDebug) println("=============================") + } else { + reifyTrace("reified = ")(untyped) + } + + untyped + } catch { + case ex: ReificationError => + throw ex + case ex: UnexpectedReificationError => + throw ex + case ex: Throwable => + throw new UnexpectedReificationError(defaultErrorPosition, "reification crashed", ex) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Names.scala b/src/compiler/scala/reflect/reify/codegen/Names.scala new file mode 100644 index 0000000000..589f6355d0 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Names.scala @@ -0,0 +1,15 @@ +package scala.reflect.reify +package codegen + +trait Names { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + def reifyName(name: Name) = { + val factory = if (name.isTypeName) nme.nmeNewTypeName else nme.nmeNewTermName + mirrorCall(factory, Literal(Constant(name.toString))) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Positions.scala b/src/compiler/scala/reflect/reify/codegen/Positions.scala new file mode 100644 index 0000000000..ac9195ef31 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Positions.scala @@ -0,0 +1,18 @@ +package scala.reflect.reify +package codegen + +trait Positions { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + // we do not reify positions because this inflates resulting trees, but doesn't buy as anything + // where would one use positions? right, in error messages + // but I can hardly imagine when one would need a position that points to the reified code + // usually reified trees are used to compose macro expansions or to be fed to the runtime compiler + // however both macros and toolboxes have their own means to report errors in synthetic trees + def reifyPosition(pos: Position): Tree = + reifyMirrorObject(NoPosition) +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala new file mode 100644 index 0000000000..3328f5e402 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -0,0 +1,111 @@ +package scala.reflect.reify +package codegen + +trait Symbols { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** Reify a reference to a symbol */ + def reifySymRef(sym0: Symbol): Tree = { + assert(sym0 != null, "sym is null") + val sym = sym0.dealias + + if (sym == NoSymbol) + mirrorSelect(nme.NoSymbol) + else if (sym == RootPackage) + Select(mirrorSelect(nme.definitions), nme.RootPackage) + else if (sym == RootClass) + Select(mirrorSelect(nme.definitions), nme.RootClass) + else if (sym == EmptyPackage) + Select(mirrorSelect(nme.definitions), nme.EmptyPackage) + else if (sym == EmptyPackageClass) + Select(mirrorSelect(nme.definitions), nme.EmptyPackageClass) + else if (sym.isModuleClass) + Select(reify(sym.sourceModule), nme.moduleClass) + else if (sym.isLocatable) { + // [Eugene] am I doing this right? +// if (sym.isStaticOwner) { // no good for us, because it returns false for packages + if (sym.isStatic && (sym.isClass || sym.isModule)) { + val resolver = if (sym.isType) nme.staticClass else nme.staticModule + mirrorCall(resolver, reify(sym.fullName)) + } else { + if (reifyDebug) println("Locatable: %s (%s) owned by %s (%s) at %s".format(sym, sym.accurateKindString, sym.owner, sym.owner.accurateKindString, sym.owner.fullNameString)) + val rowner = reify(sym.owner) + val rname = reify(sym.name.toString) + if (sym.isType) + mirrorCall(nme.selectType, rowner, rname) + else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) { + val index = sym.owner.info.decl(sym.name).alternatives indexOf sym + assert(index >= 0, sym) + mirrorCall(nme.selectOverloadedMethod, rowner, rname, reify(index)) + } else + mirrorCall(nme.selectTerm, rowner, rname) + } + } else { + // todo. make sure that free methods and free local defs work correctly + if (sym.isTerm) { + if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym) + reifyFreeTerm(sym, Ident(sym)) + } else { + if (reifyDebug) println("Free type: " + sym) + reifyFreeType(sym, Ident(sym)) + } + } + } + + def reifyFreeTerm(sym: Symbol, value: Tree): Tree = + locallyReified get sym match { + case Some(reified) => + reified + case None => + if (sym.isCapturedVariable) { + assert(value.isInstanceOf[Ident], showRaw(value)) + val capturedTpe = capturedVariableType(sym) + val capturedValue = referenceCapturedVariable(sym) + locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym)))) + } else { + locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(origin(sym)))) + } + } + + def reifyFreeType(sym: Symbol, value: Tree): Tree = + locallyReified get sym match { + case Some(reified) => + reified + case None => + val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.MIRROR_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null)))) + // todo. implement info reification for free types: type bounds, HK-arity, whatever else that can be useful + locallyReify(sym, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym)))) + } + + import scala.collection.mutable._ + private val localReifications = ArrayBuffer[ValDef]() + private val locallyReified = Map[Symbol, Tree]() + def symbolTable: List[ValDef] = localReifications.toList + def symbolTable_=(newSymbolTable: List[ValDef]): Unit = { + localReifications.clear() + locallyReified.clear() + newSymbolTable foreach { + case freedef @ FreeDef(_, name, binding, _) => + if (!(locallyReified contains binding.symbol)) { + localReifications += freedef + locallyReified(binding.symbol) = Ident(name) + } + } + } + + private def locallyReify(sym: Symbol, reificode: => Tree): Tree = { + val reified = reificode + val Apply(Select(_, flavor), _) = reified + // [Eugene] name clashes are impossible, right? + var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name) + if (flavor == nme.newFreeTerm && sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX); + // todo. also reify annotations for free vars + localReifications += ValDef(NoMods, name, TypeTree(), reified) + locallyReified(sym) = Ident(name) + locallyReified(sym) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala new file mode 100644 index 0000000000..22f42aea49 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala @@ -0,0 +1,220 @@ +package scala.reflect.reify +package codegen + +trait Trees { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Reify a tree. + * For internal use only, use ``reified'' instead. + */ + def reifyTree(tree: Tree): Tree = { + assert(tree != null, "tree is null") + + if (tree.isErroneous) + CannotReifyErroneousReifee(tree) + + val splicedTree = spliceTree(tree) + if (splicedTree != EmptyTree) + return splicedTree + + // the idea behind the new reincarnation of reifier is a simple maxim: + // + // never call ``reifyType'' to reify a tree + // + // this works because the stuff we are reifying was once represented with trees only + // and lexical scope information can be fully captured by reifying symbols + // + // to enable this idyll, we work hard in the ``Reshape'' phase + // which replaces all types with equivalent trees and works around non-idempotencies of the typechecker + // + // why bother? because this brings method to the madness + // the first prototype of reification reified all types and symbols for all trees => this quickly became unyieldy + // the second prototype reified external types, but avoided reifying local ones => this created an ugly irregularity + // current approach is uniform and compact + var rtree = tree match { + case mirror.EmptyTree => + reifyMirrorObject(EmptyTree) + case mirror.emptyValDef => + mirrorSelect(nme.emptyValDef) + case FreeDef(_, _, _, _) => + reifyNestedFreeDef(tree) + case FreeRef(_, _) => + reifyNestedFreeRef(tree) + case BoundTerm(tree) => + reifyBoundTerm(tree) + case BoundType(tree) => + reifyBoundType(tree) + case NestedExpr(_, _, _) => + reifyNestedExpr(tree) + case Literal(const @ Constant(_)) => + mirrorCall(nme.Literal, reifyProduct(const)) + case Import(expr, selectors) => + mirrorCall(nme.Import, reify(expr), mkList(selectors map reifyProduct)) + case _ => + reifyProduct(tree) + } + + rtree + } + + def reifyModifiers(m: mirror.Modifiers) = + mirrorCall("modifiersFromInternalFlags", reify(m.flags), reify(m.privateWithin), reify(m.annotations)) + + private def spliceTree(tree: Tree): Tree = { + tree match { + case EvalSplice(splicee) => + if (reifyDebug) println("splicing eval " + tree) + + // see ``Metalevels'' for more info about metalevel breaches + // and about how we deal with splices that contain them + if (splicee exists (sub => sub.hasSymbol && sub.symbol != NoSymbol && sub.symbol.metalevel > 0)) { + if (reifyDebug) println("splicing has failed: cannot splice when facing a metalevel breach") + EmptyTree + } else { + if (reifyDebug) println("splicing has succeeded") + var splice = Select(splicee, nme.tree) + splice match { + case InlinedTreeSplice(_, inlinedSymbolTable, tree, _) => + if (reifyDebug) println("inlining the splicee") + // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' + inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) } + symbolTable ++= inlinedSymbolTable + tree + case tree => + // we need to preserve types of exprs, because oftentimes they cannot be inferred later + // this circumvents regular reification scheme, therefore we go the extra mile here + new Transformer { + override def transform(tree: Tree) = super.transform(tree match { + case NestedExpr(factory, tree, typetag) => + val typedFactory = TypeApply(factory, List(TypeTree(typetag.tpe.typeArgs(0)))) + Apply(Apply(typedFactory, List(tree)), List(typetag)) + case _ => + tree + }) + }.transform(tree) + } + } + case ValueSplice(splicee) => + // todo. implement this + ??? + case _ => + EmptyTree + } + } + + private def reifyBoundTerm(tree: Tree): Tree = tree match { + case tree @ This(_) if tree.symbol == NoSymbol => + throw new Error("unexpected: bound term that doesn't have a symbol: " + showRaw(tree)) + case tree @ This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass && !tree.symbol.isLocalToReifee => + val sym = tree.symbol + if (reifyDebug) println("This for %s, reified as freeVar".format(sym)) + if (reifyDebug) println("Free: " + sym) + mirrorCall(nme.Ident, reifyFreeTerm(sym, This(sym))) + case tree @ This(_) if !tree.symbol.isLocalToReifee => + if (reifyDebug) println("This for %s, reified as This".format(tree.symbol)) + mirrorCall(nme.This, reify(tree.symbol)) + case tree @ This(_) if tree.symbol.isLocalToReifee => + mirrorCall(nme.This, reify(tree.qual)) + case tree @ Ident(_) if tree.symbol == NoSymbol => + // this sometimes happens, e.g. for binds that don't have a body + // or for untyped code generated during previous phases + // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?") + mirrorCall(nme.Ident, reify(tree.name)) + case tree @ Ident(_) if !tree.symbol.isLocalToReifee => + if (tree.symbol.isVariable && tree.symbol.owner.isTerm) { + captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reification here. + mirrorCall(nme.Select, mirrorCall(nme.Ident, reify(tree.symbol)), reify(nme.elem)) + } else { + mirrorCall(nme.Ident, reify(tree.symbol)) + } + case tree @ Ident(_) if tree.symbol.isLocalToReifee => + mirrorCall(nme.Ident, reify(tree.name)) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + + private def reifyBoundType(tree: Tree): Tree = { + def reifyBoundType(tree: Tree): Tree = { + if (tree.tpe == null) + throw new Error("unexpected: bound type that doesn't have a tpe: " + showRaw(tree)) + + if (tree.symbol.isLocalToReifee) + reifyProduct(tree) + else { + val sym0 = tree.symbol + val sym = sym0.dealias + val tpe0 = tree.tpe + val tpe = tpe0.dealias + if (reifyDebug) println("reifying bound type %s (underlying type is %s, dealiased is %s)".format(sym0, tpe0, tpe)) + + if (eligibleForSplicing(tpe)) { + val spliced = spliceType(tpe) + if (spliced == EmptyTree) { + if (reifyDebug) println("splicing failed: reify as is") + mirrorCall(nme.TypeTree, reifyType(tpe)) + } else { + spliced match { + case TypeRefToFreeType(freeType) => + if (reifyDebug) println("splicing returned a free type: " + freeType) + Ident(freeType) + case _ => + if (reifyDebug) println("splicing succeeded: " + spliced) + mirrorCall(nme.TypeTree, spliced) + } + } + } else { + if (sym.isLocatable) { + if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym)) + mirrorCall(nme.Ident, reify(sym)) + } else { + if (reifyDebug) println("tpe is an alias, but not a locatable: reify as TypeTree(%s)".format(tpe)) + mirrorCall(nme.TypeTree, reifyType(tpe)) + } + } + } + } + + tree match { + case Select(_, _) => + reifyBoundType(tree) + case SelectFromTypeTree(_, _) => + reifyBoundType(tree) + case Ident(_) => + reifyBoundType(tree) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + } + + private def reifyNestedFreeDef(tree: Tree): Tree = { + if (reifyDebug) println("nested free def: %s".format(showRaw(tree))) + reifyProduct(tree) + } + + private def reifyNestedFreeRef(tree: Tree): Tree = tree match { + case Apply(Select(mrRef @ Ident(_), ident), List(Ident(name: TermName))) if ident == nme.Ident && name.startsWith(nme.MIRROR_FREE_PREFIX) => + if (reifyDebug) println("nested free ref: %s".format(showRaw(tree))) + reifyProduct(tree) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + + private def reifyNestedExpr(tree: Tree): Tree = tree match { + case NestedExpr(factory, tree, typetag) => + // we need to preserve types of exprs, because oftentimes they cannot be inferred later + // this circumvents regular reification scheme, therefore we go through this crazy dance + if (reifyDebug) println("nested expr: %s".format(showRaw(tree))) + val rtype = mirrorCall(nme.TypeTree, reify(typetag.tpe.typeArgs(0))) + val rfactory = mirrorCall(nme.TypeApply, reify(factory), mkList(List(rtype))) + val rexpr = mirrorCall(nme.Apply, rfactory, reify(List(tree))) + val rwrapped = mirrorCall(nme.Apply, rexpr, reify(List(typetag))) + rwrapped + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala new file mode 100644 index 0000000000..6f3a60a076 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -0,0 +1,226 @@ +package scala.reflect.reify +package codegen + +trait Types { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Reify a type. + * For internal use only, use ``reified'' instead. + */ + def reifyType(tpe0: Type): Tree = { + assert(tpe0 != null, "tpe is null") + val tpe = tpe0.dealias + + if (tpe.isErroneous) + CannotReifyErroneousReifee(tpe) + if (tpe.isLocalToReifee) + CannotReifyType(tpe) + + // [Eugene] how do I check that the substitution is legal w.r.t tpe.info? + val spliced = spliceType(tpe) + if (spliced != EmptyTree) + return spliced + + val tsym = tpe.typeSymbol + if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic) + Select(reify(tpe.typeSymbol), nme.asTypeConstructor) + else tpe match { + case tpe @ NoType => + reifyMirrorObject(tpe) + case tpe @ NoPrefix => + reifyMirrorObject(tpe) + case tpe @ ThisType(root) if root == RootClass => + mirrorSelect("definitions.RootClass.thisPrefix") + case tpe @ ThisType(empty) if empty == EmptyPackageClass => + mirrorSelect("definitions.EmptyPackageClass.thisPrefix") + case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => + mirrorCall(nme.thisModuleType, reify(clazz.fullName)) + case tpe @ ThisType(_) => + reifyProduct(tpe) + case tpe @ SuperType(thistpe, supertpe) => + reifyProduct(tpe) + case tpe @ SingleType(pre, sym) => + reifyProduct(tpe) + case tpe @ ConstantType(value) => + mirrorFactoryCall(nme.ConstantType, reifyProduct(value)) + case tpe @ TypeRef(pre, sym, args) => + reifyProduct(tpe) + case tpe @ TypeBounds(lo, hi) => + reifyProduct(tpe) + case tpe @ NullaryMethodType(restpe) => + reifyProduct(tpe) + case tpe @ AnnotatedType(anns, underlying, selfsym) => +// reifyAnnotatedType(tpe) + CannotReifyType(tpe) + case _ => +// reifyToughType(tpe) + CannotReifyType(tpe) + } + } + + /** An obscure flag necessary for implicit TypeTag generation */ + private var spliceTypesEnabled = !dontSpliceAtTopLevel + + /** Keeps track of whether this reification contains abstract type parameters */ + var maybeGround = true + var definitelyGround = true + + def eligibleForSplicing(tpe: Type): Boolean = { + // [Eugene] is this comprehensive? + // the only thingies that we want to splice are: 1) type parameters, 2) type members + // this check seems to cover them all, right? + tpe.isInstanceOf[TypeRef] && tpe.typeSymbol.isAbstractType + } + + private type SpliceCacheKey = (Symbol, Symbol) + private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = { + val cache = analyzer.perRunMacroCache.getOrElseUpdate(MacroContextReify, collection.mutable.Map[Any, Any]()) + cache.getOrElseUpdate("spliceCache", collection.mutable.Map[SpliceCacheKey, Tree]()).asInstanceOf[collection.mutable.Map[SpliceCacheKey, Tree]] + } + + def spliceType(tpe: Type): Tree = { + if (eligibleForSplicing(tpe)) { + if (reifyDebug) println("splicing " + tpe) + + if (spliceTypesEnabled) { + var tagClass = if (requireGroundTypeTag) GroundTypeTagClass else TypeTagClass + val tagTpe = singleType(prefix.tpe, prefix.tpe member tagClass.name) + + // [Eugene] this should be enough for an abstract type, right? + val key = (tagClass, tpe.typeSymbol) + if (reifyDebug && spliceCache.contains(key)) println("cache hit: " + spliceCache(key)) + val result = spliceCache.getOrElseUpdate(key, { + // if this fails, it might produce the dreaded "erroneous or inaccessible type" error + // to find out the whereabouts of the error run scalac with -Ydebug + if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe)) + val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] + typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireGroundTypeTag) match { + case failure if failure.isEmpty => + if (reifyDebug) println("implicit search was fruitless") + definitelyGround &= false + maybeGround &= false + EmptyTree + case success => + if (reifyDebug) println("implicit search has produced a result: " + success) + definitelyGround |= requireGroundTypeTag + maybeGround |= true + var splice = Select(success, nme.tpe) + splice match { + case InlinedTypeSplice(_, inlinedSymbolTable, tpe) => + // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels'' + inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) } + symbolTable ++= inlinedSymbolTable + reifyTrace("inlined the splicee: ")(tpe) + case tpe => + tpe + } + } + }) + if (result != EmptyTree) return result.duplicate + } else { + if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false") + } + + if (requireGroundTypeTag) + CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe) + } + + spliceTypesEnabled = true + EmptyTree + } + + // yet another thingie disabled for simplicity + // in principle, we could retain and reify AnnotatedTypes + // but that'd require reifying every type and symbol inside ann.args + // however, since we've given up on tough types for the moment, the former would be problematic +// private def reifyAnnotatedType(tpe: AnnotatedType): Tree = { +// // ``Reshaper'' transforms annotation infos from symbols back into Modifier.annotations, which are trees +// // so the only place on Earth that can lead to reification of AnnotationInfos is the Ay Tee Land +// // therefore this function is as local as possible, don't move it out of this scope +// def reifyAnnotationInfo(ann: AnnotationInfo): Tree = { +// val reifiedArgs = ann.args map { arg => +// val saved1 = reifyTreeSymbols +// val saved2 = reifyTreeTypes +// +// try { +// // one more quirk of reifying annotations +// // +// // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs +// // that's because a lot of logic expects post-typer trees to have non-null tpes +// // +// // Q: reified trees are pre-typer, so there's shouldn't be a problem. +// // reflective typechecker will fill in missing symbols and types, right? +// // A: actually, no. annotation ASTs live inside AnnotatedTypes, +// // and insides of the types is the place where typechecker doesn't look. +// reifyTreeSymbols = true +// reifyTreeTypes = true +// +// // todo. every AnnotationInfo is an island, entire of itself +// // no regular Traverser or Transformer can reach it +// // hence we need to run its contents through the entire reification pipeline +// // e.g. to apply reshaping or to check metalevels +// reify(arg) +// } finally { +// reifyTreeSymbols = saved1 +// reifyTreeTypes = saved2 +// } +// } +// +// def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match { +// case LiteralAnnotArg(const) => +// mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const)) +// case ArrayAnnotArg(args) => +// mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*)) +// case NestedAnnotArg(ann) => +// mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann)) +// } +// +// // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important +// val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2))) +// mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs)) +// } +// +// val AnnotatedType(anns, underlying, selfsym) = tpe +// mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym)) +// } + + // previous solution to reifying tough types involved creating dummy symbols (see ``registerReifiableSymbol'' calls below) + // however such symbols lost all the connections with their origins and became almost useless, except for typechecking + // hence this approach was replaced by less powerful, but more principled one based on ``reifyFreeType'' + // it's possible that later on we will revise and revive ``reifyToughType'', but for now it's disabled under an implementation restriction +// /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */ +// // This is the uncharted territory in the reifier +// private def reifyToughType(tpe: Type): Tree = { +// if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind)) +// +// def reifyScope(scope: Scope): Tree = { +// scope foreach registerReifiableSymbol +// mirrorCall(nme.newScopeWith, scope.toList map reify: _*) +// } +// +// tpe match { +// case tpe @ RefinedType(parents, decls) => +// registerReifiableSymbol(tpe.typeSymbol) +// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) +// case tpe @ ExistentialType(tparams, underlying) => +// tparams foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) +// case tpe @ ClassInfoType(parents, decls, clazz) => +// registerReifiableSymbol(clazz) +// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) +// case tpe @ MethodType(params, restpe) => +// params foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(params), reify(restpe)) +// case tpe @ PolyType(tparams, underlying) => +// tparams foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) +// case _ => +// throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind)) +// } +// } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala new file mode 100644 index 0000000000..bb369a1adb --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Util.scala @@ -0,0 +1,112 @@ +package scala.reflect.reify +package codegen + +trait Util { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + val reifyDebug = settings.Yreifydebug.value + val reifyCopypaste = settings.Yreifycopypaste.value + val reifyTrace = scala.tools.nsc.util.trace when reifyDebug + object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters + val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString + + def reifyList(xs: List[Any]): Tree = + mkList(xs map reify) + + def reifyProduct(x: Product): Tree = + reifyProduct(x.productPrefix, x.productIterator.toList) + + def reifyProduct(prefix: String, elements: List[Any]): Tree = { + // reflection would be more robust, but, hey, this is a hot path + if (prefix.startsWith("Tuple")) scalaFactoryCall(prefix, (elements map reify).toList: _*) + else mirrorCall(prefix, (elements map reify): _*) + } + + // helper functions + + /** Reify a case object defined in Mirror */ + def reifyMirrorObject(name: String): Tree = + mirrorSelect(name) + + def reifyMirrorObject(x: Product): Tree = + reifyMirrorObject(x.productPrefix) + + def call(fname: String, args: Tree*): Tree = + Apply(termPath(fname), args.toList) + + def mirrorSelect(name: String): Tree = + termPath(nme.MIRROR_PREFIX + name) + + def mirrorCall(name: TermName, args: Tree*): Tree = + call("" + (nme.MIRROR_PREFIX append name), args: _*) + + def mirrorCall(name: String, args: Tree*): Tree = + call(nme.MIRROR_PREFIX + name, args: _*) + + def mirrorFactoryCall(value: Product, args: Tree*): Tree = + mirrorFactoryCall(value.productPrefix, args: _*) + + def mirrorFactoryCall(prefix: String, args: Tree*): Tree = + mirrorCall(prefix, args: _*) + + def scalaFactoryCall(name: String, args: Tree*): Tree = + call("scala." + name + ".apply", args: _*) + + def mkList(args: List[Tree]): Tree = + scalaFactoryCall("collection.immutable.List", args: _*) + + /** + * An (unreified) path that refers to definition with given fully qualified name + * @param mkName Creator for last portion of name (either TermName or TypeName) + */ + def path(fullname: String, mkName: String => Name): Tree = { + val parts = fullname split "\\." + val prefixParts = parts.init + val lastName = mkName(parts.last) + if (prefixParts.isEmpty) Ident(lastName) + else { + val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _)) + Select(prefixTree, lastName) + } + } + + /** An (unreified) path that refers to term definition with given fully qualified name */ + def termPath(fullname: String): Tree = path(fullname, newTermName) + + /** An (unreified) path that refers to type definition with given fully qualified name */ + def typePath(fullname: String): Tree = path(fullname, newTypeName) + + def isTough(tpe: Type) = { + def isTough(tpe: Type) = tpe match { + case _: RefinedType => true + case _: ExistentialType => true + case _: ClassInfoType => true + case _: MethodType => true + case _: PolyType => true + case _ => false + } + + tpe != null && (tpe exists isTough) + } + + def isAnnotated(tpe: Type) = { + def isAnnotated(tpe: Type) = tpe match { + case _: AnnotatedType => true + case _ => false + } + + tpe != null && (tpe exists isAnnotated) + } + + def origin(sym: Symbol) = { + var origin = "" + if (sym.owner != NoSymbol) origin += "defined by %s".format(sym.owner.name) + if (sym.pos != NoPosition) origin += " in %s:%s:%s".format(sym.pos.source.file.name, sym.pos.line, sym.pos.column) + if (origin == "") origin = "of unknown origin" + origin + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala new file mode 100644 index 0000000000..7041fbf6ed --- /dev/null +++ b/src/compiler/scala/reflect/reify/package.scala @@ -0,0 +1,22 @@ +package scala.reflect + +import scala.tools.nsc.Global + +package object reify { + def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Reifier { val mirror: global.type } = { + val typer1: typer.type = typer + val prefix1: prefix.type = prefix + val reifee1 = reifee + val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel + val requireGroundTypeTag1 = requireGroundTypeTag + + new { + val mirror: global.type = global + val typer = typer1 + val prefix = prefix1 + val reifee = reifee1 + val dontSpliceAtTopLevel = dontSpliceAtTopLevel1 + val requireGroundTypeTag = requireGroundTypeTag1 + } with Reifier + } +} diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala new file mode 100644 index 0000000000..59a36f0ba4 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -0,0 +1,61 @@ +package scala.reflect.reify +package phases + +trait Calculate { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + implicit def sym2richSym(sym: Symbol): RichSymbol = new RichSymbol(sym) + class RichSymbol(sym: Symbol) { + def metalevel: Int = { assert(sym != NoSymbol); localSymbols.getOrElse(sym, 0) } + def isLocalToReifee = (localSymbols contains sym) // [Eugene] how do I account for local skolems? + } + + implicit def tpe2richTpe(tpe: Type): RichType = new RichType(tpe) + class RichType(tpe: Type) { + def isLocalToReifee = tpe != null && (tpe exists (tp => (localSymbols contains tp.typeSymbol) || (localSymbols contains tp.termSymbol))) + } + + private var localSymbols = collection.mutable.Map[Symbol, Int]() // set of all symbols that are local to the tree to be reified + private def registerLocalSymbol(sym: Symbol, metalevel: Int): Unit = + if (sym != null && sym != NoSymbol) { + if (localSymbols contains sym) + assert(localSymbols(sym) == metalevel, "metalevel mismatch: expected %s, actual %s".format(localSymbols(sym), metalevel)) + localSymbols(sym) = metalevel + } + + /** + * Merely traverses the reifiee and records local symbols along with their metalevels. + */ + val calculate = new Traverser { + // see the explanation of metalevels in ``Metalevels'' + var currMetalevel = 1 + + override def traverse(tree: Tree): Unit = tree match { + case TreeSplice(_) => + currMetalevel -= 1 + try super.traverse(tree) + finally currMetalevel += 1 + case tree if tree.isDef => + if (reifyDebug) println("boundSym: %s of type %s".format(tree.symbol, (tree.productIterator.toList collect { case tt: TypeTree => tt } headOption).getOrElse(TypeTree(tree.tpe)))) + registerLocalSymbol(tree.symbol, currMetalevel) + + bindRelatedSymbol(tree.symbol.sourceModule, "sourceModule") + bindRelatedSymbol(tree.symbol.moduleClass, "moduleClass") + bindRelatedSymbol(tree.symbol.companionClass, "companionClass") + bindRelatedSymbol(tree.symbol.companionModule, "companionModule") + Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") } + def bindRelatedSymbol(related: Symbol, name: String): Unit = + if (related != null && related != NoSymbol) { + if (reifyDebug) println("boundSym (" + name + "): " + related) + registerLocalSymbol(related, currMetalevel) + } + super.traverse(tree) + case _ => + super.traverse(tree) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala new file mode 100644 index 0000000000..a329a1043d --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala @@ -0,0 +1,148 @@ +package scala.reflect.reify +package phases + +trait Metalevels { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Makes sense of cross-stage bindings. + * + * ================ + * + * Analysis of cross-stage bindings becomes convenient if we introduce the notion of metalevels. + * Metalevel of a tree is a number that gets incremented every time you reify something and gets decremented when you splice something. + * Metalevel of a symbol is equal to the metalevel of its definition. + * + * Example 1. Consider the following snippet: + * + * reify { + * val x = 2 // metalevel of symbol x is 1, because it's declared inside reify + * val y = reify{x} // metalevel of symbol y is 1, because it's declared inside reify + * // metalevel of Ident(x) is 2, because it's inside two reifies + * y.eval // metalevel of Ident(y) is 0, because it's inside a designator of a splice + * } + * + * Cross-stage bindings are introduced when symbol.metalevel != curr_metalevel. + * Both bindings introduced in Example 1 are cross-stage. + * + * Depending on what side of the inequality is greater, the following situations might occur: + * + * 1) symbol.metalevel < curr_metalevel. In this case reifier will generate a free variable + * that captures both the name of the symbol (to be compiled successfully) and its value (to be run successfully). + * For example, x in Example 1 will be reified as follows: Ident(newFreeVar("x", IntClass.tpe, x)) + * + * 2) symbol.metalevel > curr_metalevel. This leads to a metalevel breach that violates intuitive perception of splicing. + * As defined in macro spec, splicing takes a tree and inserts it into another tree - as simple as that. + * However, how exactly do we do that in the case of y.eval? In this very scenario we can use dataflow analysis and inline it, + * but what if y were a var, and what if it were calculated randomly at runtime? + * + * This question has a genuinely simple answer. Sure, we cannot resolve such splices statically (i.e. during macro expansion of ``reify''), + * but now we have runtime toolboxes, so noone stops us from picking up that reified tree and evaluating it at runtime + * (in fact, this is something that ``Expr.eval'' and ``Expr.value'' do transparently). + * + * This is akin to early vs late binding dilemma. + * The prior is faster, plus, the latter (implemented with reflection) might not work because of visibility issues or might be not available on all platforms. + * But the latter still has its uses, so I'm allowing metalevel breaches, but introducing the -Xlog-runtime-evals to log them. + * + * ================ + * + * As we can see, the only problem is the fact that lhs'es of eval can be code blocks that can capture variables from the outside. + * Code inside the lhs of an eval is not reified, while the code from the enclosing reify is. + * + * Hence some bindings become cross-stage, which is not bad per se (in fact, some cross-stage bindings have sane semantics, as in the example above). + * However this affects freevars, since they are delicate inter-dimensional beings that refer to both current and next planes of existence. + * When splicing tears the fabric of the reality apart, some freevars have to go single-dimensional to retain their sanity. + * + * Example 2. Consider the following snippet: + * + * reify { + * val x = 2 + * reify{x}.eval + * } + * + * Since the result of the inner reify is wrapped in an eval, it won't be reified + * together with the other parts of the outer reify, but will be inserted into that result verbatim. + * + * The inner reify produces an Expr[Int] that wraps Ident(freeVar("x", IntClass.tpe, x)). + * However the freevar the reification points to will vanish when the compiler processes the outer reify. + * That's why we need to replace that freevar with a regular symbol that will point to reified x. + * + * Example 3. Consider the following fragment: + * + * reify { + * val x = 2 + * val y = reify{x} + * y.eval + * } + * + * In this case the inner reify doesn't appear next to eval, so it will be reified together with x. + * This means that no special processing is needed here. + * + * Example 4. Consider the following fragment: + * + * reify { + * val x = 2 + * { + * val y = 2 + * val z = reify{reify{x + y}} + * z.eval + * }.eval + * } + * + * The reasoning from Example 2 still holds here - we do need to inline the freevar that refers to x. + * However, we must not touch anything inside the eval'd block, because it's not getting reified. + */ + var metalevels = new Transformer { + var insideSplice = false + var freedefsToInline = collection.mutable.Map[String, ValDef]() + + def withinSplice[T](op: => T) = { + val old = insideSplice + insideSplice = true + try op + finally insideSplice = old + } + + // Q: here we deal with all sorts of reified trees. what about ReifiedType(_, _, _, _)? + // A: nothing. reified trees give us problems because they sometimes create dimensional rifts as described above + // to the contrast, reified types (i.e. synthetic typetags materialized by Implicits.scala) always stay on the same metalevel as their enclosing code + override def transform(tree: Tree): Tree = tree match { + case InlineableTreeSplice(splicee, inlinedSymbolTable, _, _, flavor) => + if (reifyDebug) println("entering inlineable splice: " + splicee) + val Block(mrDef :: symbolTable, expr) = splicee + // [Eugene] how to express the fact that a scrutinee is both of some type and matches an extractor? + val freedefsToInline = symbolTable collect { case freedef @ FreeTermDef(_, _, binding, _) if binding.symbol.isLocalToReifee => freedef.asInstanceOf[ValDef] } + freedefsToInline foreach (vdef => this.freedefsToInline(vdef.name) = vdef) + val symbolTable1 = symbolTable diff freedefsToInline + val tree1 = Select(Block(mrDef :: symbolTable1, expr), flavor) + if (reifyDebug) println("trimmed %s inlineable free defs from its symbol table: %s".format(freedefsToInline.length, freedefsToInline map (_.name) mkString(", "))) + withinSplice { super.transform(tree1) } + case TreeSplice(splicee) => + if (reifyDebug) println("entering splice: " + splicee) + val hasBreaches = splicee exists (_.symbol.metalevel > 0) + if (!insideSplice && hasBreaches) { + if (settings.logRuntimeSplices.value) reporter.echo(tree.pos, "this splice cannot be resolved statically") + if (reifyDebug) println("metalevel breach in %s: %s".format(tree, (splicee filter (_.symbol.metalevel > 0) map (_.symbol) distinct) mkString ", ")) + } + withinSplice { super.transform(tree) } + // todo. also inline usages of ``freedefsToInline'' in the symbolTable itself + // e.g. a free$Foo can well use free$x, if Foo is path-dependent w.r.t x + // FreeRef(_, _) check won't work, because metalevels of symbol table and body are different, hence, freerefs in symbol table look different from freerefs in body + // todo. also perform garbage collection on local symbols + // so that local symbols used only in type signatures of free vars get removed + case FreeRef(mr, name) if freedefsToInline contains name => + if (reifyDebug) println("inlineable free ref: %s in %s".format(name, showRaw(tree))) + val freedef @ FreeDef(_, _, binding, _) = freedefsToInline(name) + if (reifyDebug) println("related definition: %s".format(showRaw(freedef))) + val inlined = reify(binding) + if (reifyDebug) println("verdict: inlined as %s".format(showRaw(inlined))) + inlined + case _ => + super.transform(tree) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala new file mode 100644 index 0000000000..f6d6423605 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -0,0 +1,42 @@ +package scala.reflect.reify +package phases + +import scala.runtime.ScalaRunTime.isAnyVal +import scala.runtime.ScalaRunTime.isTuple +import scala.reflect.reify.codegen._ + +trait Reify extends Symbols + with Types + with Names + with Trees + with Positions + with Util { + + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Reifies any supported value. + * For internal use only, use ``reified'' instead. + */ + def reify(reifee: Any): Tree = reifee match { + // before adding some case here, in global scope, please, consider + // whether it can be localized like reifyAnnotationInfo or reifyScope + // this will help reification stay as sane as possible + case sym: Symbol => reifySymRef(sym) + case tpe: Type => reifyType(tpe) + case name: Name => reifyName(name) + case tree: Tree => reifyTree(tree) + case pos: Position => reifyPosition(pos) + case mods: mirror.Modifiers => reifyModifiers(mods) + case xs: List[_] => reifyList(xs) + case s: String => Literal(Constant(s)) + case v if isAnyVal(v) => Literal(Constant(v)) + case null => Literal(Constant(null)) + case _ => + throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass)) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala new file mode 100644 index 0000000000..e700604612 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -0,0 +1,296 @@ +package scala.reflect.reify +package phases + +import scala.tools.nsc.symtab.Flags._ + +trait Reshape { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * Rolls back certain changes that were introduced during typechecking of the reifee. + * + * These include: + * * Replacing type trees with TypeTree(tpe) + * * Transforming Modifiers.annotations into Symbol.annotations + * * Transforming Annotated annotations into AnnotatedType annotations + * * Transforming Annotated(annot, expr) into Typed(expr, TypeTree(Annotated(annot, _)) + * * Non-idempotencies of the typechecker: https://issues.scala-lang.org/browse/SI-5464 + */ + val reshape = new Transformer { + var currentSymbol: Symbol = NoSymbol + + override def transform(tree: Tree) = { + currentSymbol = tree.symbol + + val preTyper = tree match { + case tree if tree.isErroneous => + tree + case tt @ TypeTree() => + toPreTyperTypeTree(tt) + case toa @ TypedOrAnnotated(_) => + toPreTyperTypedOrAnnotated(toa) + case ta @ TypeApply(hk, ts) => + val discard = ts collect { case tt: TypeTree => tt } exists isDiscarded + if (reifyDebug && discard) println("discarding TypeApply: " + tree) + if (discard) hk else ta + case classDef @ ClassDef(mods, name, params, impl) => + val Template(parents, self, body) = impl + var body1 = trimAccessors(classDef, body) + body1 = trimSyntheticCaseClassMembers(classDef, body1) + var impl1 = Template(parents, self, body1).copyAttrs(impl) + ClassDef(mods, name, params, impl1).copyAttrs(classDef) + case moduledef @ ModuleDef(mods, name, impl) => + val Template(parents, self, body) = impl + var body1 = trimAccessors(moduledef, body) + body1 = trimSyntheticCaseClassMembers(moduledef, body1) + var impl1 = Template(parents, self, body1).copyAttrs(impl) + ModuleDef(mods, name, impl1).copyAttrs(moduledef) + case template @ Template(parents, self, body) => + val discardedParents = parents collect { case tt: TypeTree => tt } filter isDiscarded + if (reifyDebug && discardedParents.length > 0) println("discarding parents in Template: " + discardedParents.mkString(", ")) + val parents1 = parents diff discardedParents + val body1 = trimSyntheticCaseClassCompanions(body) + Template(parents1, self, body1).copyAttrs(template) + case block @ Block(stats, expr) => + val stats1 = trimSyntheticCaseClassCompanions(stats) + Block(stats1, expr).copyAttrs(block) + case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isLazy => + if (reifyDebug) println("dropping $lzy in lazy val's name: " + tree) + val name1 = if (name endsWith nme.LAZY_LOCAL) name dropRight nme.LAZY_LOCAL.length else name + ValDef(mods, name1, tpt, rhs).copyAttrs(valdef) + case unapply @ UnApply(fun, args) => + def extractExtractor(tree: Tree): Tree = { + val Apply(fun, args) = tree + args match { + case List(Ident(special)) if special == nme.SELECTOR_DUMMY => + val Select(extractor, flavor) = fun + assert(flavor == nme.unapply || flavor == nme.unapplySeq) + extractor + case _ => + extractExtractor(fun) + } + } + + if (reifyDebug) println("unapplying unapply: " + tree) + val fun1 = extractExtractor(fun) + Apply(fun1, args).copyAttrs(unapply) + case Literal(const @ Constant(tpe: Type)) => + // todo. implement this + ??? + case Literal(const @ Constant(sym: Symbol)) => + // todo. implement this + ??? + case _ => + tree + } + + super.transform(preTyper) + } + + override def transformModifiers(mods: Modifiers) = { + val mods1 = toPreTyperModifiers(mods, currentSymbol) + super.transformModifiers(mods1) + } + + private def toPreTyperModifiers(mods: Modifiers, sym: Symbol) = { + if (!sym.annotations.isEmpty) { + val Modifiers(flags, privateWithin, annotations) = mods + val postTyper = sym.annotations filter (_.original != EmptyTree) + if (reifyDebug && !postTyper.isEmpty) println("reify symbol annotations for: " + sym) + if (reifyDebug && !postTyper.isEmpty) println("originals are: " + sym.annotations) + val preTyper = postTyper map toPreTyperAnnotation + mods.withAnnotations(preTyper) + } else { + mods + } + } + + /** Restore pre-typer representation of a type. + * + * NB: This is the trickiest part of reification! + * + * In most cases, we're perfectly fine to reify a Type itself (see ``reifyType''). + * However if the type involves a symbol declared inside the quasiquote (i.e. registered in ``boundSyms''), + * then we cannot reify it, or otherwise subsequent reflective compilation will fail. + * + * Why will it fail? Because reified deftrees (e.g. ClassDef(...)) will generate fresh symbols during that compilation, + * so naively reified symbols will become out of sync, which brings really funny compilation errors and/or crashes, e.g.: + * https://issues.scala-lang.org/browse/SI-5230 + * + * To deal with this unpleasant fact, we need to fall back from types to equivalent trees (after all, parser trees don't contain any types, just trees, so it should be possible). + * Luckily, these original trees get preserved for us in the ``original'' field when Trees get transformed into TypeTrees. + * And if an original of a type tree is empty, we can safely assume that this type is non-essential (e.g. was inferred/generated by the compiler). + * In that case the type can be omitted (e.g. reified as an empty TypeTree), since it will be inferred again later on. + * + * An important property of the original is that it isn't just a pre-typer tree. + * It's actually kind of a post-typer tree with symbols assigned to its Idents (e.g. Ident("List") will contain a symbol that points to immutable.this.List). + * This is very important, since subsequent reflective compilation won't have to resolve these symbols. + * In general case, such resolution cannot be performed, since reification doesn't preserve lexical context, + * which means that reflective compilation won't be aware of, say, imports that were provided when the reifee has been compiled. + * + * This workaround worked surprisingly well and allowed me to fix several important reification bugs, until the abstraction has leaked. + * Suddenly I found out that in certain contexts original trees do not contain symbols, but are just parser trees. + * To the moment I know only one such situation: typedAnnotations does not typecheck the annotation in-place, but rather creates new trees and typechecks them, so the original remains symless. + * Thus we apply a workaround for that in typedAnnotated. I hope this will be the only workaround in this department. + * + * upd. Recently I went ahead and started using original for all TypeTrees, regardless of whether they refer to local symbols or not. + * As a result, ``reifyType'' is never called directly by tree reification (and, wow, it seems to work great!). + * The only usage of ``reifyType'' now is for servicing typetags, however, I have some ideas how to get rid of that as well. + */ + private def isDiscarded(tt: TypeTree) = tt.original == null + private def toPreTyperTypeTree(tt: TypeTree): Tree = { + if (tt.original != null) { + // here we rely on the fact that the originals that reach this point + // have all necessary symbols attached to them (i.e. that they can be recompiled in any lexical context) + // if this assumption fails, please, don't be quick to add postprocessing here (like I did before) + // but rather try to fix this in Typer, so that it produces quality originals (like it's done for typedAnnotated) + if (reifyDebug) println("TypeTree, essential: %s (%s)".format(tt.tpe, tt.tpe.kind)) + if (reifyDebug) println("verdict: rolled back to original %s".format(tt.original)) + transform(tt.original) + } else { + // type is deemed to be non-essential + // erase it and hope that subsequent reflective compilation will be able to recreate it again + if (reifyDebug) println("TypeTree, non-essential: %s (%s)".format(tt.tpe, tt.tpe.kind)) + if (reifyDebug) println("verdict: discarded") + TypeTree() + } + } + + private def toPreTyperTypedOrAnnotated(tree: Tree): Tree = tree match { + case ty @ Typed(expr1, tt @ TypeTree()) => + if (reifyDebug) println("reify typed: " + tree) + val annotatedArg = { + def loop(tree: Tree): Tree = tree match { + case annotated1 @ Annotated(ann, annotated2 @ Annotated(_, _)) => loop(annotated2) + case annotated1 @ Annotated(ann, arg) => arg + case _ => EmptyTree + } + + loop(tt.original) + } + if (annotatedArg != EmptyTree) { + if (annotatedArg.isType) { + if (reifyDebug) println("verdict: was an annotated type, reify as usual") + ty + } else { + if (reifyDebug) println("verdict: was an annotated value, equivalent is " + tt.original) + toPreTyperTypedOrAnnotated(tt.original) + } + } else { + if (reifyDebug) println("verdict: wasn't annotated, reify as usual") + ty + } + case at @ Annotated(annot, arg) => + if (reifyDebug) println("reify type annotations for: " + tree) + assert(at.tpe.isInstanceOf[AnnotatedType], "%s (%s)".format(at.tpe, at.tpe.kind)) + val annot1 = toPreTyperAnnotation(at.tpe.asInstanceOf[AnnotatedType].annotations(0)) + if (reifyDebug) println("originals are: " + annot1) + Annotated(annot1, arg).copyAttrs(at) + } + + /** Restore pre-typer representation of an annotation. + * The trick here is to retain the symbols that have been populated during typechecking of the annotation. + * If we do not do that, subsequent reflective compilation will fail. + */ + private def toPreTyperAnnotation(ann: AnnotationInfo): Tree = { + val args = if (ann.assocs.isEmpty) { + ann.args + } else { + def toScalaAnnotation(jann: ClassfileAnnotArg): Tree = jann match { + case LiteralAnnotArg(const) => + Literal(const) + case ArrayAnnotArg(arr) => + Apply(Ident(definitions.ArrayModule), arr.toList map toScalaAnnotation) + case NestedAnnotArg(ann) => + toPreTyperAnnotation(ann) + } + + ann.assocs map { case (nme, arg) => AssignOrNamedArg(Ident(nme), toScalaAnnotation(arg)) } + } + + def extractOriginal: PartialFunction[Tree, Tree] = { case Apply(Select(New(tpt), _), _) => tpt } + assert(extractOriginal.isDefinedAt(ann.original), showRaw(ann.original)) + New(TypeTree(ann.atp) setOriginal extractOriginal(ann.original), List(args)) + } + + // [Eugene] is this implemented correctly? + private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = { + val symdefs = stats collect { case vodef: ValOrDefDef => vodef } map (vodeff => vodeff.symbol -> vodeff) toMap + val accessors = collection.mutable.Map[ValDef, List[DefDef]]() + stats collect { case ddef: DefDef => ddef } foreach (defdef => { + val valdef = symdefs get defdef.symbol.accessedOrSelf collect { case vdef: ValDef => vdef } getOrElse null + if (valdef != null) accessors(valdef) = accessors.getOrElse(valdef, Nil) :+ defdef + + def detectBeanAccessors(prefix: String): Unit = { + if (defdef.name.startsWith(prefix)) { + var name = defdef.name.toString.substring(prefix.length) + def uncapitalize(s: String) = if (s.length == 0) "" else { val chars = s.toCharArray; chars(0) = chars(0).toLower; new String(chars) } + def findValDef(name: String) = symdefs.values collect { case vdef: ValDef if nme.dropLocalSuffix(vdef.name).toString == name => vdef } headOption; + val valdef = findValDef(name) orElse findValDef(uncapitalize(name)) orNull; + if (valdef != null) accessors(valdef) = accessors.getOrElse(valdef, Nil) :+ defdef + } + } + detectBeanAccessors("get") + detectBeanAccessors("set") + detectBeanAccessors("is") + }); + + var stats1 = stats flatMap { + case vdef @ ValDef(mods, name, tpt, rhs) => + val mods1 = if (accessors.contains(vdef)) { + val ddef = accessors(vdef)(0) // any accessor will do + val Modifiers(flags, privateWithin, annotations) = mods + var flags1 = flags & ~LOCAL + if (!ddef.symbol.isPrivate) flags1 = flags1 & ~PRIVATE + val privateWithin1 = ddef.mods.privateWithin + val annotations1 = accessors(vdef).foldLeft(annotations)((curr, acc) => curr ++ (acc.symbol.annotations map toPreTyperAnnotation)) + Modifiers(flags1, privateWithin1, annotations1) setPositions mods.positions + } else { + mods + } + val mods2 = toPreTyperModifiers(mods1, vdef.symbol) + val name1 = nme.dropLocalSuffix(name) + val vdef1 = ValDef(mods2, name1, tpt, rhs) + if (reifyDebug) println("resetting visibility of field: %s => %s".format(vdef, vdef1)) + Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are not out of sync + case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) => + if (accessors.values.exists(_.contains(ddef))) { + if (reifyDebug) println("discarding accessor method: " + ddef) + None + } else { + Some(ddef) + } + case tree => + Some(tree) + } + + stats1 + } + + private def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]): List[Tree] = + stats filterNot (memberDef => memberDef.isDef && { + val isSynthetic = memberDef.symbol.isSynthetic + // this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) + // that's why I replace the check with an assumption that all synthetic members are, in fact, generated of case classes + // val isCaseMember = deff.symbol.isCaseClass || deff.symbol.companionClass.isCaseClass + val isCaseMember = true + if (isSynthetic && isCaseMember && reifyDebug) println("discarding case class synthetic def: " + memberDef) + isSynthetic && isCaseMember + }) + + private def trimSyntheticCaseClassCompanions(stats: List[Tree]): List[Tree] = + stats diff (stats collect { case moddef: ModuleDef => moddef } filter (moddef => { + val isSynthetic = moddef.symbol.isSynthetic + // this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) + // that's why I replace the check with an assumption that all synthetic modules are, in fact, companions of case classes + // val isCaseCompanion = moddef.symbol.companionClass.isCaseClass + val isCaseCompanion = true + if (isSynthetic && isCaseCompanion && reifyDebug) println("discarding synthetic case class companion: " + moddef) + isSynthetic && isCaseCompanion + })) + } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/ClassLoaders.scala b/src/compiler/scala/reflect/runtime/ClassLoaders.scala new file mode 100644 index 0000000000..b73d57c04d --- /dev/null +++ b/src/compiler/scala/reflect/runtime/ClassLoaders.scala @@ -0,0 +1,25 @@ +package scala.reflect +package runtime + +trait ClassLoaders extends internal.SymbolTable { self: SymbolTable => + + def staticClass(fullname: String) = + definitions.getRequiredClass(fullname) + + def staticModule(fullname: String) = + definitions.getRequiredModule(fullname) + + /** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package + * ., otherwise return NoSymbol. + * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead. + */ + override def missingHook(owner: Symbol, name: Name): Symbol = + if (owner.isRoot && isJavaClass(name.toString)) + definitions.EmptyPackageClass.info decl name + else if (name.isTermName && owner.hasPackageFlag && !owner.isEmptyPackageClass) + makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule + else { + info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) + super.missingHook(owner, name) + } +} diff --git a/src/compiler/scala/reflect/runtime/ConversionUtil.scala b/src/compiler/scala/reflect/runtime/ConversionUtil.scala index 8c32026e37..e45fc243c6 100644 --- a/src/compiler/scala/reflect/runtime/ConversionUtil.scala +++ b/src/compiler/scala/reflect/runtime/ConversionUtil.scala @@ -12,6 +12,7 @@ trait ConversionUtil { self: SymbolTable => /** A cache that maintains a bijection between Java reflection type `J` * and Scala reflection type `S`. */ + // todo. should be weak protected class TwoWayCache[J, S] { private val toScalaMap = new HashMap[J, S] diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala index 89fd6bab64..6688d77985 100644 --- a/src/compiler/scala/reflect/runtime/JavaToScala.scala +++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala @@ -34,16 +34,42 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => val global: JavaToScala.this.type = self } - protected def defaultReflectiveClassLoader(): JClassLoader = { - val cl = Thread.currentThread.getContextClassLoader - if (cl == null) getClass.getClassLoader else cl - } + /** Defines the classloader that will be used for all class resolution activities in this mirror. + * Is mutable, since sometimes we need to change it in flight (e.g. to make the default mirror work with REPL). + * + * If you want to have a mirror with non-standard class resolution, override this var + * (or, even simpler, use the `mkMirror` function from `scala.reflect` package) + * + * Be careful, though, since fancy stuff might happen. + * Here's one example: + * + * partest uses a URLClassLoader(urls, null) with custom classpath to run workers (in separate threads) + * however it doesn't set the context classloader for them, so they inherit the system classloader + * http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html + * + * Once upon a time, scala.reflect.mirror was loaded using getClass.getClassLoader, + * which also means that classOf[...] constructs such as: + * + * classOf[scala.reflect.ScalaSignature] + * + * in unpickleClass were also loaded by the URLClassLoader + * + * But mirror's classLoader used Thread.currentThread.getContextClassLoader, + * which introduced a subtle bug that made the following snippet incorrectly: + * + * jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature]) + * + * Indeed, jclazz was loaded by context classloader, which defaulted to system classloader, + * while ScalaSignature class was loaded by getClass.getClassLoader, which was incompatible with system classloader. + * As a result, unpickler couldn't see the signature and that blew up the mirror. + */ + var classLoader: ClassLoader /** Paul: It seems the default class loader does not pick up root classes, whereas the system classloader does. * Can you check with your newly acquired classloader fu whether this implementation makes sense? */ def javaClass(path: String): jClass[_] = - javaClass(path, defaultReflectiveClassLoader()) + javaClass(path, classLoader) def javaClass(path: String, classLoader: JClassLoader): jClass[_] = Class.forName(path, true, classLoader) @@ -75,19 +101,70 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => (if (msg eq null) "reflection error while loading " + clazz.name else "error while loading " + clazz.name) + ", " + msg) } - try { - markAbsent(NoType) - val ssig = jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature]) + // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader + // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it) + // don't use structural types to simplify reflective invocations because of the same reason + // todo. test for this + def loadAnnotation(name: String): java.lang.annotation.Annotation = { + def inferClasspath(cl: ClassLoader) = cl match { + case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" + case _ => "" + } + def show(cl: ClassLoader) = cl match { + case cl if cl != null => + "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl)) + case null => + import scala.tools.util.PathResolver.Environment._ + "primordial classloader with boot classpath [%s]".format(javaBootClassPath) + } + + try { + val cls_ann = Class.forName(name, true, classLoader) + val anns = jclazz.getAnnotations + val ann = anns find (_.annotationType == cls_ann) orNull; + if (ann == null && anns.find(_.annotationType.getName == name).isDefined) { + val msg = "Mirror classloader mismatch: %s (loaded by %s)%nis unrelated to the mirror's classloader (%s)" + throw new Error(msg.format(jclazz, show(jclazz.getClassLoader), show(classLoader))) + } + ann + } catch { + case ex: ClassNotFoundException => + val msg = "Dysfunctional mirror classloader, cannot load %s: %s." + throw new Error(msg.format(name, show(classLoader)), ex) + } + } + def loadScalaSignature: Option[String] = { + val ssig = loadAnnotation("scala.reflect.ScalaSignature") if (ssig != null) { - info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner) - val bytes = ssig.bytes.getBytes - val len = ByteCodecs.decode(bytes) - unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName) + val bytesMethod = ssig.annotationType.getMethod("bytes") + val result = bytesMethod.invoke(ssig) + Some(result.asInstanceOf[String]) } else { - val slsig = jclazz.getAnnotation(classOf[scala.reflect.ScalaLongSignature]) - if (slsig != null) { + None + } + } + def loadScalaLongSignature: Option[Array[String]] = { + val slsig = loadAnnotation("scala.reflect.ScalaLongSignature") + if (slsig != null) { + val bytesMethod = slsig.annotationType.getMethod("bytes") + val result = bytesMethod.invoke(slsig) + Some(result.asInstanceOf[Array[String]]) + } else { + None + } + } + try { + markAbsent(NoType) + val sigs = (loadScalaSignature, loadScalaLongSignature) + sigs match { + case (Some(ssig), _) => + info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner) + val bytes = ssig.getBytes + val len = ByteCodecs.decode(bytes) + unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName) + case (_, Some(slsig)) => info("unpickling Scala "+clazz + " and " + module + " with long Scala signature") - val byteSegments = slsig.bytes map (_.getBytes) + val byteSegments = slsig map (_.getBytes) val lens = byteSegments map ByteCodecs.decode val bytes = Array.ofDim[Byte](lens.sum) var len = 0 @@ -96,10 +173,10 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => len += l } unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName) - } else { // class does not have a Scala signature; it's a Java class + case (None, None) => + // class does not have a Scala signature; it's a Java class info("translating reflection info for Java " + jclazz) //debug initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz)) - } } } catch { case ex: MissingRequirementError => @@ -383,52 +460,70 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => */ def classToScala(jclazz: jClass[_]): Symbol = classCache.toScala(jclazz) { val jname = javaTypeName(jclazz) - val owner = sOwner(jclazz) - val simpleName = scalaSimpleName(jclazz) - - val sym = { - def lookup = { - def coreLookup(name: Name): Symbol = { - val sym = owner.info.decl(name) - sym orElse { - if (name.startsWith(nme.NAME_JOIN_STRING)) - coreLookup(name.subName(1, name.length)) - else - NoSymbol + + val sym = + if (jname == fulltpnme.RuntimeNothing) + NothingClass + else if (jname == fulltpnme.RuntimeNull) + NullClass + else + { + val owner = sOwner(jclazz) + val simpleName = scalaSimpleName(jclazz) + + def lookup = { + def coreLookup(name: Name): Symbol = { + val sym = owner.info.decl(name) + sym orElse { + if (name.startsWith(nme.NAME_JOIN_STRING)) + coreLookup(name.subName(1, name.length)) + else + NoSymbol + } + } + + if (nme.isModuleName(simpleName)) { + val moduleName = nme.stripModuleSuffix(simpleName).toTermName + val sym = coreLookup(moduleName) + if (sym == NoSymbol) sym else sym.moduleClass + } else { + coreLookup(simpleName) } } - if (nme.isModuleName(simpleName)) { - val moduleName = nme.stripModuleSuffix(simpleName).toTermName - val sym = coreLookup(moduleName) - if (sym == NoSymbol) sym else sym.moduleClass - } else { - coreLookup(simpleName) + val sym = { + if (jclazz.isMemberClass && !nme.isImplClassName(jname)) { + lookup + } else if (jclazz.isLocalClass || invalidClassName(jname)) { + // local classes and implementation classes not preserved by unpickling - treat as Java + jclassAsScala(jclazz) + } else if (jclazz.isArray) { + ArrayClass + } else javaTypeToValueClass(jclazz) orElse { + // jclazz is top-level - get signature + lookup + // val (clazz, module) = createClassModule( + // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _)) + // classCache enter (jclazz, clazz) + // clazz + } } - } - if (jclazz.isMemberClass && !nme.isImplClassName(jname)) { - lookup - } else if (jclazz.isLocalClass || invalidClassName(jname)) { - // local classes and implementation classes not preserved by unpickling - treat as Java - jclassAsScala(jclazz) - } else if (jclazz.isArray) { - ArrayClass - } else javaTypeToValueClass(jclazz) orElse { - // jclazz is top-level - get signature - lookup - // val (clazz, module) = createClassModule( - // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _)) - // classCache enter (jclazz, clazz) - // clazz - } - } + if (!sym.isType) { + val classloader = jclazz.getClassLoader + println("classloader is: %s of type %s".format(classloader, classloader.getClass)) + def inferClasspath(cl: ClassLoader) = cl match { + case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" + case _ => "" + } + println("classpath is: %s".format(inferClasspath(classloader))) + def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName) + def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName) + assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType) + } - if (!sym.isType) { - def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName) - def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName) - assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType) - } + sym + } sym.asInstanceOf[ClassSymbol] } diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala deleted file mode 100644 index 4b35a5b37e..0000000000 --- a/src/compiler/scala/reflect/runtime/Loaders.scala +++ /dev/null @@ -1,130 +0,0 @@ -package scala.reflect -package runtime - -import internal.Flags -import java.lang.{Class => jClass, Package => jPackage} -import collection.mutable - -trait Loaders { self: SymbolTable => - - /** The lazy type for root. - */ - override val rootLoader = new LazyType { - override def complete(sym: Symbol) = sym setInfo new LazyPackageType - } - - /** The standard completer for top-level classes - * @param clazz The top-level class - * @param module The companion object of `clazz` - * Calling `complete` on this type will assign the infos of `clazz` and `module` - * by unpickling information from the corresponding Java class. If no Java class - * is found, a package is created instead. - */ - class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader { -// def makePackage() { -// println("wrong guess; making package "+clazz) -// val ptpe = newPackageType(module.moduleClass) -// for (sym <- List(clazz, module, module.moduleClass)) { -// sym setFlag Flags.PACKAGE -// sym setInfo ptpe -// } -// } - - override def complete(sym: Symbol) = { - debugInfo("completing "+sym+"/"+clazz.fullName) - assert(sym == clazz || sym == module || sym == module.moduleClass) -// try { - atPhaseNotLaterThan(picklerPhase) { - unpickleClass(clazz, module, javaClass(clazz.javaClassName)) -// } catch { -// case ex: ClassNotFoundException => makePackage() -// case ex: NoClassDefFoundError => makePackage() - // Note: We catch NoClassDefFoundError because there are situations - // where a package and a class have the same name except for capitalization. - // It seems in this case the class is loaded even if capitalization differs - // but then a NoClassDefFound error is issued with a ("wrong name: ...") - // reason. (I guess this is a concession to Windows). - // The present behavior is a bit too forgiving, in that it masks - // all class load errors, not just wrong name errors. We should try - // to be more discriminating. To get on the right track simply delete - // the clause above and load a collection class such as collection.Iterable. - // You'll see an error that class `parallel` has the wrong name. -// } - } - } - override def load(sym: Symbol) = complete(sym) - } - - /** Create a class and a companion object, enter in enclosing scope, - * and initialize with a lazy type completer. - * @param owner The owner of the newly created class and object - * @param name The simple name of the newly created class - * @param completer The completer to be used to set the info of the class and the module - */ - protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { - assert(!(name.toString endsWith "[]"), name) - val clazz = owner.newClass(name) - val module = owner.newModule(name.toTermName) - owner.info.decls enter clazz - owner.info.decls enter module - initClassModule(clazz, module, completer(clazz, module)) - (clazz, module) - } - - protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = { - List(clazz, module, module.moduleClass) foreach (_ setInfo info) - } - - protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = - setAllInfos(clazz, module, completer) - - /** The type completer for packages. - */ - class LazyPackageType extends LazyType { - override def complete(sym: Symbol) { - assert(sym.isPackageClass) - sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym) - // override def safeToString = pkgClass.toString - openPackageModule(sym) - } - } - - /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because - * these are nested classes or anonymous classes, - */ - def invalidClassName(name: Name) = { - val dp = name pos '$' - 0 < dp && dp < (name.length - 1) - } - - class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { - assert(pkgClass.isType) - private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. - override def lookupEntry(name: Name): ScopeEntry = { - val e = super.lookupEntry(name) - if (e != null) - e - else if (invalidClassName(name) || (negatives contains name)) - null - else { - val path = - if (pkgClass.isEmptyPackageClass) name.toString - else pkgClass.fullName + "." + name - if (isJavaClass(path)) { - val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) - debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass) - lookupEntry(name) - } else { - debugInfo("*** not found : "+path) - negatives += name - null - } - } - } - } - - override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass) - - override def scopeTransform(owner: Symbol)(op: => Scope): Scope = - if (owner.isPackageClass) owner.info.decls else op -} diff --git a/src/compiler/scala/reflect/runtime/Memoizer.scala b/src/compiler/scala/reflect/runtime/Memoizer.scala deleted file mode 100644 index 4c1b82ae6d..0000000000 --- a/src/compiler/scala/reflect/runtime/Memoizer.scala +++ /dev/null @@ -1,15 +0,0 @@ -package scala.reflect.runtime - -import collection.mutable.ArrayBuffer -import Mirror.Type - -/** Class that can be used for memoizing types in reified trees */ -class Memoizer { - private val mem = new ArrayBuffer[Mirror.Type] - def get(n: Int): Type = mem(n) - def add(n: Int, tpe: Type): Type = { - while (mem.length <= n) mem += null - mem(n) = tpe - tpe - } -} diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala index d3e4dd7619..20024ed058 100644 --- a/src/compiler/scala/reflect/runtime/Mirror.scala +++ b/src/compiler/scala/reflect/runtime/Mirror.scala @@ -1,24 +1,24 @@ package scala.reflect package runtime -import internal.{SomePhase, NoPhase, Phase, TreeGen} import java.lang.reflect.Array +import ReflectionUtils._ +import scala.tools.nsc.util.ScalaClassLoader._ /** The mirror for standard runtime reflection from Java. */ -class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxes with api.Mirror { +class Mirror(var classLoader: ClassLoader) extends Universe with api.Mirror { definitions.init() - import definitions._ def symbolForName(name: String): Symbol = { - val clazz = javaClass(name, defaultReflectiveClassLoader()) + val clazz = javaClass(name, classLoader) classToScala(clazz) } def companionInstance(clazz: Symbol): AnyRef = { - val singleton = ReflectionUtils.singletonInstance(clazz.fullName, defaultReflectiveClassLoader()) + val singleton = singletonInstance(classLoader, clazz.fullName) singleton } @@ -46,17 +46,31 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*) } - override def classToType(jclazz: java.lang.Class[_]): Type = typeToScala(jclazz) - override def classToSymbol(jclazz: java.lang.Class[_]): Symbol = classToScala(jclazz) + private def validateIncomingClassLoader(wannabeCl: ClassLoader) = { + val ourCls = loaderChain(classLoader) + if (wannabeCl != null && !(ourCls contains wannabeCl)) + throw new Error("class doesn't belong to the classloader chain of the mirror") + } + + def classToType(jclazz: java.lang.Class[_]): Type = { + validateIncomingClassLoader(jclazz.getClassLoader) + typeToScala(jclazz) + } + + def classToSymbol(jclazz: java.lang.Class[_]): Symbol = { + validateIncomingClassLoader(jclazz.getClassLoader) + classToScala(jclazz) + } + + def typeToClass(tpe: Type): java.lang.Class[_] = + typeToJavaClass(tpe) - override def typeToClass(tpe: Type): java.lang.Class[_] = typeToJavaClass(tpe) - override def symbolToClass(sym: Symbol): java.lang.Class[_] = classToJava(sym) + def symbolToClass(sym: Symbol): java.lang.Class[_] = + classToJava(sym) override def inReflexiveMirror = true } -object Mirror extends Mirror - /** test code; should go to tests once things settle down a bit * diff --git a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala b/src/compiler/scala/reflect/runtime/RuntimeTypes.scala deleted file mode 100644 index 84d02ab7a0..0000000000 --- a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala +++ /dev/null @@ -1,27 +0,0 @@ -package scala.reflect -package runtime - -import collection.mutable.ListBuffer - -trait RuntimeTypes extends Universe with api.RuntimeTypes { - - /** To lift path dependent types into reflection, we use InstanceRefSymbols. - * Two of these are equal if they point to the same object reference. Todo: remove - */ - case class InstanceRefSymbol(value: AnyRef) extends TermSymbol(NoSymbol, NoPosition, nme.EMPTY) - object InstanceRefSymbol extends InstanceRefSymbolExtractor - - override private[reflect] def namedType(pre: Type, sym: Symbol, args: List[Type]): Type = { - val tparamBuf = new ListBuffer[Symbol] - val args1 = for (arg <- args) yield arg match { - case _: TypeBounds => - val ex = pre.typeSymbol.freshExistential("$ex") setInfo arg - tparamBuf += ex - TypeRef(NoPrefix, ex, List()) - case _ => - arg - } - existentialAbstraction(tparamBuf.toList, typeRef(pre, sym, args1)) - } - -} \ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala new file mode 100644 index 0000000000..7c1cc16152 --- /dev/null +++ b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala @@ -0,0 +1,135 @@ +package scala.reflect +package runtime + +import internal.Flags +import java.lang.{Class => jClass, Package => jPackage} +import collection.mutable + +trait SymbolLoaders { self: SymbolTable => + + /** The lazy type for root. + */ + override val rootLoader = new LazyType { + override def complete(sym: Symbol) = sym setInfo new LazyPackageType + } + + /** The standard completer for top-level classes + * @param clazz The top-level class + * @param module The companion object of `clazz` + * Calling `complete` on this type will assign the infos of `clazz` and `module` + * by unpickling information from the corresponding Java class. If no Java class + * is found, a package is created instead. + */ + class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader { +// def makePackage() { +// println("wrong guess; making package "+clazz) +// val ptpe = newPackageType(module.moduleClass) +// for (sym <- List(clazz, module, module.moduleClass)) { +// sym setFlag Flags.PACKAGE +// sym setInfo ptpe +// } +// } + + override def complete(sym: Symbol) = { + debugInfo("completing "+sym+"/"+clazz.fullName) + assert(sym == clazz || sym == module || sym == module.moduleClass) +// try { + atPhaseNotLaterThan(picklerPhase) { + unpickleClass(clazz, module, javaClass(clazz.javaClassName)) +// } catch { +// case ex: ClassNotFoundException => makePackage() +// case ex: NoClassDefFoundError => makePackage() + // Note: We catch NoClassDefFoundError because there are situations + // where a package and a class have the same name except for capitalization. + // It seems in this case the class is loaded even if capitalization differs + // but then a NoClassDefFound error is issued with a ("wrong name: ...") + // reason. (I guess this is a concession to Windows). + // The present behavior is a bit too forgiving, in that it masks + // all class load errors, not just wrong name errors. We should try + // to be more discriminating. To get on the right track simply delete + // the clause above and load a collection class such as collection.Iterable. + // You'll see an error that class `parallel` has the wrong name. +// } + } + } + override def load(sym: Symbol) = complete(sym) + } + + /** Create a class and a companion object, enter in enclosing scope, + * and initialize with a lazy type completer. + * @param owner The owner of the newly created class and object + * @param name The simple name of the newly created class + * @param completer The completer to be used to set the info of the class and the module + */ + protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { + assert(!(name.toString endsWith "[]"), name) + val clazz = owner.newClass(name) + val module = owner.newModule(name.toTermName) + owner.info.decls enter clazz + owner.info.decls enter module + initClassModule(clazz, module, completer(clazz, module)) + (clazz, module) + } + + protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = { + List(clazz, module, module.moduleClass) foreach (_ setInfo info) + } + + protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = + setAllInfos(clazz, module, completer) + + /** The type completer for packages. + */ + class LazyPackageType extends LazyType { + override def complete(sym: Symbol) { + assert(sym.isPackageClass) + sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym) + // override def safeToString = pkgClass.toString + openPackageModule(sym) + } + } + + /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because + * these are nested classes or anonymous classes, + */ + def invalidClassName(name: Name) = { + val dp = name pos '$' + 0 < dp && dp < (name.length - 1) + } + + class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { + assert(pkgClass.isType) + private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. + override def lookupEntry(name: Name): ScopeEntry = { + val e = super.lookupEntry(name) + if (e != null) + e + else if (invalidClassName(name) || (negatives contains name)) + null + else { + val path = + if (pkgClass.isEmptyPackageClass) name.toString + else pkgClass.fullName + "." + name + if (isJavaClass(path)) { + val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) + debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass) + lookupEntry(name) + } else { + debugInfo("*** not found : "+path) + negatives += name + null + } + } + } + } + + /** Assert that packages have package scopes */ + override def validateClassInfo(tp: ClassInfoType) { + assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope]) + } + + override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass) + + override def scopeTransform(owner: Symbol)(op: => Scope): Scope = + if (owner.isPackageClass) owner.info.decls else op +} diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala index 5331f0a53e..64a5894d01 100644 --- a/src/compiler/scala/reflect/runtime/SymbolTable.scala +++ b/src/compiler/scala/reflect/runtime/SymbolTable.scala @@ -3,29 +3,10 @@ package runtime /** * This symbol table trait fills in the definitions so that class information is obtained by refection. - * It can be used either from the reflexive mirror itself (class Universe), or else from + * It can be used either from the reflexive mirror itself (class Mirror), or else from * a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal) */ -trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with Loaders with SynchronizedOps { - - /** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package - * ., otherwise return NoSymbol. - * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead. - */ - override def missingHook(owner: Symbol, name: Name): Symbol = - if (owner.isRoot && isJavaClass(name.toString)) - definitions.EmptyPackageClass.info decl name - else if (name.isTermName && owner.hasPackageFlag && !owner.isEmptyPackageClass) - makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule - else { - info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) - super.missingHook(owner, name) - } - - /** Assert that packages have package scopes */ - override def validateClassInfo(tp: ClassInfoType) { - assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope]) - } +trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with ClassLoaders with SymbolLoaders with SynchronizedOps { def info(msg: => String) = if (settings.verbose.value) println("[reflect-compiler] "+msg) diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala index 5ae4ec15ee..6fc5f7ed8a 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala @@ -14,8 +14,11 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = synchronized { super.connectModuleToClass(m, moduleClass) } - override def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar = - new FreeVar(name, value) with SynchronizedTermSymbol initFlags newFlags setInfo tpe + override def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeTerm = + new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags newFlags setInfo info + + override def newFreeType(name: TypeName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeType = + new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags newFlags setInfo info override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index 28f12b378f..6d832a590f 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -1,28 +1,30 @@ package scala.reflect package runtime -import scala.tools.nsc -import scala.tools.nsc.reporters.Reporter -import scala.tools.nsc.reporters.StoreReporter -import scala.tools.nsc.reporters.AbstractReporter +import scala.tools.nsc.reporters._ import scala.tools.nsc.ReflectGlobal import scala.tools.nsc.CompilerCommand import scala.tools.nsc.Global import scala.tools.nsc.typechecker.Modes import scala.tools.nsc.io.VirtualDirectory import scala.tools.nsc.interpreter.AbstractFileClassLoader -import reflect.{mirror => rm} import scala.tools.nsc.util.FreshNameCreator import scala.reflect.internal.Flags import scala.tools.nsc.util.{NoSourceFile, NoFile} import java.lang.{Class => jClass} -import scala.tools.nsc.util.trace +import scala.compat.Platform.EOL trait ToolBoxes extends { self: Universe => - class ToolBox(val reporter: Reporter = new StoreReporter, val options: String = "") { + import self.{Reporter => ApiReporter} + import scala.tools.nsc.reporters.{Reporter => NscReporter} - class ToolBoxGlobal(settings0: nsc.Settings, reporter0: nsc.reporters.Reporter) extends ReflectGlobal(settings0, reporter0) { + def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options) + + class ToolBox(val reporter: ApiReporter, val options: String) extends AbsToolBox { + + class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: NscReporter) + extends ReflectGlobal(settings, reporter, ToolBox.this.classLoader) { import definitions._ private val trace = scala.tools.nsc.util.trace when settings.debug.value @@ -36,64 +38,7 @@ trait ToolBoxes extends { self: Universe => newTermName("__wrapper$" + wrapCount) } - private def moduleFileName(className: String) = className + "$" - - private def isFree(t: Tree) = t.isInstanceOf[Ident] && t.symbol.isInstanceOf[FreeVar] - - def typedTopLevelExpr(tree: Tree, pt: Type): Tree = { - // !!! Why is this is in the empty package? If it's only to make - // it inaccessible then please put it somewhere designed for that - // rather than polluting the empty package with synthetics. - trace("typing: ")(showAttributed(tree, true, true, settings.Yshowsymkinds.value)) - val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName(""), List(ObjectClass.tpe), newScope) - val owner = ownerClass.newLocalDummy(tree.pos) - val ttree = typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt) - trace("typed: ")(showAttributed(ttree, true, true, settings.Yshowsymkinds.value)) - ttree - } - - def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match { - case Some(sym) if sym != null && sym != NoSymbol => sym.owner - case _ => NoSymbol - } - - def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = { - val obj = EmptyPackageClass.newModule(nextWrapperModuleName()) - val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass) - obj.moduleClass setInfo minfo - obj setInfo obj.moduleClass.tpe - val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName)) - def makeParam(fv: Symbol) = meth.newValueParameter(fv.name.toTermName) setInfo fv.tpe - meth setInfo MethodType(fvs map makeParam, AnyClass.tpe) - minfo.decls enter meth - trace("wrapping ")(defOwner(expr) -> meth) - val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth)) - val moduledef = ModuleDef( - obj, - Template( - List(TypeTree(ObjectClass.tpe)), - emptyValDef, - NoMods, - List(), - List(List()), - List(methdef), - NoPosition)) - trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value)) - val cleanedUp = resetLocalAttrs(moduledef) - trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value)) - cleanedUp - } - - def wrapInPackage(clazz: Tree): PackageDef = - PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(clazz)) - - def wrapInCompilationUnit(tree: Tree): CompilationUnit = { - val unit = new CompilationUnit(NoSourceFile) - unit.body = tree - unit - } - - def compileExpr(expr: Tree, fvs: List[Symbol]): String = { + def verifyExpr(expr: Tree): Unit = { // Previously toolboxes used to typecheck their inputs before compiling. // Actually, the initial demo by Martin first typechecked the reified tree, // then ran it, which typechecked it again, and only then launched the @@ -104,44 +49,190 @@ trait ToolBoxes extends { self: Universe => // That's why we cannot allow inputs of toolboxes to be typechecked, // at least not until the aforementioned issue is closed. val typed = expr filter (t => t.tpe != null && t.tpe != NoType && !t.isInstanceOf[TypeTree]) - if (!typed.isEmpty) { - throw new Error("cannot compile trees that are already typed") + if (!typed.isEmpty) throw new ToolBoxError(ToolBox.this, "reflective toolbox has failed: cannot operate on trees that are already typed") + + val freeTypes = this.freeTypes(expr) + if (freeTypes.length > 0) { + var msg = "reflective toolbox has failed:" + EOL + msg += "unresolved free type variables (namely: " + (freeTypes map (ft => "%s %s".format(ft.name, ft.origin)) mkString ", ") + "). " + msg += "have you forgot to use TypeTag annotations for type parameters external to a reifee? " + msg += "if you have troubles tracking free type variables, consider using -Xlog-free-types" + throw new ToolBoxError(ToolBox.this, msg) } + } - val mdef = wrapInObject(expr, fvs) - val pdef = wrapInPackage(mdef) - val unit = wrapInCompilationUnit(pdef) - val run = new Run - run.compileUnits(List(unit), run.namerPhase) - mdef.symbol.fullName + def typeCheckExpr(expr0: Tree, pt: Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + verifyExpr(expr0) + + // need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars + // [Eugene] get rid of the copy/paste w.r.t compileExpr + val freeTerms = this.freeTerms(expr0) + val freeTermNames = collection.mutable.Map[Symbol, TermName]() + freeTerms foreach (ft => { + var name = ft.name.toString + val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name) + if (namesakes.length > 0) name += ("$" + (namesakes.length + 1)) + freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX)) + }) + var expr = new Transformer { + override def transform(tree: Tree): Tree = + if (tree.hasSymbol && tree.symbol.isFreeTerm) { + tree match { + case Ident(_) => + Ident(freeTermNames(tree.symbol)) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + } else { + super.transform(tree) + } + }.transform(expr0) + val dummies = freeTerms map (freeTerm => ValDef(NoMods, freeTermNames(freeTerm), TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark")))) + expr = Block(dummies, expr) + + // [Eugene] how can we implement that? + // !!! Why is this is in the empty package? If it's only to make + // it inaccessible then please put it somewhere designed for that + // rather than polluting the empty package with synthetics. + val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName(""), List(ObjectClass.tpe), newScope) + val owner = ownerClass.newLocalDummy(expr.pos) + var currentTyper = typer.atOwner(expr, owner) + val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _) + def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) + + phase = (new Run).typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled + currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions + reporter.reset() + + trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) + wrapper(currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match { + case analyzer.SilentResultValue(result) => + trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) + var Block(dummies, unwrapped) = result + var reversedFreeTermNames = freeTermNames map (_.swap) + // todo. also fixup singleton types + unwrapped = new Transformer { + override def transform(tree: Tree): Tree = + tree match { + case Ident(name) if reversedFreeTermNames contains name => + Ident(reversedFreeTermNames(name)) + case _ => + super.transform(tree) + } + }.transform(unwrapped) + new TreeTypeSubstituter(dummies map (_.symbol), dummies map (dummy => SingleType(NoPrefix, reversedFreeTermNames(dummy.symbol.name)))).traverse(unwrapped) + unwrapped + case error @ analyzer.SilentTypeError(_) => + trace("failed: ")(error.err.errMsg) + if (!silent) throw new ToolBoxError(ToolBox.this, "reflective typecheck has failed: %s".format(error.err.errMsg)) + EmptyTree + }) } - private def getMethod(jclazz: jClass[_], name: String) = - jclazz.getDeclaredMethods.find(_.getName == name).get + def compileExpr(expr: Tree): (Object, java.lang.reflect.Method) = { + verifyExpr(expr) + + def wrapExpr(expr0: Tree): Tree = { + def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match { + case Some(sym) if sym != null && sym != NoSymbol => sym.owner + case _ => NoSymbol + } + + val freeTerms = this.freeTerms(expr0) + val freeTermNames = collection.mutable.Map[Symbol, TermName]() + freeTerms foreach (ft => { + var name = ft.name.toString + val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name) + if (namesakes.length > 0) name += ("$" + (namesakes.length + 1)) + freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX)) + }) + val expr = new Transformer { + override def transform(tree: Tree): Tree = + if (tree.hasSymbol && tree.symbol.isFreeTerm) { + tree match { + case Ident(_) => + Apply(Ident(freeTermNames(tree.symbol)), List()) + case _ => + throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) + } + } else { + super.transform(tree) + } + }.transform(expr0) + + val obj = EmptyPackageClass.newModule(nextWrapperModuleName()) + val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass) + obj.moduleClass setInfo minfo + obj setInfo obj.moduleClass.tpe + val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName)) + def makeParam(fv: Symbol) = { + // [Eugene] conventional way of doing this? + val underlying = fv.tpe.resultType + val tpe = appliedType(definitions.FunctionClass(0).tpe, List(underlying)) + meth.newValueParameter(freeTermNames(fv)) setInfo tpe + } + meth setInfo MethodType(freeTerms map makeParam, AnyClass.tpe) + minfo.decls enter meth + trace("wrapping ")(defOwner(expr) -> meth) + val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth)) + val moduledef = ModuleDef( + obj, + Template( + List(TypeTree(ObjectClass.tpe)), + emptyValDef, + NoMods, + List(), + List(List()), + List(methdef), + NoPosition)) + trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value)) + var cleanedUp = resetLocalAttrs(moduledef) + trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value)) + cleanedUp + } - def runExpr(expr: Tree): Any = { - val fvs = (expr filter isFree map (_.symbol)).distinct + val mdef = wrapExpr(expr) + val pdef = PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(mdef)) + val unit = new CompilationUnit(NoSourceFile) + unit.body = pdef + val run = new Run reporter.reset() - val className = compileExpr(expr, fvs) + run.compileUnits(List(unit), run.namerPhase) if (reporter.hasErrors) { - throw new Error("reflective compilation has failed") + var msg = "reflective compilation has failed: " + EOL + EOL + msg += ToolBox.this.reporter.infos map (_.msg) mkString EOL + throw new ToolBoxError(ToolBox.this, msg) } + val className = mdef.symbol.fullName if (settings.debug.value) println("generated: "+className) + def moduleFileName(className: String) = className + "$" val jclazz = jClass.forName(moduleFileName(className), true, classLoader) val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get val jfield = jclazz.getDeclaredFields.find(_.getName == NameTransformer.MODULE_INSTANCE_NAME).get val singleton = jfield.get(null) + (singleton, jmeth) + } + + def runExpr(expr: Tree, freeTypes: Map[TypeName, Type] = Map[TypeName, Type]()): Any = { + val freeTerms = this.freeTerms(expr) // need to calculate them here, because later on they will be erased + val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order + // @odersky writes: Not sure we will be able to drop this. I forgot the reason why we dereference () functions, // but there must have been one. So I propose to leave old version in comments to be resurrected if the problem resurfaces. -// val result = jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*) + // @Eugene writes: this dates back to the days when one could only reify functions + // hence, blocks were translated into nullary functions, so + // presumably, it was useful to immediately evaluate them to get the result of a block +// val result = jmeth.invoke(singleton, freeTerms map (sym => sym.asInstanceOf[FreeTermVar].value.asInstanceOf[AnyRef]): _*) // if (etpe.typeSymbol != FunctionClass(0)) result // else { // val applyMeth = result.getClass.getMethod("apply") // applyMeth.invoke(result) // } - jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*) + val (singleton, jmeth) = compileExpr(expr) + jmeth.invoke(singleton, thunks map (_.asInstanceOf[AnyRef]): _*) } def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = { @@ -161,6 +252,7 @@ trait ToolBoxes extends { self: Universe => } } + // todo. is not going to work with quoted arguments with embedded whitespaces lazy val arguments = options.split(" ") lazy val virtualDirectory = @@ -170,49 +262,96 @@ trait ToolBoxes extends { self: Universe => } lazy val compiler: ToolBoxGlobal = { - val errorFn: String => Unit = reporter.error(scala.tools.nsc.util.NoPosition, _) - val command = reporter match { - case reporter: AbstractReporter => new CompilerCommand(arguments.toList, reporter.settings, errorFn) - case _ => new CompilerCommand(arguments.toList, errorFn) + try { + val errorFn: String => Unit = msg => reporter.log(NoPosition, msg, reporter.ERROR) + // [Eugene] settings shouldn't be passed via reporters, this is crazy +// val command = reporter match { +// case reporter: AbstractReporter => new CompilerCommand(arguments.toList, reporter.settings, errorFn) +// case _ => new CompilerCommand(arguments.toList, errorFn) +// } + val command = new CompilerCommand(arguments.toList, errorFn) + command.settings.outputDirs setSingleOutput virtualDirectory + val nscReporter = new ApiToNscReporterProxy(reporter) { val settings = command.settings } + val instance = new ToolBoxGlobal(command.settings, nscReporter) + if (nscReporter.hasErrors) { + var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL + msg += reporter.infos map (_.msg) mkString EOL + throw new ToolBoxError(this, msg) + } + instance.phase = (new instance.Run).typerPhase // need to manually set a phase, because otherwise TypeHistory will crash + instance + } catch { + case ex: Throwable => + var msg = "reflective compilation has failed: cannot initialize the compiler due to %s".format(ex.toString) + throw new ToolBoxError(this, msg, ex) } - - command.settings.outputDirs setSingleOutput virtualDirectory - val instance = new ToolBoxGlobal(command.settings, reporter) - - // need to establish a run an phase because otherwise we run into an assertion in TypeHistory - // that states that the period must be different from NoPeriod - val run = new instance.Run - instance.phase = run.refchecksPhase - instance } - lazy val importer = new compiler.Importer { - val from: self.type = self - } + // @Eugene: how do I make this work without casts? + // lazy val importer = compiler.mkImporter(self) + lazy val importer = compiler.mkImporter(self).asInstanceOf[compiler.Importer { val from: self.type }] lazy val exporter = importer.reverse - lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, defaultReflectiveClassLoader) + lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, self.classLoader) - def typeCheck(tree: rm.Tree, expectedType: rm.Type): rm.Tree = { - if (compiler.settings.verbose.value) println("typing "+tree+", pt = "+expectedType) - val ctree: compiler.Tree = importer.importTree(tree.asInstanceOf[Tree]) - val pt: compiler.Type = importer.importType(expectedType.asInstanceOf[Type]) - val ttree: compiler.Tree = compiler.typedTopLevelExpr(ctree, pt) - val rmttree = exporter.importTree(ttree).asInstanceOf[rm.Tree] + def typeCheck(tree: Tree, expectedType: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + if (compiler.settings.verbose.value) println("typing "+tree+", expectedType = "+expectedType+", freeTypes = "+freeTypes) + var ctree: compiler.Tree = importer.importTree(tree) + var cexpectedType: compiler.Type = importer.importType(expectedType) + + if (compiler.settings.verbose.value) println("substituting "+ctree+", expectedType = "+expectedType) + val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) } + ctree = compiler.substituteFreeTypes(ctree, cfreeTypes) + cexpectedType = compiler.substituteFreeTypes(cexpectedType, cfreeTypes) + + if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType) + val ttree: compiler.Tree = compiler.typeCheckExpr(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) + val rmttree = exporter.importTree(ttree) rmttree } - def typeCheck(tree: rm.Tree): rm.Tree = - typeCheck(tree, WildcardType.asInstanceOf[rm.Type]) + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree = + // todo. implement this + ??? + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree = + // todo. implement this + ??? + + def resetAllAttrs[T <: Tree](tree: T): T = { + val ctree: compiler.Tree = importer.importTree(tree) + val ttree: compiler.Tree = compiler.resetAllAttrs(ctree) + val rmttree = exporter.importTree(ttree) + rmttree.asInstanceOf[T] + } + + def resetLocalAttrs[T <: Tree](tree: T): T = { + val ctree: compiler.Tree = importer.importTree(tree) + val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree) + val rmttree = exporter.importTree(ttree) + rmttree.asInstanceOf[T] + } + + def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = + compiler.showAttributed(importer.importTree(tree), printTypes, printIds, printKinds) + + def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = { + if (compiler.settings.verbose.value) println("running "+tree+", freeTypes = "+freeTypes) + var ctree: compiler.Tree = importer.importTree(tree) - def showAttributed(tree: rm.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = - compiler.showAttributed(importer.importTree(tree.asInstanceOf[Tree]), printTypes, printIds, printKinds) + if (compiler.settings.verbose.value) println("substituting "+ctree) + val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) } + ctree = compiler.substituteFreeTypes(ctree, cfreeTypes) - def runExpr(tree: rm.Tree): Any = { - if (compiler.settings.verbose.value) println("running "+tree) - val ctree: compiler.Tree = importer.importTree(tree.asInstanceOf[Tree]) + if (compiler.settings.verbose.value) println("running "+ctree) compiler.runExpr(ctree) } + + class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause) + + object ToolBoxError extends ToolBoxErrorExtractor { + def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message)) + } } } diff --git a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala deleted file mode 100644 index 61001a4778..0000000000 --- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala +++ /dev/null @@ -1,49 +0,0 @@ -package scala.reflect -package runtime - -trait TreeBuildUtil extends Universe with api.TreeBuildUtil { - /** A comment to the effect of why initialize was added to all these - * would be appreciated. (We may as well start somewhere.) - */ - def staticClass(fullname: String) = definitions.getRequiredClass(fullname).initialize - def staticModule(fullname: String) = definitions.getRequiredModule(fullname).initialize - def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.initialize.thisType - - /** Selects type symbol with given name from the defined members of prefix type - */ - def selectType(owner: Symbol, name: String): Symbol = - owner.info.decl(newTypeName(name)) - - /** Selects term symbol with given name and type from the defined members of prefix type - * @pre The prefix type - * @name The name of the selected member - */ - def selectTerm(owner: Symbol, name: String): Symbol = { - val sym = owner.info.decl(newTermName(name)) - if (sym.isOverloaded) sym suchThat (!_.isMethod) - else sym - } - - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol = - owner.info.decl(newTermName(name)).alternatives(index) - - def selectParam(owner: Symbol, idx: Int): Symbol = { - def selectInList(params: List[Symbol], idx: Int, fallback: Type): Symbol = { - if (params.isEmpty) selectIn(fallback, idx) - else if (idx == 0) params.head - else selectInList(params.tail, idx - 1, fallback) - } - def selectIn(tpe: Type, idx: Int): Symbol = tpe match { - case PolyType(tparams, res) => selectInList(tparams, idx, res) - case MethodType(params, res) => selectInList(params, idx, res) - case _ => NoSymbol - } - selectIn(owner.info, idx) - } - - def newFreeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value) - - def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers = - Modifiers(flags, privateWithin, annotations) - -} \ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala index dca6d6041b..fd53308d0a 100644 --- a/src/compiler/scala/reflect/runtime/Universe.scala +++ b/src/compiler/scala/reflect/runtime/Universe.scala @@ -8,12 +8,14 @@ import internal.{SomePhase, NoPhase, Phase, TreeGen} * It also provides methods to go from Java members to Scala members, * using the code in JavaConversions. */ -class Universe extends SymbolTable { +abstract class Universe extends SymbolTable with ToolBoxes { type AbstractFileType = AbstractFile def picklerPhase = SomePhase + type TreeGen = internal.TreeGen + val gen = new TreeGen { val global: Universe.this.type = Universe.this } lazy val settings = new Settings @@ -30,24 +32,12 @@ class Universe extends SymbolTable { def newStrictTreeCopier: TreeCopier = new StrictTreeCopier def newLazyTreeCopier: TreeCopier = new LazyTreeCopier - def focusPos(pos: Position) = pos - def isRangePos(pos: Position) = false - def showPos(pos: Position) = "" - - type Position = String // source file? - val NoPosition = "" - definitions.AnyValClass // force it. - type TreeAnnotation = Position - def NoTreeAnnotation: TreeAnnotation = NoPosition - def positionToAnnotation(pos: Position): TreeAnnotation = pos // TODO - def annotationToPosition(annot: TreeAnnotation): Position = annot //TODO - // establish root association to avoid cyclic dependency errors later - classToScala(classOf[java.lang.Object]).initialize + // don't use classOf[...] here, because it gets serviced by getClass.getClassLoader! + classToScala(Class.forName("java.lang.Object", true, classLoader)).initialize // println("initializing definitions") definitions.init() - } diff --git a/src/compiler/scala/reflect/runtime/package.scala b/src/compiler/scala/reflect/runtime/package.scala new file mode 100644 index 0000000000..52ab2c5deb --- /dev/null +++ b/src/compiler/scala/reflect/runtime/package.scala @@ -0,0 +1,5 @@ +package scala.reflect + +package object runtime { + def mkMirror(classLoader: ClassLoader): api.Mirror = new Mirror(classLoader) +} \ No newline at end of file diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala index 3792c26c34..9592e7a716 100644 --- a/src/compiler/scala/tools/cmd/FromString.scala +++ b/src/compiler/scala/tools/cmd/FromString.scala @@ -7,14 +7,14 @@ package scala.tools package cmd import nsc.io.{ Path, File, Directory } -import scala.reflect.OptManifest +import scala.reflect.Manifest /** A general mechanism for defining how a command line argument * (always a String) is transformed into an arbitrary type. A few * example instances are in the companion object, but in general * either IntFromString will suffice or you'll want custom transformers. */ -abstract class FromString[+T](implicit m: OptManifest[T]) extends PartialFunction[String, T] { +abstract class FromString[+T](implicit m: Manifest[T]) extends PartialFunction[String, T] { def apply(s: String): T def isDefinedAt(s: String): Boolean = true def zero: T = apply("") diff --git a/src/compiler/scala/tools/nsc/ClassLoaders.scala b/src/compiler/scala/tools/nsc/ClassLoaders.scala new file mode 100644 index 0000000000..4058ee9324 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ClassLoaders.scala @@ -0,0 +1,64 @@ +package scala.tools.nsc + +import util.ScalaClassLoader + +trait ClassLoaders { self: Global => + + def staticClass(fullname: String) = { + if (self.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + getClass(newTypeName(fullname)) + } + + def staticModule(fullname: String) = { + if (self.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + getModule(newTermName(fullname)) + } + + private def getClass(fullname: Name): Symbol = { + var result = getModuleOrClass(fullname.toTypeName) + while (result.isAliasType) result = result.info.typeSymbol + result + } + + private def getModule(fullname: Name): Symbol = + getModuleOrClass(fullname.toTermName) + + private def getModuleOrClass(path: Name): Symbol = + getModuleOrClass(path, path.length) + + private def getModuleOrClass(path: Name, len: Int): Symbol = { + val point = path lastPos('.', len - 1) + val owner = + if (point > 0) getModuleOrClass(path.toTermName, point) + else definitions.RootClass + val name = path subName (point + 1, len) + val sym = owner.info member name + val result = if (path.isTermName) sym.suchThat(_ hasFlag symtab.Flags.MODULE) else sym + if (result != NoSymbol) result + else { + if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug + if (owner.isRoot && isJavaClass(name.toString)) + definitions.EmptyPackageClass.info decl name + else { + def info(msg: => String) = if (settings.verbose.value) println(msg) + info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) + MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path) + } + } + } + + private def isJavaClass(path: String): Boolean = + try { + val classpath = platform.classPath.asURLs + var classLoader = ScalaClassLoader.fromURLs(classpath) + Class.forName(path, true, classLoader) + true + } catch { + case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) => + false + } +} diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 5e0c24d304..b7d7f5d16f 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -12,7 +12,7 @@ import compat.Platform.currentTime import scala.tools.util.{ Profiling, PathResolver } import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } -import reporters.{ Reporter, ConsoleReporter } +import reporters.{ Reporter => NscReporter, ConsoleReporter } import util.{ NoPosition, Exceptional, ClassPath, SourceFile, NoSourceFile, Statistics, StatisticsInfo, BatchSourceFile, ScriptSourceFile, ShowPickled, ScalaClassLoader, returning } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } import settings.{ AestheticSettings } @@ -32,24 +32,25 @@ import backend.jvm.GenJVM import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination } import backend.icode.analysis._ -class Global(var currentSettings: Settings, var reporter: Reporter) extends SymbolTable - with CompilationUnits - with Plugins - with PhaseAssembly - with Trees - with Reifiers - with TreePrinters - with DocComments - with MacroContext - with symtab.Positions { +class Global(var currentSettings: Settings, var reporter: NscReporter) extends SymbolTable + with ClassLoaders + with ToolBoxes + with CompilationUnits + with Plugins + with PhaseAssembly + with Trees + with FreeVars + with TreePrinters + with DocComments + with Positions { override def settings = currentSettings - + import definitions.{ findNamedMember, findMemberFromRoot } // alternate constructors ------------------------------------------ - def this(reporter: Reporter) = + def this(reporter: NscReporter) = this(new Settings(err => reporter.error(null, err)), reporter) def this(settings: Settings) = @@ -61,7 +62,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb type AbstractFileType = scala.tools.nsc.io.AbstractFile def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = gen.mkAttributedQualifier(tpe, termSym) - + def picklerPhase: Phase = if (currentRun.isDefined) currentRun.picklerPhase else NoPhase // platform specific elements @@ -78,6 +79,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb // sub-components -------------------------------------------------- /** Generate ASTs */ + type TreeGen = scala.tools.nsc.ast.TreeGen + object gen extends { val global: Global.this.type = Global.this } with TreeGen { @@ -127,7 +130,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb /** Print tree in detailed form */ object nodePrinters extends { val global: Global.this.type = Global.this - } with NodePrinters with ReifyPrinters { + } with NodePrinters { infolevel = InfoLevel.Verbose } @@ -137,7 +140,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb } with TreeBrowsers val nodeToString = nodePrinters.nodeToString - val reifiedNodeToString = nodePrinters.reifiedNodeToString val treeBrowser = treeBrowsers.create() // ------------ Hooks for interactive mode------------------------- @@ -215,7 +217,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def logAfterEveryPhase[T](msg: String)(op: => T) { log("Running operation '%s' after every phase.\n".format(msg) + describeAfterEveryPhase(op)) } - + def shouldLogAtThisPhase = ( (settings.log.isSetByUser) && ((settings.log containsPhase globalPhase) || (settings.log containsPhase phase)) @@ -319,7 +321,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def showNames = List(showClass, showObject).flatten def showPhase = isActive(settings.Yshow) def showSymbols = settings.Yshowsyms.value - def showTrees = settings.Xshowtrees.value + def showTrees = settings.Xshowtrees.value || settings.XshowtreesCompact.value || settings.XshowtreesStringified.value val showClass = optSetting[String](settings.Xshowcls) map (x => splitClassAndPhase(x, false)) val showObject = optSetting[String](settings.Xshowobj) map (x => splitClassAndPhase(x, true)) @@ -1108,7 +1110,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def phaseNamed(name: String): Phase = findOrElse(firstPhase.iterator)(_.name == name)(NoPhase) - + /** All phases as of 3/2012 here for handiness; the ones in * active use uncommented. */ @@ -1581,7 +1583,7 @@ object Global { * This allows the use of a custom Global subclass with the software which * wraps Globals, such as scalac, fsc, and the repl. */ - def fromSettings(settings: Settings, reporter: Reporter): Global = { + def fromSettings(settings: Settings, reporter: NscReporter): Global = { // !!! The classpath isn't known until the Global is created, which is too // late, so we have to duplicate it here. Classpath is too tightly coupled, // it is a construct external to the compiler and should be treated as such. @@ -1589,7 +1591,7 @@ object Global { val loader = ScalaClassLoader.fromURLs(new PathResolver(settings).result.asURLs, parentLoader) val name = settings.globalClass.value val clazz = Class.forName(name, true, loader) - val cons = clazz.getConstructor(classOf[Settings], classOf[Reporter]) + val cons = clazz.getConstructor(classOf[Settings], classOf[NscReporter]) cons.newInstance(settings, reporter).asInstanceOf[Global] } @@ -1597,7 +1599,7 @@ object Global { /** A global instantiated this way honors -Yglobal-class setting, and * falls back on calling the Global constructor directly. */ - def apply(settings: Settings, reporter: Reporter): Global = { + def apply(settings: Settings, reporter: NscReporter): Global = { val g = ( if (settings.globalClass.isDefault) null else try fromSettings(settings, reporter) catch { case x => diff --git a/src/compiler/scala/tools/nsc/MacroContext.scala b/src/compiler/scala/tools/nsc/MacroContext.scala deleted file mode 100644 index 9ea1f87125..0000000000 --- a/src/compiler/scala/tools/nsc/MacroContext.scala +++ /dev/null @@ -1,10 +0,0 @@ -package scala.tools.nsc - -import symtab.Flags._ - -trait MacroContext extends reflect.macro.Context { self: Global => - - def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED - - def referenceCapturedVariable(id: Ident): Tree = ReferenceToBoxed(id) -} diff --git a/src/compiler/scala/tools/nsc/ReflectGlobal.scala b/src/compiler/scala/tools/nsc/ReflectGlobal.scala index 3132a9987d..68a6a4d336 100644 --- a/src/compiler/scala/tools/nsc/ReflectGlobal.scala +++ b/src/compiler/scala/tools/nsc/ReflectGlobal.scala @@ -5,7 +5,7 @@ import reporters.Reporter /** A version of Global that uses reflection to get class * infos, instead of reading class or source files. */ -class ReflectGlobal(currentSettings: Settings, reporter: Reporter) +class ReflectGlobal(currentSettings: Settings, reporter: Reporter, var classLoader: ClassLoader) extends Global(currentSettings, reporter) with reflect.runtime.SymbolTable { override def transformedType(sym: Symbol) = @@ -13,4 +13,9 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter) uncurry.transformInfo(sym, refChecks.transformInfo(sym, sym.info))) + override def staticClass(fullname: String) = + super[SymbolTable].staticClass(fullname) + + override def staticModule(fullname: String) = + super[SymbolTable].staticModule(fullname) } diff --git a/src/compiler/scala/tools/nsc/ReflectMain.scala b/src/compiler/scala/tools/nsc/ReflectMain.scala index 7167f5aa27..f9a18abc25 100644 --- a/src/compiler/scala/tools/nsc/ReflectMain.scala +++ b/src/compiler/scala/tools/nsc/ReflectMain.scala @@ -1,7 +1,16 @@ package scala.tools.nsc +import util.ScalaClassLoader +import tools.util.PathResolver +import util.ClassPath.DefaultJavaContext + object ReflectMain extends Driver { - override def newCompiler(): Global = new ReflectGlobal(settings, reporter) + private def reflectionClassloaderFromSettings(settings: Settings) = { + val classpath = new PathResolver(settings).result + ScalaClassLoader.fromURLs(classpath.asURLs, getClass.getClassLoader) + } + + override def newCompiler(): Global = new ReflectGlobal(settings, reporter, reflectionClassloaderFromSettings(settings)) } \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ToolBoxes.scala b/src/compiler/scala/tools/nsc/ToolBoxes.scala new file mode 100644 index 0000000000..eb298833b8 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ToolBoxes.scala @@ -0,0 +1,85 @@ +package scala.tools.nsc + +import util.ScalaClassLoader + +trait ToolBoxes { self: Global => + + import self.{Reporter => ApiReporter} + + def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options) + + class ToolBox(val reporter: ApiReporter, val options: String) extends AbsToolBox { + def typeCheck(tree0: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + val tree = substituteFreeTypes(tree0, freeTypes) + val currentTyper = typer + val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _) + def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) + wrapper(currentTyper.silent(_.typed(tree, analyzer.EXPRmode, pt)) match { + case analyzer.SilentResultValue(result) => + result + case error @ analyzer.SilentTypeError(_) => + if (!silent) throw new ToolBoxError(this, "reflective typecheck has failed: %s".format(error.err.errMsg)) + EmptyTree + }) + } + + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree = + // todo. implement this + ??? + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree = + // todo. implement this + ??? + + def resetAllAttrs[T <: Tree](tree: T): T = + self.resetAllAttrs(tree) + + def resetLocalAttrs[T <: Tree](tree: T): T = + self.resetLocalAttrs(tree) + + def runExpr(tree0: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = { + var tree = substituteFreeTypes(tree0, freeTypes) + // need to reset the tree, otherwise toolbox will refuse to work with it + tree = resetAllAttrs(tree0.duplicate) + val imported = importer.importTree(tree) + val toolBox = libraryClasspathMirror.mkToolBox(reporter.asInstanceOf[libraryClasspathMirror.Reporter], options) + try toolBox.runExpr(imported) + catch { + case ex: toolBox.ToolBoxError => + throw new ToolBoxError(this, ex.message, ex.cause) + } + } + + // [Eugene] how do I make this work without casts? + // private lazy val importer = libraryClasspathMirror.mkImporter(self) + private lazy val importer = libraryClasspathMirror.mkImporter(self).asInstanceOf[libraryClasspathMirror.Importer { val from: self.type }] + + private lazy val libraryClasspathMirror = { + if (self.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + val libraryClassLoader = { + val classpath = self.classPath.asURLs + var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) + + // [Eugene] a heuristic to detect REPL + if (self.settings.exposeEmptyPackage.value) { + import scala.tools.nsc.interpreter._ + val virtualDirectory = self.settings.outputDirs.getSingleOutput.get + loader = new AbstractFileClassLoader(virtualDirectory, loader) {} + } + + loader + } + + new scala.reflect.runtime.Mirror(libraryClassLoader) + } + + class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause) + + object ToolBoxError extends ToolBoxErrorExtractor { + def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message)) + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 456e7eae9e..ff4e2f3fb5 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package ast import symtab._ -import reporters.Reporter +import reporters.{Reporter => NscReporter} import util.{Position, NoPosition} import util.DocStrings._ import scala.reflect.internal.Chars._ @@ -21,7 +21,7 @@ trait DocComments { self: Global => var cookedDocComments = Map[Symbol, String]() - def reporter: Reporter + def reporter: NscReporter /** The raw doc comment map */ val docComments = mutable.HashMap[Symbol, DocComment]() diff --git a/src/compiler/scala/tools/nsc/ast/FreeVars.scala b/src/compiler/scala/tools/nsc/ast/FreeVars.scala new file mode 100644 index 0000000000..1bf36e8bf2 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ast/FreeVars.scala @@ -0,0 +1,26 @@ +package scala.tools.nsc +package ast + +trait FreeVars extends reflect.internal.FreeVars { self: Global => + + import self._ + import definitions._ + import treeInfo._ + + def logFreeVars(position: Position, reified: Tree): Unit = { + if (settings.logFreeTerms.value || settings.logFreeTypes.value) { + reified match { + case Reified(_, symbolTable, _) => + // logging free vars only when they are untyped prevents avalanches of duplicate messages + symbolTable foreach { + case FreeTermDef(_, _, binding, origin) if settings.logFreeTerms.value && binding.tpe == null => + reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin)) + case FreeTypeDef(_, _, binding, origin) if settings.logFreeTypes.value && binding.tpe == null => + reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin)) + case _ => + // do nothing + } + } + } + } +} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index acbdcd501f..c79ca1206e 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -27,24 +27,24 @@ abstract class NodePrinters { def nodeToString: Tree => String = if (sys.props contains "scala.colors") nodeToColorizedString else nodeToRegularString - + object nodeToRegularString extends DefaultPrintAST with (Tree => String) { def apply(tree: Tree) = stringify(tree) } - + object nodeToColorizedString extends ColorPrintAST with (Tree => String) { def apply(tree: Tree) = stringify(tree) } trait ColorPrintAST extends DefaultPrintAST { import scala.tools.util.color._ - + def keywordColor = Cyan def typeColor = Yellow def termColor = Blue def flagColor = Red def literalColor = Green - + override def showFlags(tree: MemberDef) = super.showFlags(tree) in flagColor.bright @@ -81,7 +81,7 @@ abstract class NodePrinters { if (tpe == null || tpe == NoType) "" else "tree.tpe=" + tpe } - + def showAttributes(tree: Tree): String = { if (infolevel == InfoLevel.Quiet) "" else { @@ -90,7 +90,7 @@ abstract class NodePrinters { } } } - + trait PrintAST { private val buf = new StringBuilder private var level = 0 @@ -101,7 +101,7 @@ abstract class NodePrinters { def showLiteral(lit: Literal): String def showTypeTree(tt: TypeTree): String def showAttributes(tree: Tree): String // symbol and type - + def showRefTreeName(tree: Tree): String = tree match { case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name) case Select(qual, name) => showRefTreeName(qual) + "." + showName(name) @@ -122,8 +122,14 @@ abstract class NodePrinters { def stringify(tree: Tree): String = { buf.clear() - level = 0 - traverse(tree) + if (settings.XshowtreesStringified.value) buf.append(tree.toString + EOL) + if (settings.XshowtreesCompact.value) { + // todo. colors for compact representation + buf.append(showRaw(tree)) + } else { + level = 0 + traverse(tree) + } buf.toString } def traverseAny(x: Any) { @@ -134,7 +140,7 @@ abstract class NodePrinters { } } def println(s: String) = printLine(s, "") - + def printLine(value: String, comment: String) { buf append " " * level buf append value @@ -183,7 +189,7 @@ abstract class NodePrinters { traverseList("Nil", "argument")(args) } } - + def printMultiline(tree: Tree)(body: => Unit) { printMultiline(tree.printingPrefix, showAttributes(tree))(body) } @@ -299,7 +305,7 @@ abstract class NodePrinters { } case Template(parents, self, body) => printMultiline(tree) { - val ps0 = parents map { p => + val ps0 = parents map { p => if (p.tpe eq null) p match { case x: RefTree => showRefTree(x) case x => "" + x @@ -339,7 +345,7 @@ abstract class NodePrinters { traverseList("[]", "type parameter")(tparams) traverse(rhs) } - + case PackageDef(pid, stats) => printMultiline("PackageDef", "")(pid :: stats foreach traverse) diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala new file mode 100644 index 0000000000..83a67cfbe3 --- /dev/null +++ b/src/compiler/scala/tools/nsc/ast/Positions.scala @@ -0,0 +1,44 @@ +package scala.tools.nsc +package ast + +import scala.tools.nsc.util.{ SourceFile, Position, OffsetPosition, NoPosition } + +trait Positions extends scala.reflect.internal.Positions { + self: Global => + + def rangePos(source: SourceFile, start: Int, point: Int, end: Int) = + new OffsetPosition(source, point) + + def validatePositions(tree: Tree) {} + + // [Eugene] disabling this for now. imo it doesn't justify pollution of the public API + // override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = { + // if (tree.pos != NoPosition && tree.pos != annot.pos) debugwarn("Overwriting annotation "+ tree.annotation +" of tree "+ tree +" with annotation "+ annot) + // // if ((tree.annotation.isInstanceOf[scala.tools.nsc.util.Position] || !annot.isInstanceOf[scala.tools.nsc.util.Position]) && tree.isInstanceOf[Block]) + // // println("Updating block from "+ tree.annotation +" to "+ annot) + // } + + class ValidatingPosAssigner extends PosAssigner { + var pos: Position = _ + override def traverse(t: Tree) { + if (t eq EmptyTree) () + else if (t.pos == NoPosition) super.traverse(t setPos pos) + else if (globalPhase.id <= currentRun.picklerPhase.id) { + // When we prune due to encountering a position, traverse the + // pruned children so we can warn about those lacking positions. + t.children foreach { c => + if ((c eq EmptyTree) || (c eq emptyValDef)) () + else if (c.pos == NoPosition) { + reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase) + inform("parent: " + treeSymStatus(t)) + inform(" child: " + treeSymStatus(c) + "\n") + } + } + } + } + } + + override protected[this] lazy val posAssigner: PosAssigner = + if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner + else new DefaultPosAssigner +} diff --git a/src/compiler/scala/tools/nsc/ast/Reifiers.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala deleted file mode 100644 index 04468a096d..0000000000 --- a/src/compiler/scala/tools/nsc/ast/Reifiers.scala +++ /dev/null @@ -1,761 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Gilles Dubochet - */ - -package scala.tools.nsc -package ast - -import symtab._ -import Flags._ -import scala.reflect.api.Modifier._ -import scala.collection.{ mutable, immutable } -import scala.collection.mutable.ListBuffer -import scala.tools.nsc.util.FreshNameCreator -import scala.runtime.ScalaRunTime.{ isAnyVal, isTuple } - -/** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type. - * See more info in the comments to `reify' in scala.reflect.macro.Context. - * - * @author Martin Odersky - * @version 2.10 - */ -trait Reifiers { self: Global => - - def reify(tree: Tree): Tree = { - class Reifier { - import definitions._ - import Reifier._ - - final val scalaPrefix = "scala." - final val localPrefix = "$local" - final val memoizerName = "$memo" - - val reifyDebug = settings.Yreifydebug.value - - private val reifiableSyms = mutable.ArrayBuffer[Symbol]() // the symbols that are reified with the tree - private val symIndex = mutable.HashMap[Symbol, Int]() // the index of a reifiable symbol in `reifiableSyms` - private var boundSyms = Set[Symbol]() // set of all symbols that are bound in tree to be reified - - private def definedInLiftedCode(tpe: Type) = - tpe exists (tp => boundSyms contains tp.typeSymbol) - - private def definedInLiftedCode(sym: Symbol) = - boundSyms contains sym - - /** - * Generate tree of the form - * - * { val $mr = scala.reflect.runtime.Mirror - * $local1 = new TypeSymbol(owner1, NoPosition, name1) - * ... - * $localN = new TermSymbol(ownerN, NoPositiion, nameN) - * $local1.setInfo(tpe1) - * ... - * $localN.setInfo(tpeN) - * $localN.setAnnotations(annotsN) - * rtree - * } - * - * where - * - * - `$localI` are free type symbols in the environment, as well as local symbols - * of refinement types. - * - `tpeI` are the info's of `symI` - * - `rtree` is code that generates `data` at runtime, maintaining all attributes. - * - `data` is typically a tree or a type. - */ - def reifyTopLevel(data: Any): Tree = { - val rtree = reify(data) - Block(mirrorAlias :: reifySymbolTableSetup, rtree) - } - - private def isLocatable(sym: Symbol) = - sym.isPackageClass || sym.owner.isClass || sym.isTypeParameter && sym.paramPos >= 0 - - private def registerReifiableSymbol(sym: Symbol): Unit = - if (!(symIndex contains sym)) { - sym.owner.ownersIterator find (x => !isLocatable(x)) foreach registerReifiableSymbol - symIndex(sym) = reifiableSyms.length - reifiableSyms += sym - } - - // helper methods - - private def localName(sym: Symbol): TermName = - newTermName(localPrefix + symIndex(sym)) - - private def call(fname: String, args: Tree*): Tree = - Apply(termPath(fname), args.toList) - - private def mirrorSelect(name: String): Tree = - termPath(nme.MIRROR_PREFIX + name) - - private def mirrorCall(name: TermName, args: Tree*): Tree = - call("" + (nme.MIRROR_PREFIX append name), args: _*) - - private def mirrorCall(name: String, args: Tree*): Tree = - call(nme.MIRROR_PREFIX + name, args: _*) - - private def mirrorFactoryCall(value: Product, args: Tree*): Tree = - mirrorFactoryCall(value.productPrefix, args: _*) - - private def mirrorFactoryCall(prefix: String, args: Tree*): Tree = - mirrorCall(prefix, args: _*) - - private def scalaFactoryCall(name: String, args: Tree*): Tree = - call(scalaPrefix + name + ".apply", args: _*) - - private def mkList(args: List[Tree]): Tree = - scalaFactoryCall("collection.immutable.List", args: _*) - - private def reifyModifiers(m: Modifiers) = - mirrorCall("modifiersFromInternalFlags", reify(m.flags), reify(m.privateWithin), reify(m.annotations)) - - private def reifyAggregate(name: String, args: Any*) = - scalaFactoryCall(name, (args map reify).toList: _*) - - /** - * Reify a list - */ - private def reifyList(xs: List[Any]): Tree = - mkList(xs map reify) - - /** - * Reify an array - */ - private def reifyArray(xs: Array[_]): Tree = - // @xeno.by: doesn't work for Array(LiteralAnnotArg(...)) - // because we cannot generate manifests for path-dependent types - scalaFactoryCall(nme.Array, xs map reify: _*) - - /** Reify a name */ - private def reifyName(name: Name) = - mirrorCall(if (name.isTypeName) "newTypeName" else "newTermName", Literal(Constant(name.toString))) - - private def isFree(sym: Symbol) = - !(symIndex contains sym) - - /** - * Reify a reference to a symbol - */ - private def reifySymRef(sym: Symbol): Tree = { - symIndex get sym match { - case Some(idx) => - Ident(localName(sym)) - case None => - if (sym == NoSymbol) - mirrorSelect("NoSymbol") - else if (sym == RootPackage) - mirrorSelect("definitions.RootPackage") - else if (sym == RootClass) - mirrorSelect("definitions.RootClass") - else if (sym == EmptyPackage) - mirrorSelect("definitions.EmptyPackage") - else if (sym.isModuleClass) - Select(reifySymRef(sym.sourceModule), "moduleClass") - else if (sym.isStatic && sym.isClass) - mirrorCall("staticClass", reify(sym.fullName)) - else if (sym.isStatic && sym.isModule) - mirrorCall("staticModule", reify(sym.fullName)) - else if (isLocatable(sym)) - if (sym.isTypeParameter) - mirrorCall("selectParam", reify(sym.owner), reify(sym.paramPos)) - else { - if (reifyDebug) println("locatable: " + sym + " " + sym.isPackageClass + " " + sym.owner + " " + sym.isTypeParameter) - val rowner = reify(sym.owner) - val rname = reify(sym.name.toString) - if (sym.isType) - mirrorCall("selectType", rowner, rname) - else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) { - val index = sym.owner.info.decl(sym.name).alternatives indexOf sym - assert(index >= 0, sym) - mirrorCall("selectOverloadedMethod", rowner, rname, reify(index)) - } else - mirrorCall("selectTerm", rowner, rname) - } - else { - if (sym.isTerm) { - if (reifyDebug) println("Free: " + sym) - val symtpe = lambdaLift.boxIfCaptured(sym, sym.tpe, erasedTypes = false) - def markIfCaptured(arg: Ident): Tree = - if (sym.isCapturedVariable) referenceCapturedVariable(arg) else arg - mirrorCall("newFreeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym))) - } else { - if (reifyDebug) println("Late local: " + sym) - registerReifiableSymbol(sym) - reifySymRef(sym) - } - } - } - } - - /** - * reify the creation of a symbol - */ - private def reifySymbolDef(sym: Symbol): Tree = { - if (reifyDebug) println("reify sym def " + sym) - - ValDef(NoMods, localName(sym), TypeTree(), - Apply( - Select(reify(sym.owner), "newNestedSymbol"), - List(reify(sym.name), reify(sym.pos), Literal(Constant(sym.flags)), Literal(Constant(sym.isClass))) - ) - ) - } - - /** - * Generate code to add type and annotation info to a reified symbol - */ - private def fillInSymbol(sym: Symbol): Tree = { - val rset = Apply(Select(reifySymRef(sym), nme.setTypeSignature), List(reifyType(sym.info))) - if (sym.annotations.isEmpty) rset - else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations))) - } - - /** Reify a scope */ - private def reifyScope(scope: Scope): Tree = { - scope foreach registerReifiableSymbol - mirrorCall(nme.newScopeWith, scope.toList map reifySymRef: _*) - } - - /** Reify a list of symbols that need to be created */ - private def reifySymbols(syms: List[Symbol]): Tree = { - syms foreach registerReifiableSymbol - mkList(syms map reifySymRef) - } - - /** Reify a type that defines some symbols */ - private def reifyTypeBinder(value: Product, bound: List[Symbol], underlying: Type): Tree = - mirrorFactoryCall(value, reifySymbols(bound), reify(underlying)) - - /** Reify a type */ - private def reifyType(tpe0: Type): Tree = { - val tpe = tpe0.normalize - - if (tpe.isErroneous) - CannotReifyErroneousType(tpe) - if (definedInLiftedCode(tpe)) - CannotReifyTypeInvolvingBoundType(tpe) - - val tsym = tpe.typeSymbol - if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic) - Select(reifySymRef(tpe.typeSymbol), nme.asTypeConstructor) - else tpe match { - case t @ NoType => - reifyMirrorObject(t) - case t @ NoPrefix => - reifyMirrorObject(t) - case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => - mirrorCall(nme.thisModuleType, reify(clazz.fullName)) - case t @ RefinedType(parents, decls) => - registerReifiableSymbol(tpe.typeSymbol) - mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol)) - case t @ ClassInfoType(parents, decls, clazz) => - registerReifiableSymbol(clazz) - mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol)) - case t @ ExistentialType(tparams, underlying) => - reifyTypeBinder(t, tparams, underlying) - case t @ PolyType(tparams, underlying) => - reifyTypeBinder(t, tparams, underlying) - case t @ MethodType(params, restpe) => - reifyTypeBinder(t, params, restpe) - case t @ AnnotatedType(anns, underlying, selfsym) => - val saved1 = reifySymbols - val saved2 = reifyTypes - - try { - // one more quirk of reifying annotations - // - // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs - // that's because a lot of logic expects post-typer trees to have non-null tpes - // - // Q: reified trees are pre-typer, so there's shouldn't be a problem. - // reflective typechecker will fill in missing symbols and types, right? - // A: actually, no. annotation ASTs live inside AnnotatedTypes, - // and insides of the types is the place where typechecker doesn't look. - reifySymbols = true - reifyTypes = true - if (reifyDebug) println("reify AnnotatedType: " + tpe) - reifyProductUnsafe(tpe) - } finally { - reifySymbols = saved1 - reifyTypes = saved2 - } - case _ => - reifyProductUnsafe(tpe) - } - } - - var reifySymbols = false - var reifyTypes = false - - /** Preprocess a tree before reification */ - private def trimTree(tree: Tree): Tree = { - def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]) = { - var stats1 = stats filterNot (stat => stat.isDef && { - if (stat.symbol.isCaseAccessorMethod && reifyDebug) println("discarding case accessor method: " + stat) - stat.symbol.isCaseAccessorMethod - }) - stats1 = stats1 filterNot (memberDef => memberDef.isDef && { - val isSynthetic = memberDef.symbol.isSynthetic - // @xeno.by: this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) - // that's why I replace the check with an assumption that all synthetic members are, in fact, generated of case classes -// val isCaseMember = deff.symbol.isCaseClass || deff.symbol.companionClass.isCaseClass - val isCaseMember = true - if (isSynthetic && isCaseMember && reifyDebug) println("discarding case class synthetic def: " + memberDef) - isSynthetic && isCaseMember - }) - stats1 = stats1 map { - case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isCaseAccessor => - if (reifyDebug) println("resetting visibility of case accessor field: " + valdef) - val Modifiers(flags, privateWithin, annotations) = mods - val flags1 = flags & ~Flags.LOCAL & ~Flags.PRIVATE - val mods1 = Modifiers(flags1, privateWithin, annotations) - ValDef(mods1, name, tpt, rhs).copyAttrs(valdef) - case stat => - stat - } - stats1 - } - - def trimSyntheticCaseClassCompanions(stats: List[Tree]) = - stats diff (stats collect { case moddef: ModuleDef => moddef } filter (moddef => { - val isSynthetic = moddef.symbol.isSynthetic - // @xeno.by: this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) - // that's why I replace the check with an assumption that all synthetic modules are, in fact, companions of case classes -// val isCaseCompanion = moddef.symbol.companionClass.isCaseClass - val isCaseCompanion = true - // @xeno.by: we also have to do this ugly hack for the very same reason described above - // normally this sort of stuff is performed in reifyTree, which binds related symbols, however, local companions will be out of its reach - if (reifyDebug) println("boundSym: "+ moddef.symbol) - boundSyms += moddef.symbol - if (isSynthetic && isCaseCompanion && reifyDebug) println("discarding synthetic case class companion: " + moddef) - isSynthetic && isCaseCompanion - })) - - tree match { - case tree if tree.isErroneous => - tree - case ta @ TypeApply(hk, ts) => - def isErased(tt: TypeTree) = tt.tpe != null && definedInLiftedCode(tt.tpe) && tt.original == null - val discard = ts collect { case tt: TypeTree => tt } exists isErased - if (reifyDebug && discard) println("discarding TypeApply: " + tree) - if (discard) hk else ta - case classDef @ ClassDef(mods, name, params, impl) => - val Template(parents, self, body) = impl - val body1 = trimSyntheticCaseClassMembers(classDef, body) - var impl1 = Template(parents, self, body1).copyAttrs(impl) - ClassDef(mods, name, params, impl1).copyAttrs(classDef) - case moduledef @ ModuleDef(mods, name, impl) => - val Template(parents, self, body) = impl - val body1 = trimSyntheticCaseClassMembers(moduledef, body) - var impl1 = Template(parents, self, body1).copyAttrs(impl) - ModuleDef(mods, name, impl1).copyAttrs(moduledef) - case template @ Template(parents, self, body) => - val body1 = trimSyntheticCaseClassCompanions(body) - Template(parents, self, body1).copyAttrs(template) - case block @ Block(stats, expr) => - val stats1 = trimSyntheticCaseClassCompanions(stats) - Block(stats1, expr).copyAttrs(block) - case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isLazy => - if (reifyDebug) println("dropping $lzy in lazy val's name: " + tree) - val name1 = if (name endsWith nme.LAZY_LOCAL) name dropRight nme.LAZY_LOCAL.length else name - ValDef(mods, name1, tpt, rhs).copyAttrs(valdef) - case unapply @ UnApply(fun, args) => - def extractExtractor(tree: Tree): Tree = { - val Apply(fun, args) = tree - args match { - case List(Ident(special)) if special == nme.SELECTOR_DUMMY => - val Select(extractor, flavor) = fun - assert(flavor == nme.unapply || flavor == nme.unapplySeq) - extractor - case _ => - extractExtractor(fun) - } - } - - if (reifyDebug) println("unapplying unapply: " + tree) - val fun1 = extractExtractor(fun) - Apply(fun1, args).copyAttrs(unapply) - case _ => - tree - } - } - - /** Reify a tree */ - private def reifyTree(tree0: Tree): Tree = { - val tree = trimTree(tree0) - - var rtree = tree match { - case tree if tree.isErroneous => - CannotReifyErroneousTree(tree) - case self.EmptyTree => - reifyMirrorObject(EmptyTree) - case self.emptyValDef => - mirrorSelect(nme.emptyValDef) - case This(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) => - reifyFree(tree) - case Ident(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) => - if (tree.symbol.isVariable && tree.symbol.owner.isTerm) { - if (reifyDebug) println("captured variable: " + tree.symbol) - captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reifyTree here. - mirrorCall("Select", reifyFree(tree), reifyName(nme.elem)) - } else reifyFree(tree) - case tt: TypeTree if (tt.tpe != null) => - reifyTypeTree(tt) - case Literal(constant @ Constant(tpe: Type)) if boundSyms exists (tpe contains _) => - CannotReifyClassOfBoundType(tree, tpe) - case Literal(constant @ Constant(sym: Symbol)) if boundSyms contains sym => - CannotReifyClassOfBoundEnum(tree, constant.tpe) - case tree if tree.isDef => - if (reifyDebug) println("boundSym: %s of type %s".format(tree.symbol, (tree.productIterator.toList collect { case tt: TypeTree => tt } headOption).getOrElse(TypeTree(tree.tpe)))) - boundSyms += tree.symbol - - bindRelatedSymbol(tree.symbol.sourceModule, "sourceModule") - bindRelatedSymbol(tree.symbol.moduleClass, "moduleClass") - bindRelatedSymbol(tree.symbol.companionClass, "companionClass") - bindRelatedSymbol(tree.symbol.companionModule, "companionModule") - Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") } - def bindRelatedSymbol(related: Symbol, name: String): Unit = - if (related != null && related != NoSymbol) { - if (reifyDebug) println("boundSym (" + name + "): " + related) - boundSyms += related - } - - val prefix = tree.productPrefix - val elements = (tree.productIterator map { - // annotations exist in two flavors: - // 1) pre-typer ones that populate: a) Modifiers, b) Annotated nodes (irrelevant in this context) - // 2) post-typer ones that dwell inside: a) sym.annotations, b) AnnotatedTypes (irrelevant in this context) - // - // here we process Modifiers that are involved in deftrees - // AnnotatedTypes get reified elsewhere (currently, in ``reifyTypeTree'') - case Modifiers(flags, privateWithin, annotations) => - assert(annotations.isEmpty) // should've been eliminated by the typer - val postTyper = tree.symbol.annotations filter (_.original != EmptyTree) - if (reifyDebug && !postTyper.isEmpty) println("reify symbol annotations for %s: %s".format(tree.symbol, tree.symbol.annotations)) - val preTyper = postTyper map toPreTyperAnnotation - Modifiers(flags, privateWithin, preTyper) - case x => - x - }).toList - reifyProduct(prefix, elements) - case _ => - reifyProduct(tree) - } - - // usually we don't reify symbols/types, because they can be re-inferred during subsequent reflective compilation - // however, reification of AnnotatedTypes is special. see ``reifyType'' to find out why. - if (reifySymbols && tree.hasSymbol) { - if (reifyDebug) println("reifying symbol %s for tree %s".format(tree.symbol, tree)) - rtree = Apply(Select(rtree, nme.setSymbol), List(reifySymRef(tree.symbol))) - } - if (reifyTypes && tree.tpe != null) { - if (reifyDebug) println("reifying type %s for tree %s".format(tree.tpe, tree)) - rtree = Apply(Select(rtree, nme.setType), List(reifyType(tree.tpe))) - } - - rtree - } - - /** Reify pre-typer representation of a type. - * - * NB: This is the trickiest part of reification! - * - * In most cases, we're perfectly fine to reify a Type itself (see ``reifyType''). - * However if the type involves a symbol declared inside the quasiquote (i.e. registered in ``boundSyms''), - * then we cannot reify it, or otherwise subsequent reflective compilation will fail. - * - * Why will it fail? Because reified deftrees (e.g. ClassDef(...)) will generate fresh symbols during that compilation, - * so naively reified symbols will become out of sync, which brings really funny compilation errors and/or crashes, e.g.: - * https://issues.scala-lang.org/browse/SI-5230 - * - * To deal with this unpleasant fact, we need to fall back from types to equivalent trees (after all, parser trees don't contain any types, just trees, so it should be possible). - * Luckily, these original trees get preserved for us in the ``original'' field when Trees get transformed into TypeTrees. - * And if an original of a type tree is empty, we can safely assume that this type is non-essential (e.g. was inferred/generated by the compiler). - * In that case the type can be omitted (e.g. reified as an empty TypeTree), since it will be inferred again later on. - * - * An important property of the original is that it isn't just a pre-typer tree. - * It's actually kind of a post-typer tree with symbols assigned to its Idents (e.g. Ident("List") will contain a symbol that points to immutable.this.List). - * This is very important, since subsequent reflective compilation won't have to resolve these symbols. - * In general case, such resolution cannot be performed, since reification doesn't preserve lexical context, - * which means that reflective compilation won't be aware of, say, imports that were provided when the reifee has been compiled. - * - * This workaround worked surprisingly well and allowed me to fix several important reification bugs, until the abstraction has leaked. - * Suddenly I found out that in certain contexts original trees do not contain symbols, but are just parser trees. - * To the moment I know only one such situation: typedAnnotations does not typecheck the annotation in-place, but rather creates new trees and typechecks them, so the original remains symless. - * This is laboriously worked around in the code below. I hope this will be the only workaround in this department. - */ - private def reifyTypeTree(tt: TypeTree): Tree = { - if (definedInLiftedCode(tt.tpe)) { - if (reifyDebug) println("reifyTypeTree, defined in lifted code: " + tt.tpe) - if (tt.original != null) { - val annotations = tt.tpe filter { _.isInstanceOf[AnnotatedType] } collect { case atp: AnnotatedType => atp.annotations } flatten - val annmap = annotations map { ann => (ann.original, ann) } toMap - - // annotations exist in two flavors: - // 1) pre-typer ones that populate: a) Modifiers (irrelevant in this context), b) Annotated nodes - // 2) post-typer ones that dwell inside: a) sym.annotations (irrelevant in this context), b) AnnotatedTypes - // - // here we process AnnotatedTypes, since only they can be involved in TypeTrees - // Modifiers get reified elsewhere (currently, in the "isDef" case of ``reifyTree'') - // - // the problem with annotations is that their originals don't preserve any symbols at all - // read the comment to this method to find out why it's bad - // that's why we transplant typechecked, i.e. symful, annotations onto original trees - class AnnotationFixup extends self.Transformer { - override def transform(tree: Tree) = tree match { - case Annotated(ann0, args) => - assert(annmap contains ann0) - val ann1 = annmap(ann0) - val ann = toPreTyperAnnotation(ann1) - Annotated(ann, transform(args)) - case _ => - tree - } - } - - if (reifyDebug) println("verdict: essential, reify as original") - val patchedOriginal = new AnnotationFixup().transform(tt.original) - reifyTree(patchedOriginal) - } else { - // type is deemed to be non-essential - // erase it and hope that subsequent reflective compilation will be able to recreate it again - if (reifyDebug) println("verdict: non-essential, discard") - mirrorCall("TypeTree") - } - } else { - var rtt = mirrorCall(nme.TypeTree, reifyType(tt.tpe)) - // @xeno.by: temporarily disabling reification of originals - // subsequent reflective compilation will try to typecheck them - // and this means that the reifier has to do additional efforts to ensure that this will succeed - // additional efforts + no clear benefit = will be implemented later -// if (tt.original != null) { -// val setOriginal = Select(rtt, newTermName("setOriginal")) -// val reifiedOriginal = reify(tt.original) -// rtt = Apply(setOriginal, List(reifiedOriginal)) -// } - rtt - } - } - - /** Reify post-typer representation of an annotation */ - private def reifyAnnotation(ann: AnnotationInfo): Tree = - // @xeno.by: if you reify originals, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important - mirrorFactoryCall("AnnotationInfo", reifyType(ann.atp), reifyList(ann.args), reify(ann.assocs)) - - /** Reify pre-typer representation of an annotation. - * The trick here is to retain the symbols that have been populated during typechecking of the annotation. - * If we do not do that, subsequent reflective compilation will fail. - */ - private def toPreTyperAnnotation(ann: AnnotationInfo): Tree = { - if (definedInLiftedCode(ann.atp)) { - // todo. deconstruct reifiable tree from ann.original and ann.args+ann.assocs - // - // keep in mind that we can't simply use ann.original, because its args are symless - // which means that any imported symbol (e.g. List) will crash subsequent reflective compilation - // hint: if I had enough time, I'd try to extract reifiable annotation type from ann.original - // and to apply its constructor to ann.args (that are symful, i.e. suitable for reification) - // - // also, if we pursue the route of reifying annotations defined in lifted code - // we should think about how to provide types for all nodes of the return value - // this will be necessary for reifying AnnotatedTypes, since ASTs inside ATs must all have non-null tpes - // an alternative would be downgrading ATs to Annotated nodes, but this needs careful thinking - // for now I just leave this as an implementation restriction - CannotReifyAnnotationInvolvingBoundType(ann) - } else { - val args = if (ann.assocs.isEmpty) { - ann.args - } else { - def toScalaAnnotation(jann: ClassfileAnnotArg): Tree = jann match { - case LiteralAnnotArg(const) => - Literal(const) - case ArrayAnnotArg(arr) => - Apply(Ident(definitions.ArrayModule), arr.toList map toScalaAnnotation) - case NestedAnnotArg(ann) => - toPreTyperAnnotation(ann) - } - - ann.assocs map { case (nme, arg) => AssignOrNamedArg(Ident(nme), toScalaAnnotation(arg)) } - } - - New(ann.atp, args: _*) - } - } - - /** - * Reify a free reference. The result will be either a mirror reference - * to a global value, or else a mirror Literal. - */ - private def reifyFree(tree: Tree): Tree = tree match { - case This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass => - val sym = tree.symbol - if (reifyDebug) println("This for %s, reified as freeVar".format(sym)) - if (reifyDebug) println("Free: " + sym) - val freeVar = mirrorCall("newFreeVar", reify(sym.name.toString), reify(sym.tpe), This(sym)) - mirrorCall(nme.Ident, freeVar) - case This(_) => - if (reifyDebug) println("This for %s, reified as This".format(tree.symbol)) - mirrorCall(nme.This, reifySymRef(tree.symbol)) - case _ => - mirrorCall(nme.Ident, reifySymRef(tree.symbol)) - } - - // todo: consider whether we should also reify positions - private def reifyPosition(pos: Position): Tree = - reifyMirrorObject(NoPosition) - - // !!! we must eliminate these casts. - private def reifyProductUnsafe(x: Any): Tree = - if (x.isInstanceOf[Product]) reifyProduct(x.asInstanceOf[Product]) - else throw new Exception("%s of type %s cannot be cast to Product".format(x, x.getClass)) - private def reifyProduct(x: Product): Tree = - reifyProduct(x.productPrefix, x.productIterator.toList) - private def reifyProduct(prefix: String, elements: List[Any]): Tree = { - // @xeno.by: reflection would be more robust, but, hey, this is a hot path - if (prefix.startsWith("Tuple")) reifyAggregate(prefix, elements: _*) - else mirrorCall(prefix, (elements map reify): _*) - } - - /** - * Reify a case object defined in Mirror - */ - private def reifyMirrorObject(name: String): Tree = mirrorSelect(name) - private def reifyMirrorObject(x: Product): Tree = reifyMirrorObject(x.productPrefix) - - private def isReifiableConstant(value: Any) = value match { - case null => true // seems pretty reifable to me? - case _: String => true - case _ => isAnyVal(value) - } - - /** Reify an arbitary value */ - private def reify(value: Any): Tree = value match { - case tree: Tree => reifyTree(tree) - case sym: Symbol => reifySymRef(sym) - case tpe: Type => reifyType(tpe) - case xs: List[_] => reifyList(xs) - case xs: Array[_] => reifyArray(xs) - case scope: Scope => reifyScope(scope) - case x: Name => reifyName(x) - case x: Position => reifyPosition(x) - case x: Modifiers => reifyModifiers(x) - case x: AnnotationInfo => reifyAnnotation(x) - case _ => - if (isReifiableConstant(value)) Literal(Constant(value)) - else reifyProductUnsafe(value) - } - - /** - * An (unreified) path that refers to definition with given fully qualified name - * @param mkName Creator for last portion of name (either TermName or TypeName) - */ - private def path(fullname: String, mkName: String => Name): Tree = { - val parts = fullname split "\\." - val prefixParts = parts.init - val lastName = mkName(parts.last) - if (prefixParts.isEmpty) Ident(lastName) - else { - val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _)) - Select(prefixTree, lastName) - } - } - - /** An (unreified) path that refers to term definition with given fully qualified name */ - private def termPath(fullname: String): Tree = path(fullname, newTermName) - - /** An (unreified) path that refers to type definition with given fully qualified name */ - private def typePath(fullname: String): Tree = path(fullname, newTypeName) - - private def mirrorAlias = - ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(termPath(fullnme.MirrorPackage)), termPath(fullnme.MirrorPackage)) - - /** - * Generate code that generates a symbol table of all symbols registered in `reifiableSyms` - */ - private def reifySymbolTableSetup: List[Tree] = { - val symDefs, fillIns = new mutable.ArrayBuffer[Tree] - var i = 0 - while (i < reifiableSyms.length) { - // fillInSymbol might create new reifiableSyms, that's why this is done iteratively - symDefs += reifySymbolDef(reifiableSyms(i)) - fillIns += fillInSymbol(reifiableSyms(i)) - i += 1 - } - - symDefs.toList ++ fillIns.toList - } - } // end of Reifier - - object Reifier { - def CannotReifyPreTyperTree(tree: Tree) = { - val msg = "pre-typer trees are not supported, consider typechecking the tree before passing it to the reifier" - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyErroneousTree(tree: Tree) = { - val msg = "erroneous trees are not supported, make sure that your tree typechecks successfully before passing it to the reifier" - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyErroneousType(tpe: Type) = { - val msg = "erroneous types are not supported, make sure that your tree typechecks successfully before passing it to the reifier" - throw new ReifierError(NoPosition, msg) - } - - def CannotReifyClassOfBoundType(tree: Tree, tpe: Type) = { - val msg = "implementation restriction: cannot reify classOf[%s] which refers to a type declared inside the block being reified".format(tpe) - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyClassOfBoundEnum(tree: Tree, tpe: Type) = { - val msg = "implementation restriction: cannot reify classOf[%s] which refers to an enum declared inside the block being reified".format(tpe) - throw new ReifierError(tree.pos, msg) - } - - def CannotReifyTypeInvolvingBoundType(tpe: Type) = { - val msg = "implementation restriction: cannot reify type %s which involves a symbol declared inside the block being reified".format(tpe) - throw new ReifierError(NoPosition, msg) - } - - def CannotReifyAnnotationInvolvingBoundType(ann: AnnotationInfo) = { - val msg = "implementation restriction: cannot reify annotation @%s which involves a symbol declared inside the block being reified".format(ann) - throw new ReifierError(ann.original.pos, msg) - } - } // end of Reifier - - // begin reify - import Reifier._ - if (tree.tpe != null) { - val saved = printTypings - try { - val reifyDebug = settings.Yreifydebug.value - val debugTrace = util.trace when reifyDebug - debugTrace("transforming = ")(if (settings.Xshowtrees.value) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString) - debugTrace("transformed = ") { - val reifier = new Reifier() - val untyped = reifier.reifyTopLevel(tree) - - val reifyCopypaste = settings.Yreifycopypaste.value - if (reifyCopypaste) { - if (reifyDebug) println("=======================") - println(reifiedNodeToString(untyped)) - if (reifyDebug) println("=======================") - } - - untyped - } - } finally { - printTypings = saved - } - } else { - CannotReifyPreTyperTree(tree) - } - } - - /** A throwable signalling a reification error */ - class ReifierError(var pos: Position, val msg: String) extends Throwable(msg) { - def this(msg: String) = this(NoPosition, msg) - } -} diff --git a/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala b/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala deleted file mode 100644 index fce59bb099..0000000000 --- a/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala +++ /dev/null @@ -1,75 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.tools.nsc -package ast - -import compat.Platform.EOL -import symtab._ -import Flags._ - -trait ReifyPrinters { self: NodePrinters => - - val global: Global - import global._ - - object reifiedNodeToString extends Function1[Tree, String] { - def apply(tree: Tree): String = { - import scala.reflect.api.Modifier - - // @PP: I fervently hope this is a test case or something, not anything being - // depended upon. Of more fragile code I cannot conceive. - // @eb: This stuff is only needed to debug-print out reifications in human-readable format - // Rolling a full-fledged, robust TreePrinter would be several times more code. - (for (line <- (tree.toString.split(EOL) drop 2 dropRight 1)) yield { - var s = line.trim - s = s.replace("$mr.", "") - s = s.replace(".apply", "") - s = s.replace("scala.collection.immutable.", "") - s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") - s = "List\\[.*?\\]".r.replaceAllIn(s, "List") - s = s.replace("immutable.this.Nil", "List()") - s = s.replace("modifiersFromInternalFlags", "Modifiers") - s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()") - s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => { - val buf = new collection.mutable.ListBuffer[String] - - val annotations = m.group(3) - if (buf.nonEmpty || annotations.nonEmpty) - buf.append("List(" + annotations + ")") - - val privateWithin = "" + m.group(2) - if (buf.nonEmpty || privateWithin != "") - buf.append("newTypeName(\"" + privateWithin + "\")") - - val flags = m.group(1).toLong - val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", " - if (buf.nonEmpty || s_flags != "") - buf.append("Set(" + s_flags + ")") - - "Modifiers(" + buf.reverse.mkString(", ") + ")" - }) - s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => { - val flags = m.group(1).toLong - val mods = Flags.modifiersOfFlags(flags) map (_.sourceString) - "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))" - }) - - s - }) mkString EOL - } - } - - - def printReifyCopypaste(tree: Tree) { - val reifyDebug = settings.Yreifydebug.value - if (reifyDebug) println("=======================") - printReifyCopypaste1(tree) - if (reifyDebug) println("=======================") - } - - def printReifyCopypaste1(tree: Tree) { - } -} \ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index ad26ccad5e..19d1e0a51a 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -207,22 +207,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { def mkSysErrorCall(message: String): Tree = mkMethodCall(Sys_error, List(Literal(Constant(message)))) - /** A creator for a call to a scala.reflect.Manifest or ClassManifest factory method. - * - * @param full full or partial manifest (target will be Manifest or ClassManifest) - * @param constructor name of the factory method (e.g. "classType") - * @param tparg the type argument - * @param args value arguments - * @return the tree - */ - def mkManifestFactoryCall(full: Boolean, constructor: String, tparg: Type, args: List[Tree]): Tree = - mkMethodCall( - if (full) FullManifestModule else PartialManifestModule, - newTermName(constructor), - List(tparg), - args - ) - /** Make a synchronized block on 'monitor'. */ def mkSynchronized(monitor: Tree, body: Tree): Tree = Apply(Select(monitor, Object_synchronized), List(body)) diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 43c231cf2d..66704680ae 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -13,6 +13,7 @@ import scala.reflect.internal.Flags.PARAM import scala.reflect.internal.Flags.PARAMACCESSOR import scala.reflect.internal.Flags.PRESUPER import scala.reflect.internal.Flags.TRAIT +import scala.compat.Platform.EOL trait Trees extends reflect.internal.Trees { self: Global => @@ -33,30 +34,6 @@ trait Trees extends reflect.internal.Trees { self: Global => ) } - class ValidatingPosAssigner extends PosAssigner { - var pos: Position = _ - override def traverse(t: Tree) { - if (t eq EmptyTree) () - else if (t.pos == NoPosition) super.traverse(t setPos pos) - else if (globalPhase.id <= currentRun.picklerPhase.id) { - // When we prune due to encountering a position, traverse the - // pruned children so we can warn about those lacking positions. - t.children foreach { c => - if ((c eq EmptyTree) || (c eq emptyValDef)) () - else if (c.pos == NoPosition) { - reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase) - inform("parent: " + treeSymStatus(t)) - inform(" child: " + treeSymStatus(c) + "\n") - } - } - } - } - } - - override protected[this] lazy val posAssigner: PosAssigner = - if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner - else new DefaultPosAssigner - // --- additional cases -------------------------------------------------------- /** Only used during parsing */ case class Parens(args: List[Tree]) extends Tree @@ -84,15 +61,6 @@ trait Trees extends reflect.internal.Trees { self: Global => /** emitted by typer, eliminated by refchecks */ case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree - /** Marks underlying reference to id as boxed. - * @pre: id must refer to a captured variable - * A reference such marked will refer to the boxed entity, no dereferencing - * with `.elem` is done on it. - * This tree node can be emitted by macros such as reify that call markBoxedReference. - * It is eliminated in LambdaLift, where the boxing conversion takes place. - */ - case class ReferenceToBoxed(idt: Ident) extends TermTree - // --- factory methods ---------------------------------------------------------- /** Generates a template with constructor corresponding to @@ -118,7 +86,7 @@ trait Trees extends reflect.internal.Trees { self: Global => // create parameters for as synthetic trees. var vparamss1 = vparamss map (vps => vps.map { vd => - atPos(focusPos(vd.pos)) { + atPos(vd.pos.focus) { ValDef( Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate) @@ -130,7 +98,7 @@ trait Trees extends reflect.internal.Trees { self: Global => // !!! I know "atPos in case" wasn't intentionally planted to // add an air of mystery to this file, but it is the sort of // comment which only its author could love. - tpt = atPos(focusPos(vdef.pos))(TypeTree() setOriginal tpt setPos focusPos(tpt.pos)), // atPos in case + tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), // atPos in case rhs = EmptyTree ) } @@ -198,8 +166,6 @@ trait Trees extends reflect.internal.Trees { self: Global => traverser.traverse(qualifier) case InjectDerivedValue(arg) => traverser.traverse(arg) - case ReferenceToBoxed(idt) => - traverser.traverse(idt) case TypeTreeWithDeferredRefCheck() => // (and rewrap the result? how to update the deferred check? would need to store wrapped tree instead of returning it from check) case _ => super.xtraverse(traverser, tree) @@ -209,7 +175,6 @@ trait Trees extends reflect.internal.Trees { self: Global => def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue - def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck } @@ -223,8 +188,6 @@ trait Trees extends reflect.internal.Trees { self: Global => new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree) def InjectDerivedValue(tree: Tree, arg: Tree) = new InjectDerivedValue(arg) - def ReferenceToBoxed(tree: Tree, idt: Ident) = - new ReferenceToBoxed(idt).copyAttrs(tree) def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match { case dc@TypeTreeWithDeferredRefCheck() => new TypeTreeWithDeferredRefCheck()(dc.check).copyAttrs(tree) } @@ -246,11 +209,6 @@ trait Trees extends reflect.internal.Trees { self: Global => if (arg0 == arg) => t case _ => this.treeCopy.InjectDerivedValue(tree, arg) } - def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { - case t @ ReferenceToBoxed(idt0) - if (idt0 == idt) => t - case _ => this.treeCopy.ReferenceToBoxed(tree, idt) - } def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match { case t @ TypeTreeWithDeferredRefCheck() => t case _ => this.treeCopy.TypeTreeWithDeferredRefCheck(tree) @@ -277,9 +235,6 @@ trait Trees extends reflect.internal.Trees { self: Global => case InjectDerivedValue(arg) => transformer.treeCopy.InjectDerivedValue( tree, transformer.transform(arg)) - case ReferenceToBoxed(idt) => - transformer.treeCopy.ReferenceToBoxed( - tree, transformer.transform(idt) match { case idt1: Ident => idt1 }) case TypeTreeWithDeferredRefCheck() => transformer.treeCopy.TypeTreeWithDeferredRefCheck(tree) } @@ -296,8 +251,8 @@ trait Trees extends reflect.internal.Trees { self: Global => // def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x } // def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x } - def resetAllAttrs[A<:Tree](x:A): A = new ResetAttrs(false).transform(x) - def resetLocalAttrs[A<:Tree](x:A): A = new ResetAttrs(true).transform(x) + def resetAllAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(false, leaveAlone).transform(x) + def resetLocalAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone).transform(x) /** A transformer which resets symbol and tpe fields of all nodes in a given tree, * with special treatment of: @@ -308,7 +263,7 @@ trait Trees extends reflect.internal.Trees { self: Global => * * (bq:) This transformer has mutable state and should be discarded after use */ - private class ResetAttrs(localOnly: Boolean) { + private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null) { val debug = settings.debug.value val trace = scala.tools.nsc.util.trace when debug @@ -328,6 +283,12 @@ trait Trees extends reflect.internal.Trees { self: Global => registerLocal(sym) registerLocal(sym.sourceModule) registerLocal(sym.moduleClass) + registerLocal(sym.companionClass) + registerLocal(sym.companionModule) + sym match { + case sym: TermSymbol => registerLocal(sym.referenced) + case _ => ; + } } } @@ -335,10 +296,8 @@ trait Trees extends reflect.internal.Trees { self: Global => tree match { case _: DefTree | Function(_, _) | Template(_, _, _) => markLocal(tree) - case _ if tree.symbol.isInstanceOf[FreeVar] => - markLocal(tree) case _ => - ; + tree } super.traverse(tree) @@ -346,43 +305,48 @@ trait Trees extends reflect.internal.Trees { self: Global => } class Transformer extends self.Transformer { - override def transform(tree: Tree): Tree = super.transform { - tree match { - case tpt: TypeTree => - if (tpt.original != null) { - transform(tpt.original) - } else { - if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol)))) - tpt.tpe = null - tree + override def transform(tree: Tree): Tree = { + if (leaveAlone != null && leaveAlone(tree)) + tree + else + super.transform { + tree match { + case tpt: TypeTree => + if (tpt.original != null) { + transform(tpt.original) + } else { + if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol)))) + tpt.tpe = null + tree + } + case TypeApply(fn, args) if args map transform exists (_.isEmpty) => + transform(fn) + case This(_) if tree.symbol != null && tree.symbol.isPackageClass => + tree + case EmptyTree => + tree + case _ => + if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol))) + tree.symbol = NoSymbol + tree.tpe = null + tree } - case TypeApply(fn, args) if args map transform exists (_.isEmpty) => - transform(fn) - case This(_) if tree.symbol != null && tree.symbol.isPackageClass => - tree - case EmptyTree => - tree - case _ => - if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol))) - tree.symbol = NoSymbol - tree.tpe = null - tree + } } - } } def transform[T <: Tree](x: T): T = { - new MarkLocals().traverse(x) + if (localOnly) + new MarkLocals().traverse(x) - if (debug) { + if (localOnly && debug) { assert(locals.size == orderedLocals.size) - val eoln = System.getProperty("line.separator") - val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString eoln + val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString EOL trace("locals (%d total): %n".format(orderedLocals.size))(msg) } val x1 = new Transformer().transform(x) - assert(x.getClass isInstance x1) + assert(x.getClass isInstance x1, x1.getClass) x1.asInstanceOf[T] } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index e7e3eaabf5..daabfae6b3 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1771,7 +1771,23 @@ self => * }}} */ def pattern2(): Tree = { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case _ => + ; + } + } + val p = pattern3() + warnIfMacro(p) + if (in.token != AT) p else p match { case Ident(nme.WILDCARD) => @@ -2421,10 +2437,10 @@ self => */ /** {{{ - * FunDef ::= FunSig `:' Type `=' Expr - * | FunSig [nl] `{' Block `}' - * | this ParamClause ParamClauses (`=' ConstrExpr | [nl] ConstrBlock) - * | `macro' FunSig [`:' Type] `=' Expr + * FunDef ::= FunSig [`:' Type] `=' [`macro'] Expr + * | FunSig [nl] `{' Block `}' + * | `this' ParamClause ParamClauses + * (`=' ConstrExpr | [nl] ConstrBlock) * FunDcl ::= FunSig [`:' Type] * FunSig ::= id [FunTypeParamClause] ParamClauses * }}} @@ -2444,18 +2460,16 @@ self => } else { val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = ident() - if (name == nme.macro_ && isIdent && settings.Xmacros.value) - funDefRest(start, in.offset, mods | Flags.MACRO, ident()) - else - funDefRest(start, nameOffset, mods, name) + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + funDefRest(start, nameOffset, mods, name) } } def funDefRest(start: Int, nameOffset: Int, mods: Modifiers, name: Name): Tree = { val result = atPos(start, if (name.toTermName == nme.ERROR) start else nameOffset) { - val isMacro = mods hasFlag Flags.MACRO - val isTypeMacro = isMacro && name.isTypeName var newmods = mods // contextBoundBuf is for context bounded type parameters of the form // [T : B] or [T : => B]; it contains the equivalent implicit parameter type, @@ -2463,12 +2477,10 @@ self => val contextBoundBuf = new ListBuffer[Tree] val tparams = typeParamClauseOpt(name, contextBoundBuf) val vparamss = paramClauses(name, contextBoundBuf.toList, false) - if (!isMacro) newLineOptWhenFollowedBy(LBRACE) - var restype = if (isTypeMacro) TypeTree() else fromWithinReturnType(typedOpt()) - val rhs = - if (isMacro) - equalsExpr() - else if (isStatSep || in.token == RBRACE) { + newLineOptWhenFollowedBy(LBRACE) + var restype = fromWithinReturnType(typedOpt()) + val rhs = + if (isStatSep || in.token == RBRACE) { if (restype.isEmpty) restype = scalaUnitConstr newmods |= Flags.DEFERRED EmptyTree @@ -2476,10 +2488,12 @@ self => restype = scalaUnitConstr blockExpr() } else { - if (name == nme.macro_ && isIdent && in.token != EQUALS) { - warning("this syntactically invalid code resembles a macro definition. have you forgotten to enable -Xmacros?") + accept(EQUALS) + if (settings.Xmacros.value && in.token == MACRO) { + in.nextToken() + newmods |= Flags.MACRO } - equalsExpr() + expr() } DefDef(newmods, name, tparams, vparamss, restype, rhs) } @@ -2529,7 +2543,7 @@ self => /** {{{ * TypeDef ::= type Id [TypeParamClause] `=' Type - * | `macro' FunSig `=' Expr + * | FunSig `=' Expr * TypeDcl ::= type Id [TypeParamClause] TypeBounds * }}} */ @@ -2537,22 +2551,22 @@ self => in.nextToken() newLinesOpt() atPos(start, in.offset) { + val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = identForType() - if (name == nme.macro_.toTypeName && isIdent && settings.Xmacros.value) { - funDefRest(start, in.offset, mods | Flags.MACRO, identForType()) - } else { - // @M! a type alias as well as an abstract type may declare type parameters - val tparams = typeParamClauseOpt(name, null) - in.token match { - case EQUALS => - in.nextToken() - TypeDef(mods, name, tparams, typ()) - case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE => - TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds()) - case _ => - syntaxErrorOrIncomplete("`=', `>:', or `<:' expected", true) - EmptyTree - } + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + // @M! a type alias as well as an abstract type may declare type parameters + val tparams = typeParamClauseOpt(name, null) + in.token match { + case EQUALS => + in.nextToken() + TypeDef(mods, name, tparams, typ()) + case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE => + TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds()) + case _ => + syntaxErrorOrIncomplete("`=', `>:', or `<:' expected", true) + EmptyTree } } } @@ -2599,7 +2613,10 @@ self => def classDef(start: Int, mods: Modifiers): ClassDef = { in.nextToken val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = identForType() + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") atPos(start, if (name == tpnme.ERROR) start else nameOffset) { savingClassContextBounds { @@ -2640,7 +2657,10 @@ self => def objectDef(start: Int, mods: Modifiers): ModuleDef = { in.nextToken val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = ident() + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") val tstart = in.offset atPos(start, if (name == nme.ERROR) start else nameOffset) { val mods1 = if (in.token == SUBTYPE) mods | Flags.DEFERRED else mods @@ -2818,7 +2838,25 @@ self => * }}} */ def packaging(start: Int): Tree = { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case Select(qual, name) => + warnIfMacro(qual) + check(name) + case _ => + ; + } + } + val pkg = pkgQualId() + warnIfMacro(pkg) val stats = inBracesOrNil(topStatSeq()) makePackaging(start, pkg, stats) } @@ -3020,8 +3058,29 @@ self => ts ++= topStatSeq() } } else { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + // [Eugene] pkgQualId never returns BackQuotedIdents + // this means that we'll get spurious warnings even if we wrap macro package name in backquotes + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case Select(qual, name) => + warnIfMacro(qual) + check(name) + case _ => + ; + } + } + in.flushDoc val pkg = pkgQualId() + warnIfMacro(pkg) + if (in.token == EOF) { ts += makePackaging(start, pkg, List()) } else if (isStatSep) { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 2895d02dfe..81d81a4fb7 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -1125,7 +1125,8 @@ trait Scanners extends ScannersCommon { nme.SUPERTYPEkw -> SUPERTYPE, nme.HASHkw -> HASH, nme.ATkw -> AT - ) + ) ++ + (if (settings.Xmacros.value) List(nme.MACROkw -> MACRO) else List()) private var kwOffset: Int = -1 private val kwArray: Array[Int] = { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index fb4daefd57..e17bbf5e46 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -110,6 +110,7 @@ object Tokens extends Tokens { final val MATCH = 58 final val FORSOME = 59 final val LAZY = 61 + final val MACRO = 62 def isKeyword(code: Int) = code >= IF && code <= LAZY diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index be1e466f4e..c04be1721e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -651,7 +651,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with case StringTag => buf put 's'.toByte buf putShort cpool.addUtf8(const.stringValue).toShort - case ClassTag => + case ClazzTag => buf put 'c'.toByte buf putShort cpool.addUtf8(javaType(const.typeValue).getSignature()).toShort case EnumTag => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala index b74981b999..807a3dd0bb 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala @@ -121,7 +121,7 @@ trait GenJVMUtil { case DoubleTag => jcode emitPUSH const.doubleValue case StringTag => jcode emitPUSH const.stringValue case NullTag => jcode.emitACONST_NULL() - case ClassTag => + case ClazzTag => val kind = toTypeKind(const.typeValue) val toPush = if (kind.isValueType) classLiteral(kind) diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 2fb615f893..98c1fc2f63 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -365,7 +365,7 @@ abstract class GenMSIL extends SubComponent { arr.foreach(emitConst) } - // TODO: other Tags: NoTag, UnitTag, ClassTag, EnumTag, ArrayTag ??? + // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag, ArrayTag ??? case _ => abort("could not handle attribute argument: " + const) } @@ -388,7 +388,7 @@ abstract class GenMSIL extends SubComponent { case DoubleTag => buf.put(0x0d.toByte) case StringTag => buf.put(0x0e.toByte) - // TODO: other Tags: NoTag, UnitTag, ClassTag, EnumTag ??? + // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag ??? // ArrayTag falls in here case _ => abort("could not handle attribute argument: " + c) @@ -968,7 +968,7 @@ abstract class GenMSIL extends SubComponent { case DoubleTag => mcode.Emit(OpCodes.Ldc_R8, const.doubleValue) case StringTag => mcode.Emit(OpCodes.Ldstr, const.stringValue) case NullTag => mcode.Emit(OpCodes.Ldnull) - case ClassTag => + case ClazzTag => mcode.Emit(OpCodes.Ldtoken, msilType(const.typeValue)) mcode.Emit(OpCodes.Call, TYPE_FROM_HANDLE) case _ => abort("Unknown constant value: " + const) diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 5b298b3761..12a3c4b3c6 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -957,7 +957,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") if (ownerTpe.isErroneous) List() else new ImplicitSearch( tree, functionType(List(ownerTpe), AnyClass.tpe), isView = true, - context.makeImplicit(reportAmbiguousErrors = false)).allImplicits + context0 = context.makeImplicit(reportAmbiguousErrors = false)).allImplicits for (view <- applicableViews) { val vtree = viewApply(view) val vpre = stabilizedType(vtree) diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala index 88e3827403..72e5ee42ed 100644 --- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package interactive import ast.Trees -import symtab.Positions +import ast.Positions import scala.tools.nsc.util.{SourceFile, Position, RangePosition, NoPosition, WorkScheduler} import scala.collection.mutable.ListBuffer diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 0c64bb2901..c0f7d8412a 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -13,6 +13,7 @@ import scala.sys.BooleanProp import io.VirtualDirectory import scala.tools.nsc.io.AbstractFile import reporters._ +import reporters.{Reporter => NscReporter} import symtab.Flags import scala.reflect.internal.Names import scala.tools.util.PathResolver @@ -274,7 +275,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends protected def createLineManager(classLoader: ClassLoader): Line.Manager = new Line.Manager(classLoader) /** Instantiate a compiler. Overridable. */ - protected def newCompiler(settings: Settings, reporter: Reporter) = { + protected def newCompiler(settings: Settings, reporter: NscReporter) = { settings.outputDirs setSingleOutput virtualDirectory settings.exposeEmptyPackage.value = true @@ -340,7 +341,14 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def getInterpreterClassLoader() = classLoader // Set the current Java "context" class loader to this interpreter's class loader - def setContextClassLoader() = classLoader.setAsContext() + def setContextClassLoader() = { + classLoader.setAsContext() + + // this is risky, but it's our only possibility to make default reflexive mirror to work with REPL + // so far we have only used the default mirror to create a few manifests for the compiler + // so it shouldn't be in conflict with our classloader, especially since it respects its parent + scala.reflect.mirror.classLoader = classLoader + } /** Given a simple repl-defined name, returns the real name of * the class representing it, e.g. for "Bippy" it may return diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index 14876425f4..cc06100f5f 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -6,7 +6,6 @@ package scala.tools.nsc package interpreter -import scala.reflect.AnyValManifest import scala.collection.{ mutable, immutable } import scala.util.matching.Regex import scala.tools.nsc.util.{ BatchSourceFile } diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index ad6e8dc48d..e293c0fed9 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -58,7 +58,7 @@ object ReplVals { * I have this forwarder which widens the type and then cast the result back * to the dependent type. */ - def manifestToType(m: OptManifest[_]): Global#Type = + def manifestToType(m: Manifest[_]): Global#Type = definitions.manifestToType(m) class AppliedTypeFromManifests(sym: Symbol) { diff --git a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala index 5edc8fd202..59a7b9b5d2 100644 --- a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala +++ b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package interpreter class RichClass[T](val clazz: Class[T]) { - def toManifest: Manifest[T] = Manifest.classType(clazz) + def toManifest: Manifest[T] = Manifest[T](ClassManifest[T](clazz).tpe) def toTypeString: String = TypeStrings.fromClazz(clazz) // Sadly isAnonymousClass does not return true for scala anonymous diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala index 6b56d881fc..872ac00bfd 100644 --- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala @@ -10,6 +10,7 @@ import java.lang.{ reflect => r } import r.TypeVariable import scala.reflect.NameTransformer import NameTransformer._ +import scala.reflect.{mirror => rm} /** Logic for turning a type into a String. The goal is to be * able to take some arbitrary object 'x' and obtain the most precise @@ -72,8 +73,12 @@ trait TypeStrings { brackets(clazz.getTypeParameters map tvarString: _*) } - private def tparamString[T: Manifest] : String = - brackets(manifest[T].typeArguments map (m => tvarString(List(m.erasure))): _*) + private def tparamString[T: Manifest] : String = { + // [Eugene to Paul] needs review!! + def typeArguments: List[rm.Type] = manifest[T].tpe.typeArguments + def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => rm.typeToClass(targ)) + brackets(typeArguments map (jc => tvarString(List(jc))): _*) + } /** Going for an overabundance of caution right now. Later these types * can be a lot more precise, but right now the manifests have a habit of diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala index 2ba8c8eb6b..ab8fe23909 100644 --- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala @@ -35,17 +35,22 @@ abstract class AbstractReporter extends Reporter { else _severity if (severity == INFO) { - if (isVerbose || force) + if (isVerbose || force) { + severity.count += 1 display(pos, msg, severity) + } } else { val hidden = testAndLog(pos, severity) if (severity == WARNING && noWarnings) () else { - if (!hidden || isPromptSet) + if (!hidden || isPromptSet) { + severity.count += 1 display(pos, msg, severity) - else if (settings.debug.value) + } else if (settings.debug.value) { + severity.count += 1 display(pos, "[ suppressed ] " + msg, severity) + } if (isPromptSet) displayPrompt diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala index f5335fb0f5..956c43c35a 100644 --- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala @@ -75,7 +75,6 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr } def display(pos: Position, msg: String, severity: Severity) { - severity.count += 1 if (severity != ERROR || severity.count <= ERROR_LIMIT) print(pos, msg, severity) } diff --git a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala index ff0f94d897..8a918a829c 100644 --- a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala +++ b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala @@ -28,7 +28,7 @@ object Executor { Console.setOut(newOut) Console.setErr(newOut) try { - singletonInstance(name, classLoader) + singletonInstance(classLoader, name) } catch { case ex: Throwable => unwrapThrowable(ex) match { diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index e7959f36b2..ea12300785 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -28,7 +28,7 @@ class MutableSettings(val errorFn: String => Unit) settings } - protected def copyInto(settings: MutableSettings) { + def copyInto(settings: MutableSettings) { allSettings foreach { thisSetting => val otherSetting = settings.allSettings find { _.name == thisSetting.name } otherSetting foreach { otherSetting => diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 14b3bcc8ce..e9a7e3dab4 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -80,6 +80,9 @@ trait ScalaSettings extends AbsScalaSettings val XlogImplicits = BooleanSetting ("-Xlog-implicits", "Show more detail on why some implicits are not applicable.") val logImplicitConv = BooleanSetting ("-Xlog-implicit-conversions", "Print a message whenever an implicit conversion is inserted.") val logReflectiveCalls = BooleanSetting("-Xlog-reflective-calls", "Print a message when a reflective method call is generated") + val logRuntimeSplices = BooleanSetting("-Xlog-runtime-splices", "Print a message when Expr.eval or Expr.value cannot be resolved statically.") + val logFreeTerms = BooleanSetting ("-Xlog-free-terms", "Print a message when reification creates a free term.") + val logFreeTypes = BooleanSetting ("-Xlog-free-types", "Print a message when reification resorts to generating a free type.") val maxClassfileName = IntSetting ("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, Some((72, 255)), _ => None) val Xmigration28 = BooleanSetting ("-Xmigration", "Warn about constructs whose behavior may have changed between 2.7 and 2.8.") val nouescape = BooleanSetting ("-Xno-uescape", "Disable handling of \\u unicode escapes.") @@ -116,62 +119,62 @@ trait ScalaSettings extends AbsScalaSettings /** * -Y "Private" settings */ - val overrideObjects = BooleanSetting ("-Yoverride-objects", "Allow member objects to be overridden.") - val overrideVars = BooleanSetting ("-Yoverride-vars", "Allow vars to be overridden.") - val Yhelp = BooleanSetting ("-Y", "Print a synopsis of private options.") - val browse = PhasesSetting ("-Ybrowse", "Browse the abstract syntax tree after") - val check = PhasesSetting ("-Ycheck", "Check the tree at the end of") - val Yshow = PhasesSetting ("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after") - val Xcloselim = BooleanSetting ("-Yclosure-elim", "Perform closure elimination.") - val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.") - val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL.") - val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination.") - val debug = BooleanSetting ("-Ydebug", "Increase the quantity of debugging output.") - // val doc = BooleanSetting ("-Ydoc", "Generate documentation") - val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", - List("package", "object", "error"), "error") - val inline = BooleanSetting ("-Yinline", "Perform inlining when possible.") - val inlineHandlers= BooleanSetting ("-Yinline-handlers", "Perform exception handler inlining when possible.") - val Xlinearizer = ChoiceSetting ("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo") - val log = PhasesSetting ("-Ylog", "Log operations during") - val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.") - val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.") - val noimports = BooleanSetting ("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.") - val nopredef = BooleanSetting ("-Yno-predef", "Compile without importing Predef.") - val noAdaptedArgs = BooleanSetting ("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.") - val Yprofile = PhasesSetting ("-Yprofile", "(Requires jvm -agentpath to contain yjgpagent) Profile CPU usage of") - val YprofileMem = BooleanSetting ("-Yprofile-memory", "Profile memory, get heap snapshot after each compiler run (requires yjpagent, see above).") - val YprofileClass = StringSetting ("-Yprofile-class", "class", "Name of profiler class.", "scala.tools.util.YourkitProfiling") - val Yrecursion = IntSetting ("-Yrecursion", "Set recursion depth used when locking symbols.", 0, Some((0, Int.MaxValue)), (_: String) => None) - val selfInAnnots = BooleanSetting ("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.") - val Xshowtrees = BooleanSetting ("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs.") - val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.") - val Yshowsymkinds = BooleanSetting ("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.") - val skip = PhasesSetting ("-Yskip", "Skip") - val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "") - val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "") - val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.") - val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") andThen (util.Statistics.enabled = _) - val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat - val stopBefore = PhasesSetting ("-Ystop-before", "Stop before") - val refinementMethodDispatch = - ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy", - List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") - val globalClass = StringSetting ("-Yglobal-class", "class", "subclass of scala.tools.nsc.Global to use for compiler", "") - val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") - val YrichExes = BooleanSetting ("-Yrich-exceptions", - "Fancier exceptions. Set source search path with -D" + - sys.SystemProperties.traceSourcePath.key) - val Ybuilderdebug = ChoiceSetting("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none") - val Yreifycopypaste = - BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") - val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") - val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.") - val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") - val etaExpandKeepsStar = BooleanSetting("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") - val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") - val YvirtPatmat = BooleanSetting ("-Yvirtpatmat", "Translate pattern matches into flatMap/orElse calls. See scala.MatchingStrategy.") - val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") + val overrideObjects = BooleanSetting ("-Yoverride-objects", "Allow member objects to be overridden.") + val overrideVars = BooleanSetting ("-Yoverride-vars", "Allow vars to be overridden.") + val Yhelp = BooleanSetting ("-Y", "Print a synopsis of private options.") + val browse = PhasesSetting ("-Ybrowse", "Browse the abstract syntax tree after") + val check = PhasesSetting ("-Ycheck", "Check the tree at the end of") + val Yshow = PhasesSetting ("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after") + val Xcloselim = BooleanSetting ("-Yclosure-elim", "Perform closure elimination.") + val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.") + val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL.") + val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination.") + val debug = BooleanSetting ("-Ydebug", "Increase the quantity of debugging output.") + //val doc = BooleanSetting ("-Ydoc", "Generate documentation") + val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error") + val inline = BooleanSetting ("-Yinline", "Perform inlining when possible.") + val inlineHandlers = BooleanSetting ("-Yinline-handlers", "Perform exception handler inlining when possible.") + val Xlinearizer = ChoiceSetting ("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo") + val log = PhasesSetting ("-Ylog", "Log operations during") + val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.") + val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.") + val noimports = BooleanSetting ("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.") + val nopredef = BooleanSetting ("-Yno-predef", "Compile without importing Predef.") + val noAdaptedArgs = BooleanSetting ("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.") + val Yprofile = PhasesSetting ("-Yprofile", "(Requires jvm -agentpath to contain yjgpagent) Profile CPU usage of") + val YprofileMem = BooleanSetting ("-Yprofile-memory", "Profile memory, get heap snapshot after each compiler run (requires yjpagent, see above).") + val YprofileClass = StringSetting ("-Yprofile-class", "class", "Name of profiler class.", "scala.tools.util.YourkitProfiling") + val Yrecursion = IntSetting ("-Yrecursion", "Set recursion depth used when locking symbols.", 0, Some((0, Int.MaxValue)), (_: String) => None) + val selfInAnnots = BooleanSetting ("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.") + val Xshowtrees = BooleanSetting ("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs in formatted form.") + val XshowtreesCompact + = BooleanSetting ("-Yshow-trees-compact", "(Requires -Xprint:) Print detailed ASTs in compact form.") + val XshowtreesStringified + = BooleanSetting ("-Yshow-trees-stringified", "(Requires -Xprint:) Print stringifications along with detailed ASTs.") + val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.") + val Yshowsymkinds = BooleanSetting ("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.") + val skip = PhasesSetting ("-Yskip", "Skip") + val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "") + val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "") + val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.") + val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") andThen (util.Statistics.enabled = _) + val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat + val stopBefore = PhasesSetting ("-Ystop-before", "Stop before") + val refinementMethodDispatch + = ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") + val globalClass = StringSetting ("-Yglobal-class", "class", "subclass of scala.tools.nsc.Global to use for compiler", "") + val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") + val YrichExes = BooleanSetting ("-Yrich-exceptions", "Fancier exceptions. Set source search path with -D" + sys.SystemProperties.traceSourcePath.key) + val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none") + val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") + val Ymacrocopypaste = BooleanSetting ("-Ymacro-copypaste", "Dump macro expansions in copypasteable representation.") + val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") + val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.") + val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") + val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") + val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") + val YvirtPatmat = BooleanSetting ("-Yvirtpatmat", "Translate pattern matches into flatMap/orElse calls. See scala.MatchingStrategy.") + val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") val exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() val YnoProductN = BooleanSetting ("-Yno-productN", "Do not add ProductN to case classes") @@ -180,26 +183,30 @@ trait ScalaSettings extends AbsScalaSettings /** Area-specific debug output. */ - val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.") - val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.") - val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.") - val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.") - val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.") - val Ymacrodebug = BooleanSetting("-Ymacro-debug", "Trace macro-related activities: generation of synthetics, expansion, exceptions.") - val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.") - val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.") - val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.") - val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.") andThen (interpreter.replProps.debug setValue _) - val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.") + val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.") + val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.") + val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.") + val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.") + val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.") + val Yissuedebug = BooleanSetting("-Yissue-debug", "Print stack traces when a context issues an error.") + val Ymacrodebug = BooleanSetting("-Ymacro-debug", "Trace macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions.") + val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.") + val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.") + val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.") + val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.") andThen (interpreter.replProps.debug setValue _) + val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.") /** Groups of Settings. */ - val future = BooleanSetting ("-Xfuture", "Turn on future language features.") enabling futureSettings - val optimise = BooleanSetting ("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize" enabling optimiseSettings - val Xexperimental = BooleanSetting ("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings + val future = BooleanSetting("-Xfuture", "Turn on future language features.") enabling futureSettings + val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize" enabling optimiseSettings + val Xexperimental = BooleanSetting("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings // Feature extensions - val Xmacros = BooleanSetting ("-Xmacros", "Enable macros.") + val Xmacros = BooleanSetting("-Xmacros", "Enable macros.") + val XmacroSettings = MultiStringSetting("-Xmacro-settings", "option", "Custom settings for macros.") + val XmacroPrimaryClasspath = PathSetting("-Xmacro-primary-classpath", "Classpath to load macros implementations from, defaults to compilation classpath (aka \"library classpath\".", "") + val XmacroFallbackClasspath = PathSetting("-Xmacro-fallback-classpath", "Classpath to load macros implementations from if they cannot be loaded from library classpath.", "") /** * IDE-specific settings diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala deleted file mode 100644 index 94b619de90..0000000000 --- a/src/compiler/scala/tools/nsc/symtab/Positions.scala +++ /dev/null @@ -1,30 +0,0 @@ -package scala.tools.nsc -package symtab - -import scala.tools.nsc.util.{ SourceFile, Position, OffsetPosition, NoPosition } - -trait Positions extends scala.reflect.internal.Positions { -self: scala.tools.nsc.symtab.SymbolTable => - - def rangePos(source: SourceFile, start: Int, point: Int, end: Int) = - new OffsetPosition(source, point) - - def validatePositions(tree: Tree) {} - - type Position = scala.tools.nsc.util.Position - val NoPosition = scala.tools.nsc.util.NoPosition - - type TreeAnnotation = scala.tools.nsc.util.TreeAnnotation - def NoTreeAnnotation: TreeAnnotation = NoPosition - def positionToAnnotation(pos: Position): TreeAnnotation = pos - def annotationToPosition(annot: TreeAnnotation): Position = annot.pos - override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = { - if (tree.pos != NoPosition && tree.pos != annot.pos) debugwarn("Overwriting annotation "+ tree.annotation +" of tree "+ tree +" with annotation "+ annot) - // if ((tree.annotation.isInstanceOf[scala.tools.nsc.util.Position] || !annot.isInstanceOf[scala.tools.nsc.util.Position]) && tree.isInstanceOf[Block]) - // println("Updating block from "+ tree.annotation +" to "+ annot) - } - def focusPos(pos: Position): Position = pos.focus - def isRangePos(pos: Position): Boolean = pos.isRange - def showPos(pos: Position): String = pos.show - -} diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 758f870d6b..edbe6df472 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -425,7 +425,7 @@ abstract class Pickler extends SubComponent { private def putConstant(c: Constant) { if (putEntry(c)) { if (c.tag == StringTag) putEntry(newTermName(c.stringValue)) - else if (c.tag == ClassTag) putType(c.typeValue) + else if (c.tag == ClazzTag) putType(c.typeValue) else if (c.tag == EnumTag) putSymbol(c.symbolValue) } } @@ -606,7 +606,7 @@ abstract class Pickler extends SubComponent { else if (c.tag == FloatTag) writeLong(floatToIntBits(c.floatValue)) else if (c.tag == DoubleTag) writeLong(doubleToLongBits(c.doubleValue)) else if (c.tag == StringTag) writeRef(newTermName(c.stringValue)) - else if (c.tag == ClassTag) writeRef(c.typeValue) + else if (c.tag == ClazzTag) writeRef(c.typeValue) else if (c.tag == EnumTag) writeRef(c.symbolValue) LITERAL + c.tag // also treats UnitTag, NullTag; no value required case AnnotatedType(annotations, tp, selfsym) => @@ -1059,7 +1059,7 @@ abstract class Pickler extends SubComponent { else if (c.tag == FloatTag) print("Float "+c.floatValue) else if (c.tag == DoubleTag) print("Double "+c.doubleValue) else if (c.tag == StringTag) { print("String "); printRef(newTermName(c.stringValue)) } - else if (c.tag == ClassTag) { print("Class "); printRef(c.typeValue) } + else if (c.tag == ClazzTag) { print("Class "); printRef(c.typeValue) } else if (c.tag == EnumTag) { print("Enum "); printRef(c.symbolValue) } case AnnotatedType(annots, tp, selfsym) => if (settings.selfInAnnots.value) { diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 97e844f6d8..5a11926048 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -179,7 +179,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => /** If `tp` refers to a non-interface trait, return a * reference to its implementation class. Otherwise return `tp`. */ - def mixinToImplClass(tp: Type): Type = erasure(implSym) { + def mixinToImplClass(tp: Type): Type = AddInterfaces.this.erasure(implSym) { tp match { //@MATN: no normalize needed (comes after erasure) case TypeRef(pre, sym, _) if sym.needsImplClass => typeRef(pre, implClass(sym), Nil) diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index e6f5dc5b5f..eea87c8ba6 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -542,7 +542,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { if (forMSIL) savingStatics( transformTemplate(tree) ) else transformTemplate(tree) - case Literal(c) if (c.tag == ClassTag) && !forMSIL=> + case Literal(c) if (c.tag == ClazzTag) && !forMSIL=> val tpe = c.typeValue typedWithPos(tree.pos) { if (isPrimitiveValueClass(tpe.typeSymbol)) { diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ecfc2b6084..e2ce3b62b4 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -734,7 +734,7 @@ abstract class Erasure extends AddInterfaces /** A replacement for the standard typer's `typed1` method. */ - override protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = { + override def typed1(tree: Tree, mode: Int, pt: Type): Tree = { val tree1 = try { tree match { case InjectDerivedValue(arg) => @@ -1090,7 +1090,7 @@ abstract class Erasure extends AddInterfaces case Match(selector, cases) => Match(Typed(selector, TypeTree(selector.tpe)), cases) - case Literal(ct) if ct.tag == ClassTag + case Literal(ct) if ct.tag == ClazzTag && ct.typeValue.typeSymbol != definitions.UnitClass => val erased = ct.typeValue match { case TypeRef(pre, clazz, args) if clazz.isDerivedValueClass => scalaErasure.eraseNormalClassRef(pre, clazz) diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index f6dc8fbfb0..6bddfe8d57 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -19,19 +19,6 @@ abstract class LambdaLift extends InfoTransform { /** the following two members override abstract members in Transform */ val phaseName: String = "lambdalift" - /** Converts types of captured variables to *Ref types. - */ - def boxIfCaptured(sym: Symbol, tpe: Type, erasedTypes: Boolean) = - if (sym.isCapturedVariable) { - val symClass = tpe.typeSymbol - def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) = - if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe - else if (erasedTypes) objectRefClass.tpe - else appliedType(objectRefClass, tpe) - if (sym.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass) - else refType(refClass, ObjectRefClass) - } else tpe - private val lifted = new TypeMap { def apply(tp: Type): Type = tp match { case TypeRef(NoPrefix, sym, Nil) if sym.isClass && !sym.isPackageClass => @@ -46,7 +33,8 @@ abstract class LambdaLift extends InfoTransform { } def transformInfo(sym: Symbol, tp: Type): Type = - boxIfCaptured(sym, lifted(tp), erasedTypes = true) + if (sym.isCapturedVariable) capturedVariableType(sym, tpe = lifted(tp), erasedTypes = true) + else lifted(tp) protected def newTransformer(unit: CompilationUnit): Transformer = new LambdaLifter(unit) @@ -471,6 +459,8 @@ abstract class LambdaLift extends InfoTransform { private def preTransform(tree: Tree) = super.transform(tree) setType lifted(tree.tpe) override def transform(tree: Tree): Tree = tree match { + case Select(ReferenceToBoxed(idt), elem) if elem == nme.elem => + postTransform(preTransform(idt), isBoxedRef = false) case ReferenceToBoxed(idt) => postTransform(preTransform(idt), isBoxedRef = true) case _ => diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 6d4dab57a3..0e4975c04c 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -1085,7 +1085,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { // add forwarders assert(sym.alias != NoSymbol, sym) // debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString) - addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident))) + if (!sym.isTermMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident))) } } } diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index f90d3d45fe..11f06a0541 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -358,18 +358,18 @@ abstract class UnCurry extends InfoTransform def sequenceToArray(tree: Tree) = { val toArraySym = tree.tpe member nme.toArray assert(toArraySym != NoSymbol) - def getManifest(tp: Type): Tree = { - val manifestOpt = localTyper.findManifest(tp, false) + def getClassTag(tp: Type): Tree = { + val tag = localTyper.resolveClassTag(tree, tp) // Don't want bottom types getting any further than this (SI-4024) - if (tp.typeSymbol.isBottomClass) getManifest(AnyClass.tpe) - else if (!manifestOpt.tree.isEmpty) manifestOpt.tree - else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi) - else localTyper.getManifestTree(tree, tp, false) + if (tp.typeSymbol.isBottomClass) getClassTag(AnyClass.tpe) + else if (!tag.isEmpty) tag + else if (tp.bounds.hi ne tp) getClassTag(tp.bounds.hi) + else localTyper.TyperErrorGen.MissingClassTagError(tree, tp) } afterUncurry { localTyper.typedPos(pos) { Apply(gen.mkAttributedSelect(tree, toArraySym), - List(getManifest(tree.tpe.baseType(TraversableClass).typeArgs.head))) + List(getClassTag(tree.tpe.baseType(TraversableClass).typeArgs.head))) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index ff0bdf7580..b400743469 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -277,11 +277,6 @@ trait ContextErrors { setError(tree) } - def MultiDimensionalArrayError(tree: Tree) = { - issueNormalTypeError(tree, "cannot create a generic multi-dimensional array of more than "+ definitions.MaxArrayDims+" dimensions") - setError(tree) - } - //typedSuper def MixinMissingParentClassNameError(tree: Tree, mix: Name, clazz: Symbol) = issueNormalTypeError(tree, mix+" does not name a parent class of "+clazz) @@ -344,6 +339,11 @@ trait ContextErrors { setError(tree) } + def MacroEtaError(tree: Tree) = { + issueNormalTypeError(tree, "macros cannot be eta-expanded") + setError(tree) + } + //typedReturn def ReturnOutsideOfDefError(tree: Tree) = { issueNormalTypeError(tree, "return outside method definition") @@ -453,6 +453,9 @@ trait ContextErrors { // doTypeApply //tryNamesDefaults + def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) = + NormalTypeError(tree, "macros application do not support named and/or default arguments") + def WrongNumberOfArgsError(tree: Tree, fun: Tree) = NormalTypeError(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun)) @@ -581,9 +584,9 @@ trait ContextErrors { def AbstractExistentiallyOverParamerizedTpeError(tree: Tree, tp: Type) = issueNormalTypeError(tree, "can't existentially abstract over parameterized type " + tp) - //manifestTreee - def MissingManifestError(tree: Tree, full: Boolean, tp: Type) = { - issueNormalTypeError(tree, "cannot find "+(if (full) "" else "class ")+"manifest for element type "+tp) + // classTagTree + def MissingClassTagError(tree: Tree, tp: Type) = { + issueNormalTypeError(tree, "cannot find class tag for element type "+tp) setError(tree) } @@ -622,7 +625,6 @@ trait ContextErrors { def DefDefinedTwiceError(sym0: Symbol, sym1: Symbol) = { val isBug = sym0.isAbstractType && sym1.isAbstractType && (sym0.name startsWith "_$") issueSymbolTypeError(sym0, sym1+" is defined twice in " + context0.unit - + ( if (sym0.isMacro && sym1.isMacro) "\n(note that macros cannot be overloaded)" else "" ) + ( if (isBug) "\n(this error is likely due to a bug in the scala compiler involving wildcards in package objects)" else "" ) ) } @@ -848,6 +850,19 @@ trait ContextErrors { def TypeSigError(tree: Tree, ex: TypeError) = { ex match { + case CyclicReference(_, _) if tree.symbol.isTermMacro => + // say, we have a macro def `foo` and its macro impl `impl` + // if impl: 1) omits return type, 2) has anything implicit in its body, 3) sees foo + // + // then implicit search will trigger an error + // (note that this is not a compilation error, it's an artifact of implicit search algorithm) + // normally, such "errors" are discarded by `isCyclicOrErroneous` in Implicits.scala + // but in our case this won't work, because isCyclicOrErroneous catches CyclicReference exceptions + // while our error will manifest itself as a "recursive method needs a return type" + // + // hence we (together with reportTypeError in TypeDiagnostics) make sure that this CyclicReference + // evades all the handlers on its way and successfully reaches `isCyclicOrErroneous` in Implicits + throw ex case CyclicReference(sym, info: TypeCompleter) => issueNormalTypeError(tree, typer.cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage()) case _ => diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 9b1f395ad0..fe1c90fe67 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -105,8 +105,8 @@ trait Contexts { self: Analyzer => // not inherited to child contexts var depth: Int = 0 var imports: List[ImportInfo] = List() // currently visible imports - var openImplicits: List[(Type,Symbol)] = List() // types for which implicit arguments - // are currently searched + var openImplicits: List[(Type,Tree)] = List() // types for which implicit arguments + // are currently searched // for a named application block (Tree) the corresponding NamedApplyInfo var namedApplyBlockInfo: Option[(Tree, NamedApplyInfo)] = None var prefix: Type = NoPrefix @@ -119,6 +119,7 @@ trait Contexts { self: Analyzer => var diagnostic: List[String] = Nil // these messages are printed when issuing an error var implicitsEnabled = false + var macrosEnabled = true var checking = false var retyping = false @@ -181,6 +182,13 @@ trait Contexts { self: Analyzer => def logError(err: AbsTypeError) = buffer += err + def withImplicitsEnabled[T](op: => T): T = { + val saved = implicitsEnabled + implicitsEnabled = true + try op + finally implicitsEnabled = saved + } + def withImplicitsDisabled[T](op: => T): T = { val saved = implicitsEnabled implicitsEnabled = false @@ -188,6 +196,20 @@ trait Contexts { self: Analyzer => finally implicitsEnabled = saved } + def withMacrosEnabled[T](op: => T): T = { + val saved = macrosEnabled + macrosEnabled = true + try op + finally macrosEnabled = saved + } + + def withMacrosDisabled[T](op: => T): T = { + val saved = macrosEnabled + macrosEnabled = false + try op + finally macrosEnabled = saved + } + def make(unit: CompilationUnit, tree: Tree, owner: Symbol, scope: Scope, imports: List[ImportInfo]): Context = { val c = new Context @@ -223,6 +245,7 @@ trait Contexts { self: Analyzer => c.diagnostic = this.diagnostic c.typingIndentLevel = typingIndentLevel c.implicitsEnabled = this.implicitsEnabled + c.macrosEnabled = this.macrosEnabled c.checking = this.checking c.retyping = this.retyping c.openImplicits = this.openImplicits @@ -237,6 +260,7 @@ trait Contexts { self: Analyzer => val c = make(unit, EmptyTree, owner, scope, imports) c.setReportErrors() c.implicitsEnabled = true + c.macrosEnabled = true c } @@ -312,6 +336,7 @@ trait Contexts { self: Analyzer => def issue(err: AbsTypeError) { debugwarn("issue error: " + err.errMsg) + if (settings.Yissuedebug.value) (new Exception).printStackTrace() if (reportErrors) unitError(err.errPos, addDiagString(err.errMsg)) else if (bufferErrors) { buffer += err } else throw new TypeError(err.errPos, err.errMsg) @@ -319,6 +344,7 @@ trait Contexts { self: Analyzer => def issueAmbiguousError(pre: Type, sym1: Symbol, sym2: Symbol, err: AbsTypeError) { debugwarn("issue ambiguous error: " + err.errMsg) + if (settings.Yissuedebug.value) (new Exception).printStackTrace() if (ambiguousErrors) { if (!pre.isErroneous && !sym1.isErroneous && !sym2.isErroneous) unitError(err.errPos, err.errMsg) @@ -328,6 +354,7 @@ trait Contexts { self: Analyzer => def issueAmbiguousError(err: AbsTypeError) { debugwarn("issue ambiguous error: " + err.errMsg) + if (settings.Yissuedebug.value) (new Exception).printStackTrace() if (ambiguousErrors) unitError(err.errPos, addDiagString(err.errMsg)) else if (bufferErrors) { buffer += err } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 75440a1136..8aa257983a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -32,7 +32,10 @@ trait Implicits { import global.typer.{ printTyping, deindentTyping, indentTyping, printInference } def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context): SearchResult = - inferImplicit(tree, pt, reportAmbiguous, isView, context, true) + inferImplicit(tree, pt, reportAmbiguous, isView, context, true, NoPosition) + + def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult = + inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, NoPosition) /** Search for an implicit value. See the comment on `result` at the end of class `ImplicitSearch` * for more info how the search is conducted. @@ -48,9 +51,12 @@ trait Implicits { * @param saveAmbiguousDivergent False if any divergent/ambiguous errors should be ignored after * implicits search, * true if they should be reported (used in further typechecking). + * @param pos Position that is should be used for tracing and error reporting + * (useful when we infer synthetic stuff and pass EmptyTree in the `tree` argument) + * If it's set NoPosition, then position-based services will use `tree.pos` * @return A search result */ - def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult = { + def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean, pos: Position): SearchResult = { printInference("[infer %s] %s with pt=%s in %s".format( if (isView) "view" else "implicit", tree, pt, context.owner.enclClass) @@ -71,9 +77,11 @@ trait Implicits { if (printInfers && !tree.isEmpty && !context.undetparams.isEmpty) printTyping("typing implicit: %s %s".format(tree, context.undetparamsString)) val implicitSearchContext = context.makeImplicit(reportAmbiguous) - val result = new ImplicitSearch(tree, pt, isView, implicitSearchContext).bestImplicit - if (saveAmbiguousDivergent && implicitSearchContext.hasErrors) + val result = new ImplicitSearch(tree, pt, isView, implicitSearchContext, pos).bestImplicit + if (saveAmbiguousDivergent && implicitSearchContext.hasErrors) { context.updateBuffer(implicitSearchContext.errBuffer.filter(err => err.kind == ErrorKinds.Ambiguous || err.kind == ErrorKinds.Divergent)) + debugwarn("update buffer: " + implicitSearchContext.errBuffer) + } printInference("[infer implicit] inferred " + result) context.undetparams = context.undetparams filterNot result.subst.from.contains @@ -100,8 +108,6 @@ trait Implicits { improvesCache.clear() } - private val ManifestSymbols = Set(PartialManifestClass, FullManifestClass, OptManifestClass) - /* Map a polytype to one in which all type parameters and argument-dependent types are replaced by wildcards. * Consider `implicit def b(implicit x: A): x.T = error("")`. We need to approximate DebruijnIndex types * when checking whether `b` is a valid implicit, as we haven't even searched a value for the implicit arg `x`, @@ -251,8 +257,11 @@ trait Implicits { * @param pt The original expected type of the implicit. * @param isView We are looking for a view * @param context0 The context used for the implicit search + * @param pos0 Position that is preferable for use in tracing and error reporting + * (useful when we infer synthetic stuff and pass EmptyTree in the `tree` argument) + * If it's set to NoPosition, then position-based services will use `tree.pos` */ - class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context) + class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context, pos0: Position = NoPosition) extends Typer(context0) with ImplicitsContextErrors { printTyping( ptBlock("new ImplicitSearch", @@ -264,6 +273,13 @@ trait Implicits { ) ) // assert(tree.isEmpty || tree.pos.isDefined, tree) + def pos = if (pos0 != NoPosition) pos0 else tree.pos + + def failure(what: Any, reason: String, pos: Position = this.pos): SearchResult = { + if (settings.XlogImplicits.value) + reporter.echo(pos, what+" is not a valid implicit value for "+pt+" because:\n"+reason) + SearchFailure + } import infer._ /** Is implicit info `info1` better than implicit info `info2`? @@ -351,13 +367,13 @@ trait Implicits { * @pre `info.tpe` does not contain an error */ private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean): SearchResult = { - (context.openImplicits find { case (tp, sym) => sym == tree.symbol && dominates(pt, tp)}) match { + (context.openImplicits find { case (tp, tree1) => tree1.symbol == tree.symbol && dominates(pt, tp)}) match { case Some(pending) => // println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG throw DivergentImplicit case None => try { - context.openImplicits = (pt, tree.symbol) :: context.openImplicits + context.openImplicits = (pt, tree) :: context.openImplicits // println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt) //@MDEBUG typedImplicit0(info, ptChecked) } catch { @@ -515,7 +531,7 @@ trait Implicits { private def typedImplicit1(info: ImplicitInfo): SearchResult = { incCounter(matchingImplicits) - val itree = atPos(tree.pos.focus) { + val itree = atPos(pos.focus) { if (info.pre == NoPrefix) Ident(info.name) else Select(gen.mkAttributedQualifier(info.pre), info.name) } @@ -523,11 +539,7 @@ trait Implicits { typeDebug.ptTree(itree), wildPt, info.name, info.tpe) ) - def fail(reason: String): SearchResult = { - if (settings.XlogImplicits.value) - inform(itree+" is not a valid implicit value for "+pt+" because:\n"+reason) - SearchFailure - } + def fail(reason: String): SearchResult = failure(itree, reason) try { val itree1 = if (isView) { @@ -707,6 +719,7 @@ trait Implicits { info.isCyclicOrErroneous || isView && isPredefMemberNamed(info.sym, nme.conforms) || isShadowed(info.name) + || (!context.macrosEnabled && info.sym.isTermMacro) ) /** True if a given ImplicitInfo (already known isValid) is eligible. @@ -825,7 +838,7 @@ trait Implicits { throw DivergentImplicit if (invalidImplicits.nonEmpty) - setAddendum(tree.pos, () => + setAddendum(pos, () => "\n Note: implicit "+invalidImplicits.head+" is not applicable here"+ " because it comes after the application point and it lacks an explicit result type") } @@ -1085,111 +1098,58 @@ trait Implicits { implicitInfoss1 } - /** Creates a tree that calls the relevant factory method in object - * reflect.Manifest for type 'tp'. An EmptyTree is returned if - * no manifest is found. todo: make this instantiate take type params as well? - */ - private def manifestOfType(tp: Type, full: Boolean): SearchResult = { - - /** Creates a tree that calls the factory method called constructor in object reflect.Manifest */ - def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree = - if (args contains EmptyTree) EmptyTree - else typedPos(tree.pos.focus) { - val mani = gen.mkManifestFactoryCall(full, constructor, tparg, args.toList) - if (settings.debug.value) println("generated manifest: "+mani) // DEBUG - mani - } + // these should be lazy, otherwise we wouldn't be able to compile scala-library with starr + private val TagSymbols = Set(ClassTagClass, TypeTagClass, GroundTypeTagClass) + private val TagMaterializers = Map( + ClassTagClass -> MacroInternal_materializeClassTag, + TypeTagClass -> MacroInternal_materializeTypeTag, + GroundTypeTagClass -> MacroInternal_materializeGroundTypeTag + ) - /** Creates a tree representing one of the singleton manifests.*/ - def findSingletonManifest(name: String) = typedPos(tree.pos.focus) { - Select(gen.mkAttributedRef(FullManifestModule), name) - } + def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = { + def success(arg: Tree) = + try { + val tree1 = typed(atPos(pos.focus)(arg)) + def isErroneous = tree exists (_.isErroneous) + if (context.hasErrors) failure(tp, "failed to typecheck the materialized typetag: %n%s".format(context.errBuffer.head.errMsg), context.errBuffer.head.errPos) + else new SearchResult(tree1, EmptyTreeTypeSubstituter) + } catch { + case ex: TypeError => + failure(arg, "failed to typecheck the materialized typetag: %n%s".format(ex.msg), ex.pos) + } - /** Re-wraps a type in a manifest before calling inferImplicit on the result */ - def findManifest(tp: Type, manifestClass: Symbol = if (full) FullManifestClass else PartialManifestClass) = - inferImplicit(tree, appliedType(manifestClass, tp), true, false, context).tree - - def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass) - def mot(tp0: Type, from: List[Symbol], to: List[Type]): SearchResult = { - implicit def wrapResult(tree: Tree): SearchResult = - if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to)) - - val tp1 = tp0.normalize - tp1 match { - case ThisType(_) | SingleType(_, _) => - // can't generate a reference to a value that's abstracted over by an existential - if (containsExistential(tp1)) EmptyTree - else manifestFactoryCall("singleType", tp, gen.mkAttributedQualifier(tp1)) - case ConstantType(value) => - manifestOfType(tp1.deconst, full) - case TypeRef(pre, sym, args) => - if (isPrimitiveValueClass(sym) || isPhantomClass(sym)) { - findSingletonManifest(sym.name.toString) - } else if (sym == ObjectClass || sym == AnyRefClass) { - findSingletonManifest("Object") - } else if (sym == RepeatedParamClass || sym == ByNameParamClass) { - EmptyTree - } else if (sym == ArrayClass && args.length == 1) { - manifestFactoryCall("arrayType", args.head, findManifest(args.head)) - } else if (sym.isClass) { - val classarg0 = gen.mkClassOf(tp1) - val classarg = tp match { - case _: ExistentialType => gen.mkCast(classarg0, ClassType(tp)) - case _ => classarg0 - } - val suffix = classarg :: (args map findSubManifest) - manifestFactoryCall( - "classType", tp, - (if ((pre eq NoPrefix) || pre.typeSymbol.isStaticOwner) suffix - else findSubManifest(pre) :: suffix): _*) - } else if (sym.isExistentiallyBound && full) { - manifestFactoryCall("wildcardType", tp, - findManifest(tp.bounds.lo), findManifest(tp.bounds.hi)) - } - // looking for a manifest of a type parameter that hasn't been inferred by now, - // can't do much, but let's not fail - else if (undetParams contains sym) { - // #3859: need to include the mapping from sym -> NothingClass.tpe in the SearchResult - mot(NothingClass.tpe, sym :: from, NothingClass.tpe :: to) - } else { - // a manifest should have been found by normal searchImplicit - EmptyTree - } - case RefinedType(parents, decls) => // !!! not yet: if !full || decls.isEmpty => - // refinement is not generated yet - if (hasLength(parents, 1)) findManifest(parents.head) - else if (full) manifestFactoryCall("intersectionType", tp, parents map findSubManifest: _*) - else mot(erasure.intersectionDominator(parents), from, to) - case ExistentialType(tparams, result) => - mot(tp1.skolemizeExistential, from, to) - case _ => - EmptyTree -/* !!! the following is almost right, but we have to splice nested manifest - * !!! types into this type. This requires a substantial extension of - * !!! reifiers. - val reifier = new Reifier() - val rtree = reifier.reifyTopLevel(tp1) - manifestFactoryCall("apply", tp, rtree) -*/ - } + val prefix = (tagClass, pre) match { + // ClassTags only exist for scala.reflect.mirror, so their materializer doesn't care about prefixes + case (ClassTagClass, _) => + gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) + // [Eugene to Martin] this is the crux of the interaction between implicits and reifiers + // here we need to turn a (supposedly path-dependent) type into a tree that will be used as a prefix + // I'm not sure if I've done this right - please, review + case (_, SingleType(prePre, preSym)) => + gen.mkAttributedRef(prePre, preSym) setType pre + // necessary only to compile typetags used inside the Universe cake + case (_, ThisType(thisSym)) => + gen.mkAttributedThis(thisSym) + case _ => + // if ``pre'' is not a PDT, e.g. if someone wrote + // implicitly[scala.reflect.makro.Context#TypeTag[Int]] + // then we need to fail, because we don't know the prefix to use during type reification + return failure(tp, "tag error: unsupported prefix type %s (%s)".format(pre, pre.kind)) } - mot(tp, Nil, Nil) + // todo. migrate hardcoded materialization in Implicits to corresponding implicit macros + var materializer = atPos(pos.focus)(Apply(TypeApply(Ident(TagMaterializers(tagClass)), List(TypeTree(tp))), List(prefix))) + if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer)) + success(materializer) } - def wrapResult(tree: Tree): SearchResult = - if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter) - /** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest. */ - private def implicitManifestOrOfExpectedType(pt: Type): SearchResult = pt.dealias match { - case TypeRef(_, sym, args) if ManifestSymbols(sym) => - manifestOfType(args.head, sym == FullManifestClass) match { - case SearchFailure if sym == OptManifestClass => wrapResult(gen.mkAttributedRef(NoManifest)) - case result => result - } + private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match { + case TypeRef(pre, sym, args) if TagSymbols(sym) => + tagOfType(pre, args.head, sym) case tp@TypeRef(_, sym, _) if sym.isAbstractType => - implicitManifestOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt) + implicitTagOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt) case _ => searchImplicit(implicitsOfExpectedType, false) // shouldn't we pass `pt` to `implicitsOfExpectedType`, or is the recursive case @@ -1199,7 +1159,9 @@ trait Implicits { /** The result of the implicit search: * First search implicits visible in current context. * If that fails, search implicits in expected type `pt`. - * If that fails, and `pt` is an instance of Manifest, try to construct a manifest. + * // [Eugene] the following two lines should be deleted after we migrate delegate manifest materialization to implicit macros + * If that fails, and `pt` is an instance of a ClassTag, try to construct a class tag. + * If that fails, and `pt` is an instance of a TypeTag, try to construct a type tag. * If all fails return SearchFailure */ def bestImplicit: SearchResult = { @@ -1219,7 +1181,7 @@ trait Implicits { val failstart = startTimer(oftypeFailNanos) val succstart = startTimer(oftypeSucceedNanos) - result = implicitManifestOrOfExpectedType(pt) + result = implicitTagOrOfExpectedType(pt) if (result == SearchFailure) { context.updateBuffer(previousErrs) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index ebf8e3fc9a..98b8d7673e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -67,7 +67,7 @@ trait Infer { */ def freshVar(tparam: Symbol): TypeVar = TypeVar(tparam) - private class NoInstance(msg: String) extends Throwable(msg) with ControlThrowable { } + class NoInstance(msg: String) extends Throwable(msg) with ControlThrowable { } private class DeferredNoInstance(getmsg: () => String) extends NoInstance("") { override def getMessage(): String = getmsg() } @@ -267,6 +267,16 @@ trait Infer { setError(tree) } else { + if (context.owner.isTermMacro && (sym1 hasFlag LOCKED)) { + // we must not let CyclicReference to be thrown from sym1.info + // because that would mark sym1 erroneous, which it is not + // but if it's a true CyclicReference then macro def will report it + // see comments to TypeSigError for an explanation of this special case + // [Eugene] is there a better way? + val dummy = new TypeCompleter { val tree = EmptyTree; override def complete(sym: Symbol) {} } + throw CyclicReference(sym1, dummy) + } + if (sym1.isTerm) sym1.cookJavaRawInfo() // xform java rawtypes into existentials @@ -310,6 +320,8 @@ trait Infer { /** Like weakly compatible but don't apply any implicit conversions yet. * Used when comparing the result type of a method with its prototype. + * [Martin] I think Infer is also created by Erasure, with the default + * implementation of isCoercible */ def isConservativelyCompatible(tp: Type, pt: Type): Boolean = context.withImplicitsDisabled(isWeaklyCompatible(tp, pt)) @@ -426,6 +438,9 @@ trait Infer { tvars map (tvar => WildcardType) } + /** [Martin] Can someone comment this please? I have no idea what it's for + * and the code is not exactly readable. + */ object AdjustedTypeArgs { val Result = collection.mutable.LinkedHashMap type Result = collection.mutable.LinkedHashMap[Symbol, Option[Type]] @@ -992,6 +1007,7 @@ trait Infer { PolymorphicExpressionInstantiationError(tree, undetparams, pt) } else { new TreeTypeSubstituter(undetparams, targs).traverse(tree) + notifyUndetparamsInferred(undetparams, targs) } } @@ -1028,6 +1044,7 @@ trait Infer { if (checkBounds(fn, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")) { val treeSubst = new TreeTypeSubstituter(okparams, okargs) treeSubst traverseTrees fn :: args + notifyUndetparamsInferred(okparams, okargs) leftUndet match { case Nil => Nil @@ -1116,6 +1133,7 @@ trait Infer { (inferFor(pt) orElse inferForApproxPt) map { targs => new TreeTypeSubstituter(undetparams, targs).traverse(tree) + notifyUndetparamsInferred(undetparams, targs) } getOrElse { debugwarn("failed inferConstructorInstance for "+ tree +" : "+ tree.tpe +" under "+ undetparams +" pt = "+ pt +(if(isFullyDefined(pt)) " (fully defined)" else " (not fully defined)")) // if (settings.explaintypes.value) explainTypes(resTp.instantiateTypeParams(undetparams, tvars), pt) @@ -1568,9 +1586,9 @@ trait Infer { else infer } - /** Assign tree the type of unique polymorphic alternative + /** Assign tree the type of all polymorphic alternatives * with nparams as the number of type parameters, if it exists. - * If several or none such polymorphic alternatives exist, error. + * If no such polymorphic alternative exist, error. * * @param tree ... * @param nparams ... diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index e43b1fab0b..3b270a92ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -3,135 +3,682 @@ package typechecker import symtab.Flags._ import scala.tools.nsc.util._ +import scala.tools.nsc.util.ClassPath._ import scala.reflect.ReflectionUtils +import scala.collection.mutable.ListBuffer +import scala.compat.Platform.EOL +import scala.reflect.makro.runtime.{Context => MacroContext} +import scala.reflect.runtime.Mirror +/** + * Code to deal with macros, namely with: + * * Compilation of macro definitions + * * Expansion of macro applications + * + * Say we have in a class C: + * + * def foo[T](xs: List[T]): T = macro fooBar + * + * Then fooBar needs to point to a static method of the following form: + * + * def fooBar[T: c.TypeTag] + * (c: scala.reflect.makro.Context) + * (xs: c.Expr[List[T]]) + * : c.mirror.Tree = { + * ... + * } + * + * Then, if foo is called in qual.foo[Int](elems), where qual: D, + * the macro application is expanded to a reflective invocation of fooBar with parameters + * + * (simpleMacroContext{ type PrefixType = D; val prefix = qual }) + * (Expr(elems)) + * (TypeTag(Int)) + */ trait Macros { self: Analyzer => import global._ import definitions._ - def macroMeth(mac: Symbol): Symbol = { - var owner = mac.owner - if (!owner.isModuleClass) owner = owner.companionModule.moduleClass - owner.info.decl(nme.macroMethodName(mac.name)) - } + val macroDebug = settings.Ymacrodebug.value + val macroCopypaste = settings.Ymacrocopypaste.value + val macroTrace = scala.tools.nsc.util.trace when macroDebug - def macroArgs(tree: Tree): (List[List[Tree]]) = tree match { - case Apply(fn, args) => - macroArgs(fn) :+ args - case TypeApply(fn, args) => - macroArgs(fn) :+ args - case Select(qual, name) => - List(List(qual)) - case _ => - List(List()) - } + val globalMacroCache = collection.mutable.Map[Any, Any]() + val perRunMacroCache = perRunCaches.newMap[Symbol, collection.mutable.Map[Any, Any]] - /** - * The definition of the method implementing a macro. Example: - * Say we have in a class C + /** A list of compatible macro implementation signatures. * - * def macro foo[T](xs: List[T]): T = expr + * In the example above: + * (c: scala.reflect.makro.Context)(xs: c.Expr[List[T]]): c.Expr[T] * - * Then the following macro method is generated for `foo`: - * - * def defmacro$foo - * (_context: scala.reflect.macro.Context) - * (_this: _context.Tree) - * (T: _context.TypeTree) - * (xs: _context.Tree): _context.Tree = { - * import _context._ // this means that all methods of Context can be used unqualified in macro's body - * expr - * } + * @param macroDef The macro definition symbol + * @param tparams The type parameters of the macro definition + * @param vparamss The value parameters of the macro definition + * @param retTpe The return type of the macro definition + */ + private def macroImplSigs(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[List[Symbol]]], Type) = { + // had to move method's body to an object because of the recursive dependencies between sigma and param + object SigGenerator { + val hasThis = macroDef.owner.isClass + val ownerTpe = macroDef.owner match { + case owner if owner.isModuleClass => new UniqueThisType(macroDef.owner) + case owner if owner.isClass => macroDef.owner.tpe + case _ => NoType + } + val hasTparams = !tparams.isEmpty + + def sigma(tpe: Type): Type = { + class SigmaTypeMap extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = pre match { + case ThisType(sym) if sym == macroDef.owner => + SingleType(SingleType(SingleType(NoPrefix, paramsCtx(0)), MacroContextPrefix), ExprValue) + case SingleType(NoPrefix, sym) => + vparamss.flatten.find(_.symbol == sym) match { + case Some(macroDefParam) => + SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue) + case _ => + pre + } + case _ => + pre + } + val args1 = args map mapOver + TypeRef(pre1, sym, args1) + case _ => + mapOver(tp) + } + } + + new SigmaTypeMap() apply tpe + } + + def makeParam(name: Name, pos: Position, tpe: Type, flags: Long = 0L) = + macroDef.newValueParameter(name, pos, flags) setInfo tpe + val ctxParam = makeParam(nme.macroContext, macroDef.pos, MacroContextClass.tpe, SYNTHETIC) + def implType(isType: Boolean, origTpe: Type): Type = + if (isRepeatedParamType(origTpe)) + appliedType( + RepeatedParamClass.typeConstructor, + List(implType(isType, sigma(origTpe.typeArgs.head)))) + else { + val tsym = getMember(MacroContextClass, if (isType) tpnme.TypeTag else tpnme.Expr) + typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(origTpe))) + } + val paramCache = collection.mutable.Map[Symbol, Symbol]() + def param(tree: Tree): Symbol = + paramCache.getOrElseUpdate(tree.symbol, { + // [Eugene] deskolemization became necessary once I implemented inference of macro def return type + // please, verify this solution, but for now I'll leave it here - cargo cult for the win + val sym = tree.symbol.deSkolemize + val sigParam = makeParam(sym.name, sym.pos, implType(sym.isType, sym.tpe)) + if (sym.isSynthetic) sigParam.flags |= SYNTHETIC + sigParam + }) + + val paramsCtx = List(ctxParam) + val paramsThis = List(makeParam(nme.macroThis, macroDef.pos, implType(false, ownerTpe), SYNTHETIC)) + val paramsTparams = tparams map param + val paramssParams = vparamss map (_ map param) + + var paramsss = List[List[List[Symbol]]]() + // tparams are no longer part of a signature, they get into macro implementations via context bounds +// if (hasTparams && hasThis) paramsss :+= paramsCtx :: paramsThis :: paramsTparams :: paramssParams +// if (hasTparams) paramsss :+= paramsCtx :: paramsTparams :: paramssParams + // _this params are no longer part of a signature, its gets into macro implementations via Context.prefix +// if (hasThis) paramsss :+= paramsCtx :: paramsThis :: paramssParams + paramsss :+= paramsCtx :: paramssParams + + val tsym = getMember(MacroContextClass, tpnme.Expr) + val implRetTpe = typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(retTpe))) + } + + import SigGenerator._ + macroTrace("generating macroImplSigs for: ")(macroDef) + macroTrace("tparams are: ")(tparams) + macroTrace("vparamss are: ")(vparamss) + macroTrace("retTpe is: ")(retTpe) + macroTrace("macroImplSigs are: ")(paramsss, implRetTpe) + } + + private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Option[Symbol]): List[List[Symbol]] = { + if (paramss.length == 0) + return paramss + + val wannabe = if (paramss.head.length == 1) paramss.head.head else NoSymbol + val contextParam = if (wannabe != NoSymbol && wannabe.tpe <:< definitions.MacroContextClass.tpe) wannabe else NoSymbol + + val lastParamList0 = paramss.lastOption getOrElse Nil + val lastParamList = lastParamList0 flatMap (param => param.tpe match { + case TypeRef(SingleType(NoPrefix, contextParam), sym, List(tparam)) => + var wannabe = sym + while (wannabe.isAliasType) wannabe = wannabe.info.typeSymbol + if (wannabe != definitions.TypeTagClass) + List(param) + else + transform(param, tparam.typeSymbol) map (_ :: Nil) getOrElse Nil + case _ => + List(param) + }) + + var result = paramss.dropRight(1) :+ lastParamList + if (lastParamList0.isEmpty ^ lastParamList.isEmpty) { + result = result dropRight 1 + } + + result + } + + /** As specified above, body of a macro definition must reference its implementation. + * This function verifies that the body indeed refers to a method, and that + * the referenced macro implementation is compatible with the given macro definition. * - * If macro has no type arguments, the third parameter list is omitted (it's not empty, but omitted altogether). + * This means that macro implementation (fooBar in example above) must: + * 1) Refer to a statically accessible, non-overloaded method. + * 2) Have the right parameter lists as outlined in the SIP / in the doc comment of this class. * - * To find out the desugared representation of your particular macro, compile it with -Ymacro-debug. + * @return typechecked rhs of the given macro definition */ - def macroMethDef(mdef: DefDef): Tree = { - def paramDef(name: Name, tpt: Tree) = ValDef(Modifiers(PARAM), name, tpt, EmptyTree) - val contextType = TypeTree(ReflectMacroContext.tpe) - val globParamSec = List(paramDef(nme.macroContext, contextType)) - def globSelect(name: Name) = Select(Ident(nme.macroContext), name) - def globTree = globSelect(tpnme.Tree) - def globTypeTree = globSelect(tpnme.TypeTree) - val thisParamSec = List(paramDef(newTermName(nme.macroThis), globTree)) - def tparamInMacro(tdef: TypeDef) = paramDef(tdef.name.toTermName, globTypeTree) - def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, vdef.tpt match { - case tpt @ AppliedTypeTree(hk, _) if treeInfo.isRepeatedParamType(tpt) => AppliedTypeTree(hk, List(globTree)) - case _ => globTree - }) - def wrapImplicit(tree: Tree) = atPos(tree.pos) { - // implicit hasn't proven useful so far, so I'm disabling it - //val implicitDecl = ValDef(Modifiers(IMPLICIT), nme.macroContextImplicit, SingletonTypeTree(Ident(nme.macroContext)), Ident(nme.macroContext)) - val importGlob = Import(Ident(nme.macroContext), List(ImportSelector(nme.WILDCARD, -1, null, -1))) - Block(List(importGlob), tree) + def typedMacroBody(typer: Typer, ddef: DefDef): Tree = { + import typer.context + if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) + + implicit def augmentString(s: String) = new AugmentedString(s) + class AugmentedString(s: String) { + def abbreviateCoreAliases: String = { // hack! + var result = s + result = result.replace("c.mirror.TypeTag", "c.TypeTag") + result = result.replace("c.mirror.Expr", "c.Expr") + result + } } - var formals = (mdef.vparamss map (_ map vparamInMacro)) - if (mdef.tparams.nonEmpty) formals = (mdef.tparams map tparamInMacro) :: formals - - atPos(mdef.pos) { - new DefDef( // can't call DefDef here; need to find out why - mods = mdef.mods &~ MACRO &~ OVERRIDE, - name = nme.macroMethodName(mdef.name), - tparams = List(), - vparamss = globParamSec :: thisParamSec :: formals, - tpt = globTree, - wrapImplicit(mdef.rhs)) + + var hasErrors = false + def reportError(pos: Position, msg: String) = { + hasErrors = true + context.error(pos, msg) + } + + val macroDef = ddef.symbol + val defpos = macroDef.pos + val implpos = ddef.rhs.pos + assert(macroDef.isTermMacro, ddef) + + def invalidBodyError() = + reportError(defpos, + "macro body has wrong shape:" + + "\n required: macro ." + + "\n or : macro ") + def validatePreTyper(rhs: Tree): Unit = rhs match { + // we do allow macro invocations inside macro bodies + // personally I don't mind if pre-typer tree is a macro invocation + // that later resolves to a valid reference to a macro implementation + // however, I don't think that invalidBodyError() should hint at that + // let this be an Easter Egg :) + case Apply(_, _) => ; + case TypeApply(_, _) => ; + case Super(_, _) => ; + case This(_) => ; + case Ident(_) => ; + case Select(_, _) => ; + case _ => invalidBodyError() } + def validatePostTyper(rhs1: Tree): Unit = { + def loop(tree: Tree): Unit = { + def errorNotStatic() = + reportError(implpos, "macro implementation must be in statically accessible object") + + def ensureRoot(sym: Symbol) = + if (!sym.isModule && !sym.isModuleClass) errorNotStatic() + + def ensureModule(sym: Symbol) = + if (!sym.isModule) errorNotStatic() + + tree match { + case TypeApply(fun, _) => + loop(fun) + case Super(qual, _) => + ensureRoot(macroDef.owner) + loop(qual) + case This(_) => + ensureRoot(tree.symbol) + case Select(qual, name) if name.isTypeName => + loop(qual) + case Select(qual, name) if name.isTermName => + if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol) + loop(qual) + case Ident(name) if name.isTypeName => + ; + case Ident(name) if name.isTermName => + if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol) + case _ => + invalidBodyError() + } + } + + loop(rhs1) + } + + val rhs = ddef.rhs + validatePreTyper(rhs) + if (hasErrors) macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + + // we use typed1 instead of typed, because otherwise adapt is going to mess us up + // if adapt sees ., it will want to perform eta-expansion and will fail + // unfortunately, this means that we have to manually trigger macro expansion + // because it's adapt which is responsible for automatic expansion during typechecking + def typecheckRhs(rhs: Tree): Tree = { + try { + val prevNumErrors = reporter.ERROR.count // [Eugene] funnily enough, the isErroneous check is not enough + var rhs1 = if (hasErrors) EmptyTree else typer.typed1(rhs, EXPRmode, WildcardType) + def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors + def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isTermMacro && !rhs1.symbol.isErroneous + while (!typecheckedWithErrors && rhsNeedsMacroExpansion) { + rhs1 = macroExpand1(typer, rhs1) match { + case Success(expanded) => + try { + val typechecked = typer.typed1(expanded, EXPRmode, WildcardType) + if (macroDebug) { + println("typechecked1:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked + } finally { + openMacros = openMacros.tail + } + case Fallback(fallback) => + typer.typed1(fallback, EXPRmode, WildcardType) + case Other(result) => + result + } + } + rhs1 + } catch { + case ex: TypeError => + typer.reportTypeError(context, rhs.pos, ex) + typer.infer.setError(rhs) + } + } + + val prevNumErrors = reporter.ERROR.count // funnily enough, the isErroneous check is not enough + var rhs1 = typecheckRhs(rhs) + def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors + hasErrors = hasErrors || typecheckedWithErrors + if (typecheckedWithErrors) macroTrace("body of a macro def failed to typecheck: ")(ddef) + + val macroImpl = rhs1.symbol + macroDef withAnnotation AnnotationInfo(MacroImplAnnotation.tpe, List(rhs1), Nil) + if (!hasErrors) { + if (macroImpl == null) { + invalidBodyError() + } else { + if (!macroImpl.isMethod) + invalidBodyError() + if (macroImpl.isOverloaded) + reportError(implpos, "macro implementation cannot be overloaded") + if (!macroImpl.typeParams.isEmpty && (!rhs1.isInstanceOf[TypeApply])) + reportError(implpos, "macro implementation reference needs type arguments") + if (!hasErrors) + validatePostTyper(rhs1) + } + if (hasErrors) + macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + } + + if (!hasErrors) { + def checkCompatibility(reqparamss: List[List[Symbol]], actparamss: List[List[Symbol]], reqres: Type, actres: Type): List[String] = { + var hasErrors = false + var errors = List[String]() + def compatibilityError(msg: String) { + hasErrors = true + errors :+= msg + } + + val flatreqparams = reqparamss.flatten + val flatactparams = actparamss.flatten + val tparams = macroImpl.typeParams + val tvars = tparams map freshVar + def lengthMsg(which: String, extra: Symbol) = + "parameter lists have different length, "+which+" extra parameter "+extra.defString + if (actparamss.length != reqparamss.length) + compatibilityError("number of parameter sections differ") + + if (!hasErrors) { + try { + for ((rparams, aparams) <- reqparamss zip actparamss) { + if (rparams.length < aparams.length) + compatibilityError(lengthMsg("found", aparams(rparams.length))) + if (aparams.length < rparams.length) + compatibilityError(lengthMsg("required", rparams(aparams.length)).abbreviateCoreAliases) + } + // if the implementation signature is already deemed to be incompatible, we bail out + // otherwise, high-order type magic employed below might crash in weird ways + if (!hasErrors) { + for ((rparams, aparams) <- reqparamss zip actparamss) { + for ((rparam, aparam) <- rparams zip aparams) { + def isRepeated(param: Symbol) = param.tpe.typeSymbol == RepeatedParamClass + if (rparam.name != aparam.name && !rparam.isSynthetic) { + val rparam1 = rparam + val aparam1 = aparam + compatibilityError("parameter names differ: "+rparam.name+" != "+aparam.name) + } + if (isRepeated(rparam) && !isRepeated(aparam)) + compatibilityError("types incompatible for parameter "+rparam.name+": corresponding is not a vararg parameter") + if (!isRepeated(rparam) && isRepeated(aparam)) + compatibilityError("types incompatible for parameter "+aparam.name+": corresponding is not a vararg parameter") + if (!hasErrors) { + var atpe = aparam.tpe.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars) + + // strip the { type PrefixType = ... } refinement off the Context or otherwise we get compatibility errors + atpe = atpe match { + case RefinedType(List(tpe), Scope(sym)) if tpe == MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe + case _ => atpe + } + + val ok = if (macroDebug) withTypesExplained(rparam.tpe <:< atpe) else rparam.tpe <:< atpe + if (!ok) { + compatibilityError("type mismatch for parameter "+rparam.name+": "+rparam.tpe.toString.abbreviateCoreAliases+" does not conform to "+atpe) + } + } + } + } + } + if (!hasErrors) { + val atpe = actres.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars) + val ok = if (macroDebug) withTypesExplained(atpe <:< reqres) else atpe <:< reqres + if (!ok) { + compatibilityError("type mismatch for return type : "+reqres.toString.abbreviateCoreAliases+" does not conform to "+(if (ddef.tpt.tpe != null) atpe.toString else atpe.toString.abbreviateCoreAliases)) + } + } + if (!hasErrors) { + val targs = solvedTypes(tvars, tparams, tparams map varianceInType(actres), false, + lubDepth(flatactparams map (_.tpe)) max lubDepth(flatreqparams map (_.tpe))) + val boundsOk = typer.silent(_.infer.checkBounds(ddef, NoPrefix, NoSymbol, tparams, targs, "")) + boundsOk match { + case SilentResultValue(true) => ; + case SilentResultValue(false) | SilentTypeError(_) => + val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds) + compatibilityError("type arguments " + targs.mkString("[", ",", "]") + + " do not conform to " + tparams.head.owner + "'s type parameter bounds " + + (tparams map (_.defString)).mkString("[", ",", "]")) + } + } + } catch { + case ex: NoInstance => + compatibilityError( + "type parameters "+(tparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+ + ex.getMessage) + } + } + + errors.toList + } + + var actparamss = macroImpl.paramss + actparamss = transformTypeTagEvidenceParams(actparamss, (param, tparam) => None) + + val rettpe = if (ddef.tpt.tpe != null) ddef.tpt.tpe else computeMacroDefTypeFromMacroImpl(ddef, macroDef, macroImpl) + val (reqparamsss0, reqres0) = macroImplSigs(macroDef, ddef.tparams, ddef.vparamss, rettpe) + var reqparamsss = reqparamsss0 + + // prohibit implicit params on macro implementations + // we don't have to do this, but it appears to be more clear than allowing them + val implicitParams = actparamss.flatten filter (_.isImplicit) + if (implicitParams.length > 0) { + reportError(implicitParams.head.pos, "macro implementations cannot have implicit parameters other than TypeTag evidences") + macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + } + + if (!hasErrors) { + val reqres = reqres0 + val actres = macroImpl.tpe.finalResultType + def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = { + var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString + if (abbreviate) argsPart = argsPart.abbreviateCoreAliases + var retPart = restpe.toString + if (abbreviate || ddef.tpt.tpe == null) retPart = retPart.abbreviateCoreAliases + argsPart + ": " + retPart + } + def compatibilityError(addendum: String) = + reportError(implpos, + "macro implementation has wrong shape:"+ + "\n required: "+showMeth(reqparamsss.head, reqres, true) + + (reqparamsss.tail map (paramss => "\n or : "+showMeth(paramss, reqres, true)) mkString "")+ + "\n found : "+showMeth(actparamss, actres, false)+ + "\n"+addendum) + + macroTrace("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name) + val results = reqparamsss map (checkCompatibility(_, actparamss, reqres, actres)) + if (macroDebug) (reqparamsss zip results) foreach { case (reqparamss, result) => + println("%s %s".format(if (result.isEmpty) "[ OK ]" else "[FAILED]", reqparamss)) + result foreach (errorMsg => println(" " + errorMsg)) + } + + if (results forall (!_.isEmpty)) { + var index = reqparamsss indexWhere (_.length == actparamss.length) + if (index == -1) index = 0 + val mostRelevantMessage = results(index).head + compatibilityError(mostRelevantMessage) + } else { + assert((results filter (_.isEmpty)).length == 1, results) + if (macroDebug) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) => + println("typechecked macro impl as: " + reqparamss) + } + } + } + } + + // if this macro definition is erroneous, then there's no sense in expanding its usages + // in the previous prototype macro implementations were magically generated from macro definitions + // so macro definitions and its usages couldn't be compiled in the same compilation run + // however, now definitions and implementations are decoupled, so it's everything is possible + // hence, we now use IS_ERROR flag to serve as an indicator that given macro definition is broken + if (hasErrors) { + macroDef setFlag IS_ERROR + } + + rhs1 } - def addMacroMethods(templ: Template, namer: Namer): Unit = { - for (ddef @ DefDef(mods, _, _, _, _, _) <- templ.body if mods hasFlag MACRO) { - val trace = scala.tools.nsc.util.trace when settings.Ymacrodebug.value - val sym = namer.enterSyntheticSym(trace("macro def: ")(macroMethDef(ddef))) - trace("added to "+namer.context.owner.enclClass+": ")(sym) + def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroDef: Symbol, macroImpl: Symbol): Type = { + // get return type from method type + def unwrapRet(tpe: Type): Type = { + def loop(tpe: Type) = tpe match { + case NullaryMethodType(ret) => ret + case mtpe @ MethodType(_, ret) => unwrapRet(ret) + case _ => tpe + } + + tpe match { + case PolyType(_, tpe) => loop(tpe) + case _ => loop(tpe) + } + } + var metaType = unwrapRet(macroImpl.tpe) + + // downgrade from metalevel-0 to metalevel-1 + def inferRuntimeType(metaType: Type): Type = metaType match { + case TypeRef(pre, sym, args) if sym.name == tpnme.Expr && args.length == 1 => + args.head + case _ => + AnyClass.tpe + } + var runtimeType = inferRuntimeType(metaType) + + // transform type parameters of a macro implementation into type parameters of a macro definition + runtimeType = runtimeType map { + case TypeRef(pre, sym, args) => + // [Eugene] not sure which of these deSkolemizes are necessary + // sym.paramPos is unreliable (see another case below) + val tparams = macroImpl.typeParams map (_.deSkolemize) + val paramPos = tparams indexOf sym.deSkolemize + val sym1 = if (paramPos == -1) sym else { + val ann = macroDef.getAnnotation(MacroImplAnnotation) + ann match { + case Some(ann) => + val TypeApply(_, implRefTargs) = ann.args(0) + val implRefTarg = implRefTargs(paramPos).tpe.typeSymbol + implRefTarg + case None => + sym + } + } + TypeRef(pre, sym1, args) + case tpe => + tpe + } + + // as stated in the spec, before being matched to macroimpl, type and value parameters of macrodef + // undergo a special transformation, sigma, that adapts them to the different metalevel macroimpl lives in + // as a result, we need to reverse this transformation when inferring macrodef ret from macroimpl ret + def unsigma(tpe: Type): Type = { + // unfortunately, we cannot dereference ``paramss'', because we're in the middle of inferring a type for ``macroDef'' +// val defParamss = macroDef.paramss + val defParamss = macroDdef.vparamss map (_ map (_.symbol)) + var implParamss = macroImpl.paramss + implParamss = transformTypeTagEvidenceParams(implParamss, (param, tparam) => None) + + val implCtxParam = if (implParamss.length > 0 && implParamss(0).length > 0) implParamss(0)(0) else null + def implParamToDefParam(implParam: Symbol): Symbol = { + val indices = (implParamss drop 1 zipWithIndex) map { case (implParams, index) => (index, implParams indexOf implParam) } filter (_._2 != -1) headOption; + val defParam = indices flatMap { + case (plistIndex, pIndex) => + if (defParamss.length <= plistIndex) None + else if (defParamss(plistIndex).length <= pIndex) None + else Some(defParamss(plistIndex)(pIndex)) + } + defParam orNull + } + + class UnsigmaTypeMap extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = pre match { + case SingleType(SingleType(SingleType(NoPrefix, param), prefix), value) if param == implCtxParam && prefix == MacroContextPrefix && value == ExprValue => + ThisType(macroDef.owner) + case SingleType(SingleType(NoPrefix, param), value) if implParamToDefParam(param) != null && value == ExprValue => + val macroDefParam = implParamToDefParam(param) + SingleType(NoPrefix, macroDefParam) + case _ => + pre + } + val args1 = args map mapOver + TypeRef(pre1, sym, args1) + case _ => + mapOver(tp) + } + } + + new UnsigmaTypeMap() apply tpe } + runtimeType = unsigma(runtimeType) + + runtimeType } - lazy val mirror = new scala.reflect.runtime.Mirror { - lazy val libraryClassLoader = { - // todo. this is more or less okay, but not completely correct - // see https://issues.scala-lang.org/browse/SI-5433 for more info - val classpath = global.classPath.asURLs - var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) - - // an heuristic to detect REPL - if (global.settings.exposeEmptyPackage.value) { - import scala.tools.nsc.interpreter._ - val virtualDirectory = global.settings.outputDirs.getSingleOutput.get - loader = new AbstractFileClassLoader(virtualDirectory, loader) {} + /** Primary mirror that is used to resolve and run macro implementations. + * Loads classes from -Xmacro-primary-classpath, or from -cp if the option is not specified. + */ + private lazy val primaryMirror: Mirror = { + if (global.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + val libraryClassLoader = { + if (settings.XmacroPrimaryClasspath.value != "") { + if (macroDebug) println("primary macro mirror: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value)) + val classpath = toURLs(settings.XmacroFallbackClasspath.value) + ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) + } else { + if (macroDebug) println("primary macro mirror: initializing from -cp: %s".format(global.classPath.asURLs)) + val classpath = global.classPath.asURLs + var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) + + // [Eugene] a heuristic to detect REPL + if (global.settings.exposeEmptyPackage.value) { + import scala.tools.nsc.interpreter._ + val virtualDirectory = global.settings.outputDirs.getSingleOutput.get + loader = new AbstractFileClassLoader(virtualDirectory, loader) {} + } + + loader } + } + + new Mirror(libraryClassLoader) { override def toString = "" } + } - loader + /** Fallback mirror that is used to resolve and run macro implementations. + * Loads classes from -Xmacro-fallback-classpath aka "macro fallback classpath". + */ + private lazy val fallbackMirror: Mirror = { + if (global.forMSIL) + throw new UnsupportedOperationException("Scala reflection not available on this platform") + + val fallbackClassLoader = { + if (macroDebug) println("fallback macro mirror: initializing from -Xmacro-fallback-classpath: %s".format(settings.XmacroFallbackClasspath.value)) + val classpath = toURLs(settings.XmacroFallbackClasspath.value) + ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) } - override def defaultReflectiveClassLoader() = libraryClassLoader + new Mirror(fallbackClassLoader) { override def toString = "" } } - /** Return optionally address of companion object and implementation method symbol - * of given macro; or None if implementation classfile cannot be loaded or does - * not contain the macro implementation. + /** Produces a function that can be used to invoke macro implementation for a given macro definition: + * 1) Looks up macro implementation symbol in this universe. + * 2) Loads its enclosing class from the primary mirror. + * 3) Loads the companion of that enclosing class from the primary mirror. + * 4) Resolves macro implementation within the loaded companion. + * 5) If 2-4 fails, repeats them for the fallback mirror. + * + * @return Some(runtime) if macro implementation can be loaded successfully from either of the mirrors, + * None otherwise. */ - def macroImpl(mac: Symbol): Option[(AnyRef, mirror.Symbol)] = { - val debug = settings.Ymacrodebug.value - val trace = scala.tools.nsc.util.trace when debug - trace("looking for macro implementation: ")(mac.fullNameString) - - try { - val mmeth = macroMeth(mac) - trace("found implementation at: ")(mmeth.fullNameString) - - if (mmeth == NoSymbol) None - else { - trace("loading implementation class: ")(mmeth.owner.fullName) - trace("classloader is: ")("%s of type %s".format(mirror.libraryClassLoader, mirror.libraryClassLoader.getClass)) + private def macroRuntime(macroDef: Symbol): Option[List[Any] => Any] = { + macroTrace("looking for macro implementation: ")(macroDef) + macroTrace("macroDef is annotated with: ")(macroDef.annotations) + + val ann = macroDef.getAnnotation(MacroImplAnnotation) + if (ann == None) { + macroTrace("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef) + return None + } + + val macroImpl = ann.get.args(0).symbol + if (macroImpl == NoSymbol) { + macroTrace("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef) + return None + } + + if (macroDebug) println("resolved implementation %s at %s".format(macroImpl, macroImpl.pos)) + if (macroImpl.isErroneous) { + macroTrace("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef) + return None + } + + def loadMacroImpl(macroMirror: Mirror): Option[(Object, macroMirror.Symbol)] = { + try { + // this logic relies on the assumptions that were valid for the old macro prototype + // namely that macro implementations can only be defined in top-level classes and modules + // with the new prototype that materialized in a SIP, macros need to be statically accessible, which is different + // for example, a macro def could be defined in a trait that is implemented by an object + // there are some more clever cases when seemingly non-static method ends up being statically accessible + // however, the code below doesn't account for these guys, because it'd take a look of time to get it right + // for now I leave it as a todo and move along to more the important stuff + + macroTrace("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName) + macroTrace("classloader is: ")("%s of type %s".format(macroMirror.classLoader, if (macroMirror.classLoader != null) macroMirror.classLoader.getClass.toString else "primordial classloader")) def inferClasspath(cl: ClassLoader) = cl match { case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" + case null => "[" + scala.tools.util.PathResolver.Environment.javaBootClassPath + "]" case _ => "" } - trace("classpath is: ")(inferClasspath(mirror.libraryClassLoader)) + macroTrace("classpath is: ")(inferClasspath(macroMirror.classLoader)) - // @xeno.by: relies on the fact that macros can only be defined in static classes + // [Eugene] relies on the fact that macro implementations can only be defined in static classes + // [Martin to Eugene] There's similar logic buried in Symbol#flatname. Maybe we can refactor? def classfile(sym: Symbol): String = { def recur(sym: Symbol): String = sym match { case sym if sym.owner.isPackageClass => @@ -146,145 +693,535 @@ trait Macros { self: Analyzer => else recur(sym.enclClass) } - // @xeno.by: this doesn't work for inner classes - // neither does mmeth.owner.javaClassName, so I had to roll my own implementation - //val receiverName = mmeth.owner.fullName - val receiverName = classfile(mmeth.owner) - val receiverClass: mirror.Symbol = mirror.symbolForName(receiverName) + // [Eugene] this doesn't work for inner classes + // neither does macroImpl.owner.javaClassName, so I had to roll my own implementation + //val receiverName = macroImpl.owner.fullName + val implClassName = classfile(macroImpl.owner) + val implClassSymbol: macroMirror.Symbol = macroMirror.symbolForName(implClassName) - if (debug) { - println("receiverClass is: " + receiverClass.fullNameString) + if (macroDebug) { + println("implClassSymbol is: " + implClassSymbol.fullNameString) - val jreceiverClass = mirror.classToJava(receiverClass) - val jreceiverSource = jreceiverClass.getProtectionDomain.getCodeSource - println("jreceiverClass is %s from %s".format(jreceiverClass, jreceiverSource)) - println("jreceiverClassLoader is %s with classpath %s".format(jreceiverClass.getClassLoader, inferClasspath(jreceiverClass.getClassLoader))) + if (implClassSymbol != macroMirror.NoSymbol) { + val implClass = macroMirror.classToJava(implClassSymbol) + val implSource = implClass.getProtectionDomain.getCodeSource + println("implClass is %s from %s".format(implClass, implSource)) + println("implClassLoader is %s with classpath %s".format(implClass.getClassLoader, inferClasspath(implClass.getClassLoader))) + } } - val receiverObj = receiverClass.companionModule - trace("receiverObj is: ")(receiverObj.fullNameString) + val implObjSymbol = implClassSymbol.companionModule + macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) - if (receiverObj == mirror.NoSymbol) None + if (implObjSymbol == macroMirror.NoSymbol) None else { - // @xeno.by: yet another reflection method that doesn't work for inner classes - //val receiver = mirror.companionInstance(receiverClass) - val clazz = java.lang.Class.forName(receiverName, true, mirror.libraryClassLoader) - val receiver = clazz getField "MODULE$" get null - - val rmeth = receiverObj.info.member(mirror.newTermName(mmeth.name.toString)) - if (debug) { - println("rmeth is: " + rmeth.fullNameString) - println("jrmeth is: " + mirror.methodToJava(rmeth)) + // yet another reflection method that doesn't work for inner classes + //val receiver = macroMirror.companionInstance(receiverClass) + val implObj = try { + val implObjClass = java.lang.Class.forName(implClassName, true, macroMirror.classLoader) + implObjClass getField "MODULE$" get null + } catch { + case ex: NoSuchFieldException => macroTrace("exception when loading implObj: ")(ex); null + case ex: NoClassDefFoundError => macroTrace("exception when loading implObj: ")(ex); null + case ex: ClassNotFoundException => macroTrace("exception when loading implObj: ")(ex); null } - if (rmeth == mirror.NoSymbol) None + if (implObj == null) None else { - Some((receiver, rmeth)) + val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString)) + if (macroDebug) { + println("implMethSymbol is: " + implMethSymbol.fullNameString) + println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) + } + + if (implMethSymbol == macroMirror.NoSymbol) None + else { + if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) + Some((implObj, implMethSymbol)) + } } } + } catch { + case ex: ClassNotFoundException => + macroTrace("implementation class failed to load: ")(ex.toString) + None } - } catch { - case ex: ClassNotFoundException => - trace("implementation class failed to load: ")(ex.toString) - None + } + + val primary = loadMacroImpl(primaryMirror) + primary match { + case Some((implObj, implMethSymbol)) => + def runtime(args: List[Any]) = primaryMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any] + Some(runtime) + case None => + if (settings.XmacroFallbackClasspath.value != "") { + if (macroDebug) println("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value)) + val fallback = loadMacroImpl(fallbackMirror) + fallback match { + case Some((implObj, implMethSymbol)) => + def runtime(args: List[Any]) = fallbackMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any] + Some(runtime) + case None => + None + } + } else { + None + } } } - /** Return result of macro expansion. - * Or, if that fails, and the macro overrides a method return - * tree that calls this method instead of the macro. + /** Should become private again once we're done with migrating typetag generation from implicits */ + def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext { val mirror: global.type } = + new { + val mirror: global.type = global + val callsiteTyper: mirror.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer] + // todo. infer precise typetag for this Expr, namely the PrefixType member of the Context refinement + val prefix = Expr(prefixTree)(TypeTag.Nothing) + val expandee = expandeeTree + } with MacroContext { + override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, openMacros.length - 1 /* exclude myself */) + } + + /** Calculate the arguments to pass to a macro implementation when expanding the provided tree. + * + * This includes inferring the exact type and instance of the macro context to pass, and also + * allowing for missing parameter sections in macro implementation (see ``macroImplParamsss'' for more info). + * + * @return list of runtime objects to pass to the implementation obtained by ``macroRuntime'' */ - def macroExpand(tree: Tree, typer: Typer): Option[Any] = { - val trace = scala.tools.nsc.util.trace when settings.Ymacrodebug.value - trace("macroExpand: ")(tree) - - val macroDef = tree.symbol - macroImpl(macroDef) match { - case Some((receiver, rmeth)) => - val argss = List(global) :: macroArgs(tree) - val paramss = macroMeth(macroDef).paramss - trace("paramss: ")(paramss) - val rawArgss = for ((as, ps) <- argss zip paramss) yield { - if (isVarArgsList(ps)) as.take(ps.length - 1) :+ as.drop(ps.length - 1) - else as - } - val rawArgs: Seq[Any] = rawArgss.flatten - trace("rawArgs: ")(rawArgs) - val savedInfolevel = nodePrinters.infolevel + private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = { + var prefixTree: Tree = EmptyTree + var typeArgs = List[Tree]() + val exprArgs = new ListBuffer[List[Expr[_]]] + def collectMacroArgs(tree: Tree): Unit = tree match { + case Apply(fn, args) => + // todo. infer precise typetag for this Expr, namely the declared type of the corresponding macro impl argument + exprArgs.prepend(args map (Expr(_)(TypeTag.Nothing))) + collectMacroArgs(fn) + case TypeApply(fn, args) => + typeArgs = args + collectMacroArgs(fn) + case Select(qual, name) => + prefixTree = qual + case _ => + } + collectMacroArgs(expandee) + val context = macroContext(typer, prefixTree, expandee) + var argss: List[List[Any]] = List(context) :: exprArgs.toList + macroTrace("argss: ")(argss) + + val macroDef = expandee.symbol + val ann = macroDef.getAnnotation(MacroImplAnnotation).getOrElse(throw new Error("assertion failed. %s: %s".format(macroDef, macroDef.annotations))) + val macroImpl = ann.args(0).symbol + var paramss = macroImpl.paramss + val tparams = macroImpl.typeParams + macroTrace("paramss: ")(paramss) + + // we need to take care of all possible combos of nullary/empty-paramlist macro defs vs nullary/empty-arglist invocations + // nullary def + nullary invocation => paramss and argss match, everything is okay + // nullary def + empty-arglist invocation => illegal Scala code, impossible, everything is okay + // empty-paramlist def + nullary invocation => uh-oh, we need to append a List() to argss + // empty-paramlist def + empty-arglist invocation => paramss and argss match, everything is okay + // that's almost it, but we need to account for the fact that paramss might have context bounds that mask the empty last paramlist + val paramss_without_evidences = transformTypeTagEvidenceParams(paramss, (param, tparam) => None) + val isEmptyParamlistDef = paramss_without_evidences.length != 0 && paramss_without_evidences.last.isEmpty + val isEmptyArglistInvocation = argss.length != 0 && argss.last.isEmpty + if (isEmptyParamlistDef && !isEmptyArglistInvocation) { + if (macroDebug) println("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss") + argss = argss :+ Nil + } + + // nb! check partial application against paramss without evidences + val numParamLists = paramss_without_evidences.length + val numArgLists = argss.length + if (numParamLists != numArgLists) { + typer.context.error(expandee.pos, "macros cannot be partially applied") + return None + } + + // if paramss have typetag context bounds, add an arglist to argss if necessary and instantiate the corresponding evidences + // consider the following example: + // + // class D[T] { + // class C[U] { + // def foo[V] = macro Impls.foo[T, U, V] + // } + // } + // + // val outer1 = new D[Int] + // val outer2 = new outer1.C[String] + // outer2.foo[Boolean] + // + // then T and U need to be inferred from the lexical scope of the call using ``asSeenFrom'' + // whereas V won't be resolved by asSeenFrom and need to be loaded directly from ``expandee'' which needs to contain a TypeApply node + // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim + paramss = transformTypeTagEvidenceParams(paramss, (param, tparam) => Some(tparam)) + if (paramss.lastOption map (params => !params.isEmpty && params.forall(_.isType)) getOrElse false) argss = argss :+ Nil + val evidences = paramss.last takeWhile (_.isType) map (tparam => { + val TypeApply(_, implRefTargs) = ann.args(0) + var implRefTarg = implRefTargs(tparam.paramPos).tpe.typeSymbol + val tpe = if (implRefTarg.isTypeParameterOrSkolem) { + if (implRefTarg.owner == macroDef) { + // [Eugene] doesn't work when macro def is compiled separately from its usages + // then implRefTarg is not a skolem and isn't equal to any of macroDef.typeParams +// val paramPos = implRefTarg.deSkolemize.paramPos + val paramPos = macroDef.typeParams.indexWhere(_.name == implRefTarg.name) + typeArgs(paramPos).tpe + } else + implRefTarg.tpe.asSeenFrom( + if (prefixTree == EmptyTree) macroDef.owner.tpe else prefixTree.tpe, + macroDef.owner) + } else + implRefTarg.tpe + if (macroDebug) println("resolved tparam %s as %s".format(tparam, tpe)) + tpe + }) map (tpe => { + val ttag = TypeTag(tpe) + if (ttag.isGround) ttag.toGround else ttag + }) + argss = argss.dropRight(1) :+ (evidences ++ argss.last) + + assert(argss.length == paramss.length, "argss: %s, paramss: %s".format(argss, paramss)) + val rawArgss = for ((as, ps) <- argss zip paramss) yield { + if (isVarArgsList(ps)) as.take(ps.length - 1) :+ as.drop(ps.length - 1) + else as + } + val rawArgs = rawArgss.flatten + macroTrace("rawArgs: ")(rawArgs) + Some(rawArgs) + } + + /** Keeps track of macros in-flight. + * See more informations in comments to ``openMacros'' in ``scala.reflect.makro.Context''. + */ + var openMacros = List[MacroContext]() + + /** Performs macro expansion: + * 1) Checks whether the expansion needs to be delayed (see ``mustDelayMacroExpansion'') + * 2) Loads macro implementation using ``macroMirror'' + * 3) Synthesizes invocation arguments for the macro implementation + * 4) Checks that the result is a tree bound to this universe + * 5) Typechecks the result against the return type of the macro definition + * + * If -Ymacro-debug is enabled, you will get detailed log of how exactly this function + * performs class loading and method resolution in order to load the macro implementation. + * The log will also include other non-trivial steps of macro expansion. + * + * If -Ymacro-copypaste is enabled along with -Ymacro-debug, you will get macro expansions + * logged in the form that can be copy/pasted verbatim into REPL (useful for debugging!). + * + * @return + * the expansion result if the expansion has been successful, + * the fallback method invocation if the expansion has been unsuccessful, but there is a fallback, + * the expandee unchanged if the expansion has been delayed, + * the expandee fully expanded if the expansion has been delayed before and has been expanded now, + * the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation + * the expandee with an error marker set if there has been an error + */ + def macroExpand(typer: Typer, expandee: Tree, pt: Type): Tree = + macroExpand1(typer, expandee) match { + case Success(expanded) => try { - // @xeno.by: InfoLevel.Verbose examines and prints out infos of symbols - // by the means of this'es these symbols can climb up the lexical scope - // when these symbols will be examined by a node printer - // they will enumerate and analyze their children (ask for infos and tpes) - // if one of those children involves macro expansion, things might get nasty - // that's why I'm temporarily turning this behavior off - nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet - val expanded = mirror.invoke(receiver, rmeth)(rawArgs: _*) - expanded match { - case expanded: Tree => - val expectedTpe = tree.tpe - val typed = typer.typed(expanded, EXPRmode, expectedTpe) - Some(typed) - case expanded if expanded.isInstanceOf[Tree] => - typer.context.unit.error(tree.pos, "macro must return a compiler-specific tree; returned value is Tree, but it doesn't belong to this compiler's universe") - None - case expanded => - typer.context.unit.error(tree.pos, "macro must return a compiler-specific tree; returned value is of class: " + expanded.getClass) - None + var expectedTpe = expandee.tpe + + // [Eugene] weird situation. what's the conventional way to deal with it? + val isNullaryInvocation = expandee match { + case TypeApply(Select(_, _), _) => true + case Select(_, _) => true + case _ => false } - } catch { - case ex => - val realex = ReflectionUtils.unwrapThrowable(ex) - val msg = if (settings.Ymacrodebug.value) { - val stacktrace = new java.io.StringWriter() - realex.printStackTrace(new java.io.PrintWriter(stacktrace)) - System.getProperty("line.separator") + stacktrace - } else { - realex.getMessage - } - typer.context.unit.error(tree.pos, "exception during macro expansion: " + msg) - None + if (isNullaryInvocation) expectedTpe match { + case MethodType(Nil, restpe) => + macroTrace("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to:")(restpe) + expectedTpe = restpe + case _ => ; + } + + var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) + if (macroDebug) { + println("typechecked1:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) + if (macroDebug) { + println("typechecked2:") + println(typechecked) + println(showRaw(typechecked)) + } + + typechecked } finally { - nodePrinters.infolevel = savedInfolevel + openMacros = openMacros.tail } - case None => - def notFound() = { - typer.context.unit.error(tree.pos, "macro implementation not found: " + macroDef.name) - None - } - def fallBackToOverridden(tree: Tree): Option[Tree] = { - tree match { - case Select(qual, name) if (macroDef.isMacro) => - macroDef.allOverriddenSymbols match { - case first :: _ => - Some(Select(qual, name) setPos tree.pos setSymbol first) + case Fallback(fallback) => + typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt)) + case Other(result) => + result + } + + private sealed abstract class MacroExpansionResult extends Product with Serializable + private case class Success(expanded: Tree) extends MacroExpansionResult + private case class Fallback(fallback: Tree) extends MacroExpansionResult + private case class Other(result: Tree) extends MacroExpansionResult + private def Delay(expandee: Tree) = Other(expandee) + private def Skip(expanded: Tree) = Other(expanded) + private def Cancel(expandee: Tree) = Other(expandee) + private def Failure(expandee: Tree) = Other(expandee) + private def fail(typer: Typer, expandee: Tree, msg: String = null) = { + if (macroDebug || macroCopypaste) { + var msg1 = if (msg contains "exception during macro expansion") msg.split(EOL).drop(1).headOption.getOrElse("?") else msg + if (macroDebug) msg1 = msg + println("macro expansion has failed: %s".format(msg1)) + } + val pos = if (expandee.pos != NoPosition) expandee.pos else openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) + if (msg != null) typer.context.error(pos, msg) + typer.infer.setError(expandee) + Failure(expandee) + } + + /** Does the same as ``macroExpand'', but without typechecking the expansion + * Meant for internal use within the macro infrastructure, don't use it elsewhere. + */ + private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult = { + // if a macro implementation is incompatible or any of the arguments are erroneous + // there is no sense to expand the macro itself => it will only make matters worse + if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { + val reason = if (expandee.symbol.isErroneous) "incompatible macro implementation" else "erroneous arguments" + macroTrace("cancelled macro expansion because of %s: ".format(reason))(expandee) + return Cancel(typer.infer.setError(expandee)) + } + + if (!isDelayed(expandee)) { + if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + + val undetparams = calculateUndetparams(expandee) + if (undetparams.size != 0) { + macroTrace("macro expansion is delayed: ")(expandee) + delayed += expandee -> (typer.context, undetparams) + Delay(expandee) + } else { + val macroDef = expandee.symbol + macroRuntime(macroDef) match { + case Some(runtime) => + val savedInfolevel = nodePrinters.infolevel + try { + // InfoLevel.Verbose examines and prints out infos of symbols + // by the means of this'es these symbols can climb up the lexical scope + // when these symbols will be examined by a node printer + // they will enumerate and analyze their children (ask for infos and tpes) + // if one of those children involves macro expansion, things might get nasty + // that's why I'm temporarily turning this behavior off + nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet + val args = macroArgs(typer, expandee) + args match { + case Some(args) => + // adding stuff to openMacros is easy, but removing it is a nightmare + // it needs to be sprinkled over several different code locations + val (context: MacroContext) :: _ = args + openMacros = context :: openMacros + val expanded: MacroExpansionResult = try { + val prevNumErrors = reporter.ERROR.count + val expanded = runtime(args) + val currNumErrors = reporter.ERROR.count + if (currNumErrors != prevNumErrors) { + fail(typer, expandee) // errors have been reported by the macro itself + } else { + expanded match { + case expanded: Expr[_] => + if (macroDebug || macroCopypaste) { + if (macroDebug) println("original:") + println(expanded.tree) + println(showRaw(expanded.tree)) + } + + freeTerms(expanded.tree) foreach (fte => typer.context.error(expandee.pos, + ("macro expansion contains free term variable %s %s. "+ + "have you forgot to use eval when splicing this variable into a reifee? " + + "if you have troubles tracking free term variables, consider using -Xlog-free-terms").format(fte.name, fte.origin))) + freeTypes(expanded.tree) foreach (fty => typer.context.error(expandee.pos, + ("macro expansion contains free type variable %s %s. "+ + "have you forgot to use c.TypeTag annotation for this type parameter? " + + "if you have troubles tracking free type variables, consider using -Xlog-free-types").format(fty.name, fty.origin))) + + val currNumErrors = reporter.ERROR.count + if (currNumErrors != prevNumErrors) { + fail(typer, expandee) + } else { + // inherit the position from the first position-ful expandee in macro callstack + // this is essential for sane error messages + var tree = expanded.tree + var position = openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) + tree = atPos(position.focus)(tree) + + // now macro expansion gets typechecked against the macro definition return type + // however, this happens in macroExpand, not here in macroExpand1 + Success(tree) + } + case expanded if expanded.isInstanceOf[Expr[_]] => + val msg = "macro must return a compiler-specific expr; returned value is Expr, but it doesn't belong to this compiler's universe" + fail(typer, expandee, msg) + case expanded => + val msg = "macro must return a compiler-specific expr; returned value is of class: %s".format(expanded.getClass) + fail(typer, expandee, msg) + } + } + } catch { + case ex: Throwable => + openMacros = openMacros.tail + throw ex + } + if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail + expanded + case None => + fail(typer, expandee) // error has been reported by macroArgs + } + } catch { + case ex => + // [Eugene] any ideas about how to improve this one? + val realex = ReflectionUtils.unwrapThrowable(ex) + realex match { + case realex: reflect.makro.runtime.AbortMacroException => + if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg)) + fail(typer, expandee) // error has been reported by abort + case _ => + val message = { + try { + // the most reliable way of obtaining currently executing method + // http://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method + val currentMethodName = new Object(){}.getClass().getEnclosingMethod().getName + val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == currentMethodName) + if (relevancyThreshold == -1) None + else { + var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1) + var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1 + relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl + + realex.setStackTrace(relevantElements) + val message = new java.io.StringWriter() + realex.printStackTrace(new java.io.PrintWriter(message)) + Some(EOL + message) + } + } catch { + // if the magic above goes boom, just fall back to uninformative, but better than nothing, getMessage + case ex: Throwable => + None + } + } getOrElse realex.getMessage + fail(typer, expandee, "exception during macro expansion: " + message) + } + } finally { + nodePrinters.infolevel = savedInfolevel + } + case None => + def notFound() = { + typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " + + "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" + + "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " + + "in the second phase pointing to the output of the first phase") + None + } + def fallBackToOverridden(tree: Tree): Option[Tree] = { + tree match { + case Select(qual, name) if (macroDef.isTermMacro) => + macroDef.allOverriddenSymbols match { + case first :: _ => + Some(Select(qual, name) setPos tree.pos setSymbol first) + case _ => + macroTrace("macro is not overridden: ")(tree) + notFound() + } + case Apply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) + case _ => None + } + case TypeApply(fn, args) => + fallBackToOverridden(fn) match { + case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) + case _ => None + } case _ => - trace("macro is not overridden: ")(tree) + macroTrace("unexpected tree in fallback: ")(tree) notFound() } - case Apply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos) - case _ => None - } - case TypeApply(fn, args) => - fallBackToOverridden(fn) match { - case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos) - case _ => None - } - case _ => - trace("unexpected tree in fallback: ")(tree) - notFound() - } - } - fallBackToOverridden(tree) match { - case Some(tree1) => - trace("falling back to ")(tree1) - currentRun.macroExpansionFailed = true - Some(tree1) - case None => - None + } + fallBackToOverridden(expandee) match { + case Some(tree1) => + macroTrace("falling back to ")(tree1) + currentRun.macroExpansionFailed = true + Fallback(tree1) + case None => + fail(typer, expandee) + } } + } + } else { + val undetparams = calculateUndetparams(expandee) + if (undetparams.size != 0) + Delay(expandee) + else + Skip(macroExpandAll(typer, expandee)) } } + + /** Without any restrictions on macro expansion, macro applications will expand at will, + * and when type inference is involved, expansions will end up using yet uninferred type params. + * + * For some macros this might be ok (thanks to TreeTypeSubstituter that replaces + * the occurrences of undetparams with their inferred values), but in general case this won't work. + * E.g. for reification simple substitution is not enough - we actually need to re-reify inferred types. + * + * Luckily, there exists a very simple way to fix the problem: delay macro expansion until everything is inferred. + * Here are the exact rules. Macro application gets delayed if any of its subtrees contain: + * 1) type vars (tpe.isInstanceOf[TypeVar]) // [Eugene] this check is disabled right now, because TypeVars seem to be created from undetparams anyways + * 2) undetparams (sym.isTypeParameter && !sym.isSkolem) + */ + var hasPendingMacroExpansions = false + private val delayed = perRunCaches.newWeakMap[Tree, (Context, collection.mutable.Set[Int])] + private def isDelayed(expandee: Tree) = delayed contains expandee + private def calculateUndetparams(expandee: Tree): collection.mutable.Set[Int] = + delayed.get(expandee).map(_._2).getOrElse { + val calculated = collection.mutable.Set[Int]() + expandee foreach (sub => { + def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym.id + if (sub.symbol != null) traverse(sub.symbol) + if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol)) + }) + calculated + } + private val undetparams = perRunCaches.newSet[Int] + def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = undetparams ++= newUndets map (_.id) + def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = { + undetparams --= undetNoMore map (_.id) + if (!delayed.isEmpty) + delayed.toList foreach { + case (expandee, (_, undetparams)) if !undetparams.isEmpty => + undetparams --= undetNoMore map (_.id) + if (undetparams.isEmpty) { + hasPendingMacroExpansions = true + macroTrace("macro expansion is pending: ")(expandee) + } + case _ => + // do nothing + } + } + + /** Performs macro expansion on all subtrees of a given tree. + * Innermost macros are expanded first, outermost macros are expanded last. + * See the documentation for ``macroExpand'' for more information. + */ + def macroExpandAll(typer: Typer, expandee: Tree): Tree = + new Transformer { + override def transform(tree: Tree) = super.transform(tree match { + // todo. expansion should work from the inside out + case wannabe if (delayed contains wannabe) && calculateUndetparams(wannabe).isEmpty => + val (context, _) = delayed(wannabe) + delayed -= wannabe + macroExpand(newTyper(context), wannabe, WildcardType) + case _ => + tree + }) + }.transform(expandee) } diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 3d8c2ea564..6382e5a847 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -28,6 +28,7 @@ trait MethodSynthesis { else DefDef(sym, body) def applyTypeInternal(manifests: List[M[_]]): Type = { + // [Eugene to Paul] needs review!! val symbols = manifests map manifestToSymbol val container :: args = symbols val tparams = container.typeConstructor.typeParams @@ -58,12 +59,13 @@ trait MethodSynthesis { def newMethodType[F](owner: Symbol)(implicit m: Manifest[F]): Type = { val fnSymbol = manifestToSymbol(m) - assert(fnSymbol isSubClass FunctionClass(m.typeArguments.size - 1), (owner, m)) - val symbols = m.typeArguments map (m => manifestToSymbol(m)) - val formals = symbols.init map (_.typeConstructor) + assert(fnSymbol isSubClass FunctionClass(m.tpe.typeArguments.size - 1), (owner, m)) + // [Eugene to Paul] needs review!! + // val symbols = m.typeArguments map (m => manifestToSymbol(m)) + // val formals = symbols.init map (_.typeConstructor) + val formals = manifestToType(m).typeArguments val params = owner newSyntheticValueParams formals - - MethodType(params, symbols.last.typeConstructor) + MethodType(params, formals.last) } } import synthesisUtil._ @@ -373,7 +375,7 @@ trait MethodSynthesis { case ExistentialType(_, _) => TypeTree() case tp => TypeTree(tp) } - tpt setPos focusPos(derivedSym.pos) + tpt setPos derivedSym.pos.focus // keep type tree of original abstract field if (mods.isDeferred) tpt setOriginal tree.tpt diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 2539091966..696952fe6a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -624,11 +624,6 @@ trait Namers extends MethodSynthesis { enterCopyMethodOrGetter(tree, tparams) else sym setInfo completerOf(tree, tparams) - - if (mods hasFlag MACRO) { - if (!(sym.owner.isClass && sym.owner.isStatic)) - context.error(tree.pos, "macro definition must appear in globally accessible class") - } } def enterClassDef(tree: ClassDef) { @@ -651,14 +646,6 @@ trait Namers extends MethodSynthesis { val m = ensureCompanionObject(tree) classAndNamerOfModule(m) = (tree, null) } - val hasMacro = impl.body exists { - case DefDef(mods, _, _, _, _, _) => mods hasFlag MACRO - case _ => false - } - if (hasMacro) { - val m = ensureCompanionObject(tree) - classOfModuleClass(m.moduleClass) = new WeakReference(tree) - } val owner = tree.symbol.owner if (owner.isPackageObjectClass) { context.unit.warning(tree.pos, @@ -809,7 +796,9 @@ trait Namers extends MethodSynthesis { */ private def assignTypeToTree(tree: ValOrDefDef, defnTyper: Typer, pt: Type): Type = { // compute result type from rhs - val typedBody = defnTyper.computeType(tree.rhs, pt) + val typedBody = + if (tree.symbol.isTermMacro) defnTyper.computeMacroDefType(tree, pt) + else defnTyper.computeType(tree.rhs, pt) val sym = if (owner.isMethod) owner else tree.symbol val typedDefn = widenIfNecessary(sym, typedBody, pt) assignTypeToTree(tree, typedDefn) @@ -871,10 +860,8 @@ trait Namers extends MethodSynthesis { Namers.this.classOfModuleClass get clazz foreach { cdefRef => val cdef = cdefRef() if (cdef.mods.isCase) addApplyUnapply(cdef, templateNamer) - if (settings.Xmacros.value) addMacroMethods(cdef.impl, templateNamer) classOfModuleClass -= clazz } - if (settings.Xmacros.value) addMacroMethods(templ, templateNamer) } // add the copy method to case classes; this needs to be done here, not in SyntheticMethods, because @@ -1029,12 +1016,20 @@ trait Namers extends MethodSynthesis { } addDefaultGetters(meth, vparamss, tparams, overriddenSymbol) + // macro defs need to be typechecked in advance + // because @macroImpl annotation only gets assigned during typechecking + // otherwise we might find ourselves in the situation when we specified -Xmacro-fallback-classpath + // but macros still don't expand + // that might happen because macro def doesn't have its link a macro impl yet + if (ddef.symbol.isTermMacro) { + val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) + typer.computeMacroDefType(ddef, pt) + } + thisMethodType({ val rt = ( if (!tpt.isEmpty) { typer.typedType(tpt).tpe - } else if (meth.isMacro) { - assignTypeToTree(ddef, AnyClass.tpe) } else { // replace deSkolemized symbols with skolemized ones // (for resultPt computed by looking at overridden symbol, right?) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 806ee480f0..ad727d4082 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -227,6 +227,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R * 1.8.1 M's type is a subtype of O's type, or * 1.8.2 M is of type []S, O is of type ()T and S <: T, or * 1.8.3 M is of type ()S, O is of type []T and S <: T, or + * 1.9. If M is a macro def, O cannot be deferred. + * 1.10. If M is not a macro def, O cannot be a macro def. * 2. Check that only abstract classes have deferred members * 3. Check that concrete classes do not have deferred definitions * that are not implemented in a subclass. @@ -416,6 +418,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R } else if (other.isValue && other.isLazy && !other.isSourceMethod && !other.isDeferred && member.isValue && !member.isLazy) { overrideError("must be declared lazy to override a concrete lazy value") + } else if (other.isDeferred && member.isTermMacro) { // (1.9) + overrideError("cannot override an abstract method") + } else if (other.isTermMacro && !member.isTermMacro) { // (1.10) + overrideError("cannot override a macro") } else { checkOverrideTypes() if (settings.warnNullaryOverride.value) { diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 3233b7b07c..38c2c5f719 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -456,14 +456,20 @@ trait TypeDiagnostics { ex match { case CyclicReference(sym, info: TypeCompleter) => - val pos = info.tree match { - case Import(expr, _) => expr.pos - case _ => ex.pos + if (context0.owner.isTermMacro) { + // see comments to TypeSigError for an explanation of this special case + // [Eugene] is there a better way? + throw ex + } else { + val pos = info.tree match { + case Import(expr, _) => expr.pos + case _ => ex.pos + } + contextError(context0, pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage()) + + if (sym == ObjectClass) + throw new FatalError("cannot redefine root "+sym) } - contextError(context0, pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage()) - - if (sym == ObjectClass) - throw new FatalError("cannot redefine root "+sym) case _ => contextError(context0, ex.pos, ex) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f558e0afc7..1b508a96fe 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -51,6 +51,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { transformed.clear() } + // [Eugene] shouldn't this be converted to resetAllAttrs? object UnTyper extends Traverser { override def traverse(tree: Tree) = { if (tree != EmptyTree) tree.tpe = null @@ -181,7 +182,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case _ => def wrapImplicit(from: Type): Tree = { val result = inferImplicit(tree, functionType(List(from), to), reportAmbiguous, true, context, saveErrors) - if (result.subst != EmptyTreeTypeSubstituter) result.subst traverse tree + if (result.subst != EmptyTreeTypeSubstituter) { + result.subst traverse tree + notifyUndetparamsInferred(result.subst.from, result.subst.to) + } result.tree } val result = wrapImplicit(from) @@ -813,7 +817,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case Block(_, tree1) => tree1.symbol case _ => tree.symbol } - if (!meth.isConstructor && !meth.isMacro && isFunctionType(pt)) { // (4.2) + if (!meth.isConstructor && !meth.isTermMacro && isFunctionType(pt)) { // (4.2) debuglog("eta-expanding " + tree + ":" + tree.tpe + " to " + pt) checkParamsConvertible(tree, tree.tpe) val tree0 = etaExpand(context.unit, tree) @@ -1008,12 +1012,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else TypeApply(tree, tparams1 map (tparam => TypeTree(tparam.tpeHK) setPos tree.pos.focus)) setPos tree.pos //@M/tcpolyinfer: changed tparam.tpe to tparam.tpeHK context.undetparams ++= tparams1 + notifyUndetparamsAdded(tparams1) adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt, original) case mt: MethodType if mt.isImplicit && ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1) adaptToImplicitMethod(mt) case mt: MethodType if (((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) && - (context.undetparams.isEmpty || inPolyMode(mode))) => + (context.undetparams.isEmpty || inPolyMode(mode))) && !(tree.symbol != null && tree.symbol.isTermMacro) => instantiateToMethodType(mt) case _ => @@ -1026,13 +1031,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } if (tree.isType) adaptType() - else if (inExprModeButNot(mode, FUNmode) && tree.symbol != null && tree.symbol.isMacro && !tree.isDef && !(tree exists (_.isErroneous))) - macroExpand(tree, this) match { - case Some(expanded: Tree) => - typed(expanded, mode, pt) - case None => - setError(tree) // error already reported - } + else if (context.macrosEnabled && // when macros are enabled + inExprModeButNot(mode, FUNmode) && !tree.isDef && // and typechecking application + tree.symbol != null && tree.symbol.isTermMacro) // of a term macro + macroExpand(this, tree, pt) else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode)) adaptConstrPattern() else if (inAllModes(mode, EXPRmode | FUNmode) && @@ -1906,8 +1908,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { meth.owner.isAnonOrRefinementClass)) InvalidConstructorDefError(ddef) typed(ddef.rhs) - } else if (meth.isMacro) { - EmptyTree + } else if (meth.isTermMacro) { + // typechecking macro bodies is sort of unconventional + // that's why we employ our custom typing scheme orchestrated outside of the typer + transformedOr(ddef.rhs, typedMacroBody(this, ddef)) } else { transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe) } @@ -2212,7 +2216,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { (ps, sel) case Some((vparams, sel)) => val newParamSyms = (vparams, formals).zipped map {(p, tp) => - methodSym.newValueParameter(p.name, focusPos(p.pos), SYNTHETIC) setInfo tp + methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp } (newParamSyms, sel.duplicate) @@ -2267,7 +2271,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else { // applyOrElse's default parameter: val B1 = methodSym newTypeParameter(newTypeName("B1")) setInfo TypeBounds.empty //lower(resTp) - val default = methodSym newValueParameter(newTermName("default"), focusPos(tree.pos), SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe) + val default = methodSym newValueParameter(newTermName("default"), tree.pos.focus, SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe) val paramSyms = List(x, default) methodSym setInfoAndEnter polyType(List(A1, B1), MethodType(paramSyms, B1.tpe)) @@ -2489,7 +2493,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { var e1 = scope.lookupNextEntry(e) while ((e1 ne null) && e1.owner == scope) { if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) && - (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe) || e.sym.isMacro && e1.sym.isMacro)) + (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe))) // default getters are defined twice when multiple overloads have defaults. an // error for this is issued in RefChecks.checkDefaultsInOverloaded if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefault && @@ -2575,7 +2579,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else if (isByNameParamType(formals.head)) 0 else BYVALmode ) - val tree = typedArg(args.head, mode, typedMode, adapted.head) + var tree = typedArg(args.head, mode, typedMode, adapted.head) + if (hasPendingMacroExpansions) tree = macroExpandAll(this, tree) // formals may be empty, so don't call tail tree :: loop(args.tail, formals drop 1, adapted.tail) } @@ -2737,6 +2742,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def tryNamesDefaults: Tree = { val lencmp = compareLengths(args, formals) + def checkNotMacro() = { + if (fun.symbol != null && fun.symbol.filter(sym => sym != null && sym.isTermMacro) != NoSymbol) + duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun)) + } + if (mt.isErroneous) duplErrTree else if (inPatternMode(mode)) { // #2064 @@ -2755,8 +2765,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { else if (isIdentity(argPos) && !isNamedApplyBlock(fun)) { // if there's no re-ordering, and fun is not transformed, no need to transform // more than an optimization, e.g. important in "synchronized { x = update-x }" + checkNotMacro() doTypedApply(tree, fun, namelessArgs, mode, pt) } else { + checkNotMacro() transformNamedApplication(Typer.this, mode, pt)( treeCopy.Apply(tree, fun, namelessArgs), argPos) } @@ -2764,6 +2776,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { // defaults are needed. they are added to the argument list in named style as // calls to the default getters. Example: // foo[Int](a)() ==> foo[Int](a)(b = foo$qual.foo$default$2[Int](a)) + checkNotMacro() val fun1 = transformNamedApplication(Typer.this, mode, pt)(fun, x => x) if (fun1.isErroneous) duplErrTree else { @@ -3111,7 +3124,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } if (hasError) annotationError - else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setOriginal(ann).setPos(ann.pos) + else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setOriginal(Apply(typedFun, args)).setPos(ann.pos) } } else if (requireJava) { reportAnnotationError(NestedAnnotationError(ann, annType)) @@ -3151,7 +3164,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def annInfo(t: Tree): AnnotationInfo = t match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => - AnnotationInfo(annType, args, List()).setOriginal(ann).setPos(t.pos) + AnnotationInfo(annType, args, List()).setOriginal(typedAnn).setPos(t.pos) case Block(stats, expr) => context.warning(t.pos, "Usage of named or default arguments transformed this annotation\n"+ @@ -3437,7 +3450,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { println(s) } - protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = { + def typed1(tree: Tree, mode: Int, pt: Type): Tree = { def isPatternMode = inPatternMode(mode) //Console.println("typed1("+tree.getClass()+","+Integer.toHexString(mode)+","+pt+")") @@ -3451,10 +3464,27 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } def typedAnnotated(ann: Tree, arg1: Tree): Tree = { - def mkTypeTree(tpe: Type) = TypeTree(tpe) setOriginal tree setPos tree.pos.focus /** mode for typing the annotation itself */ val annotMode = mode & ~TYPEmode | EXPRmode + def resultingTypeTree(tpe: Type) = { + // we need symbol-ful originals for reification + // hence we go the extra mile to hand-craft tis guy + val original = + if (arg1.isType) + (tree, arg1) match { + case (Annotated(annot, arg), tt @ TypeTree()) => Annotated(annot, tt.original) + // this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)" + case (Annotated(annot, arg), _) => Annotated(annot, arg1) + case _ => throw new Error("unexpected trees in typedAnnotated: tree = %s, arg1 = %s".format(showRaw(tree), showRaw(arg1))) + } + else + tree + original setType ann.tpe + original setPos tree.pos.focus + TypeTree(tpe) setOriginal original setPos tree.pos.focus + } + if (arg1.isType) { // make sure the annotation is only typechecked once if (ann.tpe == null) { @@ -3497,11 +3527,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { arg1 // simply drop erroneous annotations else { ann.tpe = atype - mkTypeTree(atype) + resultingTypeTree(atype) } } else { // the annotation was typechecked before - mkTypeTree(ann.tpe) + resultingTypeTree(ann.tpe) } } else { @@ -3510,7 +3540,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { ann.tpe = arg1.tpe.withAnnotation(annotInfo) } val atype = ann.tpe - Typed(arg1, mkTypeTree(atype)) setPos tree.pos setType atype + Typed(arg1, resultingTypeTree(atype)) setPos tree.pos.focus setType atype } } @@ -3676,6 +3706,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { if (checkStablePrefixClassType(tpt0)) if (tpt0.hasSymbol && !tpt0.symbol.typeParams.isEmpty) { context.undetparams = cloneSymbols(tpt0.symbol.typeParams) + notifyUndetparamsAdded(context.undetparams) TypeTree().setOriginal(tpt0) .setType(appliedType(tpt0.tpe, context.undetparams map (_.tpeHK))) // @PP: tpeHK! #3343, #4018, #4347. } else tpt0 @@ -4534,7 +4565,18 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { typedNew(tpt) case Typed(expr, Function(List(), EmptyTree)) => - typedEta(checkDead(typed1(expr, mode, pt))) + // find out whether the programmer is trying to eta-expand a macro def + // to do that we need to typecheck the tree first (we need a symbol of the eta-expandee) + // that typecheck must not trigger macro expansions, so we explicitly prohibit them + // Q: "but, " - you may ask - ", `typed1` doesn't call adapt, which does macro expansion, so why explicit check?" + // A: solely for robustness reasons. this mechanism might change in the future, which might break unprotected code + val expr1 = context.withMacrosDisabled(typed1(expr, mode, pt)) + expr1 match { + case macroDef if macroDef.symbol.isTermMacro => + MacroEtaError(expr1) + case _ => + typedEta(checkDead(expr1)) + } case Typed(expr0, tpt @ Ident(tpnme.WILDCARD_STAR)) => val expr = typed(expr0, onlyStickyModes(mode), WildcardType) @@ -4608,18 +4650,17 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { tpt.tpe.typeSymbol == ArrayClass && args.length == 1 && erasure.GenericArray.unapply(tpt.tpe).isDefined) => // !!! todo simplify by using extractor - // convert new Array[T](len) to evidence[ClassManifest[T]].newArray(len) - // convert new Array^N[T](len) for N > 1 to evidence[ClassManifest[T]].newArrayN(len) - val Some((level, manifType)) = erasure.GenericArray.unapply(tpt.tpe) - if (level > MaxArrayDims) - MultiDimensionalArrayError(tree) - else { - val newArrayApp = atPos(tree.pos) { - val manif = getManifestTree(tree, manifType, false) - new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args) - } - typed(newArrayApp, mode, pt) + // convert new Array[T](len) to evidence[ClassTag[T]].newArray(len) + // convert new Array^N[T](len) for N > 1 to evidence[ClassTag[Array[...Array[T]...]]].newArray(len), where Array HK gets applied (N-1) times + // [Eugene] no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions) + val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe) + val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.asType, List(tpe))).last + val newArrayApp = atPos(tree.pos) { + val tag = resolveClassTag(tree, tagType) + if (tag.isEmpty) MissingClassTagError(tree, tagType) + else new ApplyToImplicitArgs(Select(tag, nme.newArray), args) } + typed(newArrayApp, mode, pt) case tree1 => tree1 } @@ -4679,7 +4720,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case ReferenceToBoxed(idt @ Ident(_)) => val id1 = typed1(idt, mode, pt) match { case id: Ident => id } - treeCopy.ReferenceToBoxed(tree, id1) setType AnyRefClass.tpe + // [Eugene] am I doing it right? + val erasedTypes = phaseId(currentPeriod) >= currentRun.erasurePhase.id + val tpe = capturedVariableType(idt.symbol, erasedTypes = erasedTypes) + treeCopy.ReferenceToBoxed(tree, id1) setType tpe case Literal(value) => tree setType ( @@ -4916,31 +4960,75 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def typedTypeConstructor(tree: Tree): Tree = typedTypeConstructor(tree, NOmode) def computeType(tree: Tree, pt: Type): Type = { + // macros employ different logic of `computeType` + assert(!context.owner.isTermMacro, context.owner) val tree1 = typed(tree, pt) transformed(tree) = tree1 packedType(tree1, context.owner) } + def computeMacroDefType(tree: Tree, pt: Type): Type = { + assert(context.owner.isTermMacro, context.owner) + assert(tree.symbol.isTermMacro, tree.symbol) + assert(tree.isInstanceOf[DefDef], tree.getClass) + val ddef = tree.asInstanceOf[DefDef] + + val tree1 = + if (transformed contains ddef.rhs) { + // macro defs are typechecked in `methodSig` (by calling this method) in order to establish their link to macro implementation asap + // if a macro def doesn't have explicitly specified return type, this method will be called again by `assignTypeToTree` + // here we guard against this case + transformed(ddef.rhs) + } else { + val tree1 = typedMacroBody(this, ddef) + transformed(ddef.rhs) = tree1 + tree1 + } + + val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) + if (isMacroBodyOkay) computeMacroDefTypeFromMacroImpl(ddef, tree.symbol, tree1.symbol) else AnyClass.tpe + } + + def transformedOr(tree: Tree, op: => Tree): Tree = transformed.get(tree) match { + case Some(tree1) => transformed -= tree; tree1 + case None => op + } + def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match { case Some(tree1) => transformed -= tree; tree1 case None => typed(tree, mode, pt) } - def findManifest(tp: Type, full: Boolean) = beforeTyper { + // `tree` is only necessary here for its position + // but that's invaluable for error reporting, so I decided to include it into this method's contract + // before passing EmptyTree, please, consider passing something meaningful first + def resolveClassTag(tree: Tree, tp: Type): Tree = beforeTyper { inferImplicit( EmptyTree, - appliedType((if (full) FullManifestClass else PartialManifestClass).typeConstructor, List(tp)), - true, false, context) + appliedType(ClassTagClass.typeConstructor, List(tp)), + /*reportAmbiguous =*/ true, + /*isView =*/ false, + /*context =*/ context, + /*saveAmbiguousDivergent =*/ true, + /*pos =*/ tree.pos + ).tree } - def getManifestTree(tree: Tree, tp: Type, full: Boolean): Tree = { - val manifestOpt = findManifest(tp, full) - if (manifestOpt.tree.isEmpty) { - MissingManifestError(tree, full, tp) - } else { - manifestOpt.tree - } + // `tree` is only necessary here for its position + // but that's invaluable for error reporting, so I decided to include it into this method's contract + // before passing EmptyTree, please, consider passing something meaningful first + def resolveTypeTag(tree: Tree, pre: Type, tp: Type, full: Boolean): Tree = beforeTyper { + inferImplicit( + EmptyTree, + appliedType(singleType(pre, pre member (if (full) GroundTypeTagClass else TypeTagClass).name), List(tp)), + /*reportAmbiguous =*/ true, + /*isView =*/ false, + /*context =*/ context, + /*saveAmbiguousDivergent =*/ true, + /*pos =*/ tree.pos + ).tree } + /* def convertToTypeTree(tree: Tree): Tree = tree match { case TypeTree() => tree diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index ce10ee34a2..11d7db5180 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -27,7 +27,7 @@ object ClassPath { def scalaCompiler = locate[Global] def infoFor[T](value: T) = info(value.getClass) - def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassManifest fromClass clazz) + def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassManifest[T](clazz)) def info[T: ClassManifest] = new ClassAndJarInfo[T] def locate[T: ClassManifest] = info[T] rootClasspath def locateJar[T: ClassManifest] = info[T].rootPossibles find (x => isJarOrZip(x)) map (x => File(x)) diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala index bc74717366..573f7bc7b2 100644 --- a/src/compiler/scala/tools/nsc/util/Position.scala +++ b/src/compiler/scala/tools/nsc/util/Position.scala @@ -33,62 +33,24 @@ object Position { } } -/** - * A tree does not directly store a Position. It stores a TreeAnnotation, which /typically/ is a Position. - * - * A TreeAnnotion may encompass more than just a Position, though, depending on the exact subclass of TreeAnnotation. - */ -trait TreeAnnotation { - def pos: Position -} +trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachment { + /** Exposes itself as payload of Attachment */ + // necessary for conformance with Attachment + def pos: Position = this + /** A bit weird method that is necessary to safely update positions without destroying custom attachments */ + // necessary for conformance with Attachment + def withPos(pos: scala.reflect.api.Position) = pos -/** The Position class and its subclasses represent positions of ASTs and symbols. - * Except for NoPosition and FakePos, every position refers to a SourceFile - * and to an offset in the sourcefile (its `point`). For batch compilation, - * that's all. For interactive IDE's there are also RangePositions - * and TransparentPositions. A RangePosition indicates a start and an end - * in addition to its point. TransparentPositions are a subclass of RangePositions. - * Range positions that are not transparent are called opaque. - * Trees with RangePositions need to satisfy the following invariants. - * - * INV1: A tree with an offset position never contains a child - * with a range position - * INV2: If the child of a tree with a range position also has a range position, - * then the child's range is contained in the parent's range. - * INV3: Opaque range positions of children of the same node are non-overlapping - * (this means their overlap is at most a single point). - * - * The following tests are useful on positions: - * - * pos.isDefined true if position is not a NoPosition nor a FakePosition - * pos.isRange true if position is a range - * pos.isOpaqueRange true if position is an opaque range - * - * The following accessor methods are provided: - * - * pos.source The source file of the position, which must be defined - * pos.point The offset of the position's point, which must be defined - * pos.start The start of the position, which must be a range - * pos.end The end of the position, which must be a range - * - * There are also convenience methods, such as - * - * pos.startOrPoint - * pos.endOrPoint - * pos.pointOrElse(default) - * - * These are less strict about the kind of position on which they can be applied. - * - * The following conversion methods are often used: - * - * pos.focus converts a range position to an offset position, keeping its point; - * returns all other positions unchanged. - * pos.makeTransparent converts an opaque range position into a transparent one. - * returns all other positions unchanged. - */ -trait Position extends TreeAnnotation { - def pos: Position = this + /** Java file corresponding to the source file of this position. + */ + // necessary for conformance with scala.reflect.api.Position + def fileInfo: java.io.File = source.file.file + + /** Contents of the source file that contains this position. + */ + // necessary for conformance with scala.reflect.api.Position + def fileContent: Array[Char] = source.content /** An optional value containing the source file referred to by this position, or * None if not defined. @@ -134,74 +96,74 @@ trait Position extends TreeAnnotation { def offset: Option[Int] = if (isDefined) Some(point) else None /** The same position with a different start value (if a range) */ - def withStart(off: Int) = this + def withStart(off: Int): Position = this /** The same position with a different end value (if a range) */ - def withEnd(off: Int) = this + def withEnd(off: Int): Position = this /** The same position with a different point value (if a range or offset) */ - def withPoint(off: Int) = this + def withPoint(off: Int): Position = this /** The same position with a different source value, and its values shifted by given offset */ - def withSource(source: SourceFile, shift: Int) = this + def withSource(source: SourceFile, shift: Int): Position = this /** If this is a range, the union with the other range, with the point of this position. * Otherwise, this position */ - def union(pos: Position) = this + def union(pos: scala.reflect.api.Position): Position = this /** If this is a range position, the offset position of its start. * Otherwise the position itself */ - def focusStart = this + def focusStart: Position = this /** If this is a range position, the offset position of its point. * Otherwise the position itself */ - def focus = this + def focus: Position = this /** If this is a range position, the offset position of its end. * Otherwise the position itself */ - def focusEnd = this + def focusEnd: Position = this /** Does this position include the given position `pos`. * This holds if `this` is a range position and its range [start..end] * is the same or covers the range of the given position, which may or may not be a range position. */ - def includes(pos: Position) = false + def includes(pos: scala.reflect.api.Position): Boolean = false /** Does this position properly include the given position `pos` ("properly" meaning their * ranges are not the same)? */ - def properlyIncludes(pos: Position) = + def properlyIncludes(pos: scala.reflect.api.Position): Boolean = includes(pos) && (start < pos.startOrPoint || pos.endOrPoint < end) /** Does this position precede that position? * This holds if both positions are defined and the end point of this position * is not larger than the start point of the given position. */ - def precedes(pos: Position) = + def precedes(pos: scala.reflect.api.Position): Boolean = isDefined && pos.isDefined && endOrPoint <= pos.startOrPoint /** Does this position properly precede the given position `pos` ("properly" meaning their ranges * do not share a common point). */ - def properlyPrecedes(pos: Position) = + def properlyPrecedes(pos: scala.reflect.api.Position): Boolean = isDefined && pos.isDefined && endOrPoint < pos.startOrPoint /** Does this position overlap with that position? * This holds if both positions are ranges and there is an interval of * non-zero length that is shared by both position ranges. */ - def overlaps(pos: Position) = + def overlaps(pos: scala.reflect.api.Position): Boolean = isRange && pos.isRange && ((pos.start < end && start < pos.end) || (start < pos.end && pos.start < end)) /** Does this position cover the same range as that position? * Holds only if both position are ranges */ - def sameRange(pos: Position) = + def sameRange(pos: scala.reflect.api.Position): Boolean = isRange && pos.isRange && start == pos.start && end == pos.end def line: Int = throw new UnsupportedOperationException("Position.line") @@ -219,11 +181,11 @@ trait Position extends TreeAnnotation { * file. If the SourceFile is a normal SourceFile, simply * return this. */ - def inUltimateSource(source : SourceFile) = + def inUltimateSource(source : SourceFile): Position = if (source == null) this else source.positionInUltimateSource(this) - def dbgString = toString - def safeLine = try line catch { case _: UnsupportedOperationException => -1 } + def dbgString: String = toString + def safeLine: Int = try line catch { case _: UnsupportedOperationException => -1 } def show: String = "["+toString+"]" } @@ -254,8 +216,10 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e col + 1 } - override def union(pos: Position) = - if (pos.isRange) pos else this + override def union(pos: scala.reflect.api.Position) = + // [Eugene] how do I get rid of this cast? + // I could introduce a "type PositionType <: scala.reflect.api.Position", but that's also ugly + if (pos.isRange) pos.asInstanceOf[Position] else this override def equals(that : Any) = that match { case that : OffsetPosition => point == that.point && source.file == that.source.file @@ -265,7 +229,7 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e override def toString = { val pointmsg = if (point > source.length) "out-of-bounds-" else "offset=" - "source-%s,line-%s,%s%s".format(source.path, line, pointmsg, point) + "source-%s,line-%s,%s%s".format(source.file.canonicalPath, line, pointmsg, point) } override def show = "["+point+"]" } @@ -289,8 +253,8 @@ extends OffsetPosition(source, point) { } override def focusEnd = new OffsetPosition(source, end) override def makeTransparent = new TransparentPosition(source, start, point, end) - override def includes(pos: Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end - override def union(pos: Position) = + override def includes(pos: scala.reflect.api.Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end + override def union(pos: scala.reflect.api.Position): Position = if (pos.isRange) new RangePosition(source, start min pos.start, point, end max pos.end) else this override def toSingleLine: Position = source match { @@ -301,7 +265,7 @@ extends OffsetPosition(source, point) { case _ => this } - override def toString = "RangePosition("+source+", "+start+", "+point+", "+end+")" + override def toString = "RangePosition("+source.file.canonicalPath+", "+start+", "+point+", "+end+")" override def show = "["+start+":"+end+"]" private var focusCache: Position = NoPosition } @@ -311,10 +275,4 @@ class TransparentPosition(source: SourceFile, start: Int, point: Int, end: Int) override def isTransparent = true override def makeTransparent = this override def show = "<"+start+":"+end+">" -} - - - - - - +} \ No newline at end of file diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala index 8f5e099fbf..f5c836a4e9 100644 --- a/src/compiler/scala/tools/reflect/package.scala +++ b/src/compiler/scala/tools/reflect/package.scala @@ -27,7 +27,7 @@ package object reflect { } } - def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest.classType(clazz)) + def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest(ClassManifest(clazz).tpe)) def zeroOf[T](implicit m: Manifest[T]): AnyRef = { if (m == manifest[Boolean] || m == manifest[jl.Boolean]) false: jl.Boolean else if (m == manifest[Unit] || m == manifest[jl.Void] || m == manifest[scala.runtime.BoxedUnit]) scala.runtime.BoxedUnit.UNIT diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index b5006e7948..d241d2ddc0 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -99,17 +99,40 @@ object Predef extends LowPriorityImplicits { // def AnyRef = scala.AnyRef // Manifest types, companions, and incantations for summoning + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") type ClassManifest[T] = scala.reflect.ClassManifest[T] - type Manifest[T] = scala.reflect.Manifest[T] + @deprecated("OptManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") type OptManifest[T] = scala.reflect.OptManifest[T] + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + type Manifest[T] = scala.reflect.Manifest[T] + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") val ClassManifest = scala.reflect.ClassManifest - val Manifest = scala.reflect.Manifest - val NoManifest = scala.reflect.NoManifest + // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + lazy val Manifest = scala.reflect.Manifest // needs to be lazy, because requires scala.reflect.mirror instance + @deprecated("NoManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") + lazy val NoManifest = scala.reflect.NoManifest // needs to be lazy, because requires scala.reflect.mirror instance def manifest[T](implicit m: Manifest[T]) = m def classManifest[T](implicit m: ClassManifest[T]) = m def optManifest[T](implicit m: OptManifest[T]) = m + // Tag types and companions, and incantations for summoning + type ClassTag[T] = scala.reflect.ClassTag[T] + type TypeTag[T] = scala.reflect.TypeTag[T] + type GroundTypeTag[T] = scala.reflect.GroundTypeTag[T] + val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type + // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. + lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance + lazy val GroundTypeTag = scala.reflect.GroundTypeTag + + // [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts + def classTag[T](implicit ctag: ClassTag[T]) = ctag + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag + // Minor variations on identity functions def identity[A](x: A): A = x // @see `conforms` for the implicit version @inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero` diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index f0e4c79abf..e396b0695e 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -33,8 +33,22 @@ object ArrayBuilder { * @tparam T type of the elements for the array builder, with a `ClassManifest` context bound. * @return a new empty array builder. */ - def make[T: ClassManifest](): ArrayBuilder[T] = - implicitly[ClassManifest[T]].newArrayBuilder() + def make[T: ClassManifest](): ArrayBuilder[T] = { + val manifest = implicitly[ClassManifest[T]] + val erasure = manifest.erasure + erasure match { + case java.lang.Byte.TYPE => new ArrayBuilder.ofByte().asInstanceOf[ArrayBuilder[T]] + case java.lang.Short.TYPE => new ArrayBuilder.ofShort().asInstanceOf[ArrayBuilder[T]] + case java.lang.Character.TYPE => new ArrayBuilder.ofChar().asInstanceOf[ArrayBuilder[T]] + case java.lang.Integer.TYPE => new ArrayBuilder.ofInt().asInstanceOf[ArrayBuilder[T]] + case java.lang.Long.TYPE => new ArrayBuilder.ofLong().asInstanceOf[ArrayBuilder[T]] + case java.lang.Float.TYPE => new ArrayBuilder.ofFloat().asInstanceOf[ArrayBuilder[T]] + case java.lang.Double.TYPE => new ArrayBuilder.ofDouble().asInstanceOf[ArrayBuilder[T]] + case java.lang.Boolean.TYPE => new ArrayBuilder.ofBoolean().asInstanceOf[ArrayBuilder[T]] + case java.lang.Void.TYPE => new ArrayBuilder.ofUnit().asInstanceOf[ArrayBuilder[T]] + case _ => new ArrayBuilder.ofRef[T with AnyRef]()(manifest.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] + } + } /** A class for array builders for arrays of reference types. * diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 5f7c508181..3e7b8071be 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -39,8 +39,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza private def rowBuilder[U]: Builder[U, Array[U]] = Array.newBuilder( - ClassManifest.fromClass( - repr.getClass.getComponentType.getComponentType.asInstanceOf[Predef.Class[U]])) + ClassManifest[U]( + repr.getClass.getComponentType.getComponentType)) override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) { var l = math.min(len, repr.length) @@ -87,8 +87,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza } } val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder( - ClassManifest.fromClass( - repr.getClass.getComponentType.asInstanceOf[Predef.Class[Array[U]]])) + ClassManifest[Array[U]]( + repr.getClass.getComponentType)) for (b <- bs) bb += b.result bb.result } @@ -110,7 +110,7 @@ object ArrayOps { override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr) override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr) override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()( - ClassManifest.classType[T](repr.getClass.getComponentType)) + ClassManifest[T](repr.getClass.getComponentType)) def length: Int = repr.length def apply(index: Int): T = repr(index) diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 4287bac249..fac4eb77bb 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -112,7 +112,7 @@ object WrappedArray { def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable { - lazy val elemManifest = ClassManifest.classType[T](array.getClass.getComponentType) + lazy val elemManifest = ClassManifest[T](array.getClass.getComponentType) def length: Int = array.length def apply(index: Int): T = array(index).asInstanceOf[T] def update(index: Int, elem: T) { array(index) = elem } diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala index 9771a45a28..fce65468e9 100644 --- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala +++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala @@ -28,7 +28,19 @@ class WrappedArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, Wrap private var size: Int = 0 private def mkArray(size: Int): WrappedArray[A] = { - val newelems = manifest.newWrappedArray(size) + val erasure = manifest.erasure + val newelems = erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](size)).asInstanceOf[WrappedArray[A]] + case _ => new WrappedArray.ofRef[A with AnyRef](manifest.newArray(size).asInstanceOf[Array[A with AnyRef]]).asInstanceOf[WrappedArray[A]] + } if (this.size > 0) Array.copy(elems.array, 0, newelems.array, 0, this.size) newelems } diff --git a/src/library/scala/reflect/ArrayTags.scala b/src/library/scala/reflect/ArrayTags.scala new file mode 100644 index 0000000000..8df7fe5f4e --- /dev/null +++ b/src/library/scala/reflect/ArrayTags.scala @@ -0,0 +1,19 @@ +package scala.reflect + +/** An `ArrayTag[T]` is a descriptor that is requested by the compiler every time + * when an array is instantiated, but the element type is unknown at compile time. + * + * Scala library provides a standard implementation of this trait, + * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T. + * + * However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit + * and then expose the implementation via an implicit macro. + */ +@annotation.implicitNotFound(msg = "No ArrayTag available for ${T}") +trait ArrayTag[T] { + /** Produces an `ArrayTag` that knows how to build `Array[Array[T]]` */ + def wrap: ArrayTag[Array[T]] + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] +} \ No newline at end of file diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala deleted file mode 100644 index 37be067614..0000000000 --- a/src/library/scala/reflect/ClassManifest.scala +++ /dev/null @@ -1,263 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -/* [Martin] - * Todo: ClassManifests currently contain all available type arguments. - * That's a waste of cycles if all that's needed is the class. - * We should have instead consider a structure like this: - * - * OptManifest - * / \ - * / \ - * PartialManifest ClassManifest - * \ / - * \ / - * Manifest - * - * where PartialManifest means: generate as much as you can, use NoManifest - * where nothing is known, and - * ClassManifest means: generate exactly the top-level class, and nothing else. - */ -package scala.reflect - -import scala.collection.mutable.{ WrappedArray, ArrayBuilder } -import java.lang.{ Class => jClass } - -/** A `ClassManifest[T]` is an opaque descriptor for type `T`. - * It is used by the compiler to preserve information necessary - * for instantiating `Arrays` in those cases where the element type - * is unknown at compile time. - * - * The type-relation operators make an effort to present a more accurate - * picture than can be realized with erased types, but they should not be - * relied upon to give correct answers. In particular they are likely to - * be wrong when variance is involved or when a subtype has a different - * number of type arguments than a supertype. - */ -trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable { - /** A class representing the type `U` to which `T` would be erased. Note - * that there is no subtyping relationship between `T` and `U`. */ - def erasure: jClass[_] - - /** The Scala type described by this manifest. - */ - lazy val tpe: mirror.Type = mirror.classToType(erasure) - - def symbol: mirror.Symbol = mirror.classToSymbol(erasure) - - private def subtype(sub: jClass[_], sup: jClass[_]): Boolean = { - def loop(left: Set[jClass[_]], seen: Set[jClass[_]]): Boolean = { - left.nonEmpty && { - val next = left.head - val supers = next.getInterfaces.toSet ++ Option(next.getSuperclass) - supers(sup) || { - val xs = left ++ supers filterNot seen - loop(xs - next, seen + next) - } - } - } - loop(Set(sub), Set()) - } - - private def subargs(args1: List[OptManifest[_]], args2: List[OptManifest[_]]) = (args1 corresponds args2) { - // !!! [Martin] this is wrong, need to take variance into account - case (x: ClassManifest[_], y: ClassManifest[_]) => x <:< y - case (x, y) => (x eq NoManifest) && (y eq NoManifest) - } - - /** Tests whether the type represented by this manifest is a subtype - * of the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - def <:<(that: ClassManifest[_]): Boolean = { - // All types which could conform to these types will override <:<. - def cannotMatch = { - import Manifest._ - that.isInstanceOf[AnyValManifest[_]] || (that eq AnyVal) || (that eq Nothing) || (that eq Null) - } - - // This is wrong, and I don't know how it can be made right - // without more development of Manifests, due to arity-defying - // relationships like: - // - // List[String] <: AnyRef - // Map[Int, Int] <: Iterable[(Int, Int)] - // - // Given the manifest for Map[A, B] how do I determine that a - // supertype has single type argument (A, B) ? I don't see how we - // can say whether X <:< Y when type arguments are involved except - // when the erasure is the same, even before considering variance. - !cannotMatch && { - // this part is wrong for not considering variance - if (this.erasure == that.erasure) - subargs(this.typeArguments, that.typeArguments) - // this part is wrong for punting unless the rhs has no type - // arguments, but it's better than a blindfolded pinata swing. - else - that.typeArguments.isEmpty && subtype(this.erasure, that.erasure) - } - } - - /** Tests whether the type represented by this manifest is a supertype - * of the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - def >:>(that: ClassManifest[_]): Boolean = - that <:< this - - def canEqual(other: Any) = other match { - case _: ClassManifest[_] => true - case _ => false - } - - /** Tests whether the type represented by this manifest is equal to - * the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - override def equals(that: Any): Boolean = that match { - case m: ClassManifest[_] => (m canEqual this) && (this.erasure == m.erasure) - case _ => false - } - override def hashCode = this.erasure.## - - protected def arrayClass[T](tp: jClass[_]): jClass[Array[T]] = - java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[jClass[Array[T]]] - - def arrayManifest: ClassManifest[Array[T]] = - ClassManifest.classType[Array[T]](arrayClass[T](erasure), this) - - def newArray(len: Int): Array[T] = - java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] - - def newArray2(len: Int): Array[Array[T]] = - java.lang.reflect.Array.newInstance(arrayClass[T](erasure), len) - .asInstanceOf[Array[Array[T]]] - - def newArray3(len: Int): Array[Array[Array[T]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[T]](arrayClass[T](erasure)), len) - .asInstanceOf[Array[Array[Array[T]]]] - - def newArray4(len: Int): Array[Array[Array[Array[T]]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure))), len) - .asInstanceOf[Array[Array[Array[Array[T]]]]] - - def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[Array[Array[T]]]](arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure)))), len) - .asInstanceOf[Array[Array[Array[Array[Array[T]]]]]] - - def newWrappedArray(len: Int): WrappedArray[T] = - // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new WrappedArray.ofRef[T with AnyRef](newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] - - def newArrayBuilder(): ArrayBuilder[T] = - // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new ArrayBuilder.ofRef[T with AnyRef]()(this.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] - - def typeArguments: List[OptManifest[_]] = List() - - protected def argString = - if (typeArguments.nonEmpty) typeArguments.mkString("[", ", ", "]") - else if (erasure.isArray) "["+ClassManifest.fromClass(erasure.getComponentType)+"]" - else "" -} - -/** The object `ClassManifest` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used in client code. - */ -object ClassManifest { - val Byte = Manifest.Byte - val Short = Manifest.Short - val Char = Manifest.Char - val Int = Manifest.Int - val Long = Manifest.Long - val Float = Manifest.Float - val Double = Manifest.Double - val Boolean = Manifest.Boolean - val Unit = Manifest.Unit - val Any = Manifest.Any - val Object = Manifest.Object - val AnyVal = Manifest.AnyVal - val Nothing = Manifest.Nothing - val Null = Manifest.Null - - def fromClass[T](clazz: jClass[T]): ClassManifest[T] = clazz match { - case java.lang.Byte.TYPE => Byte.asInstanceOf[ClassManifest[T]] - case java.lang.Short.TYPE => Short.asInstanceOf[ClassManifest[T]] - case java.lang.Character.TYPE => Char.asInstanceOf[ClassManifest[T]] - case java.lang.Integer.TYPE => Int.asInstanceOf[ClassManifest[T]] - case java.lang.Long.TYPE => Long.asInstanceOf[ClassManifest[T]] - case java.lang.Float.TYPE => Float.asInstanceOf[ClassManifest[T]] - case java.lang.Double.TYPE => Double.asInstanceOf[ClassManifest[T]] - case java.lang.Boolean.TYPE => Boolean.asInstanceOf[ClassManifest[T]] - case java.lang.Void.TYPE => Unit.asInstanceOf[ClassManifest[T]] - case _ => classType[T with AnyRef](clazz).asInstanceOf[ClassManifest[T]] - } - - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest.singleType(value) - - /** ClassManifest for the class type `clazz`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: jClass[_]): ClassManifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** ClassManifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class and `args` are its type arguments */ - def classType[T](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** ClassManifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { - case NoManifest => Object.asInstanceOf[ClassManifest[Array[T]]] - case m: ClassManifest[_] => m.asInstanceOf[ClassManifest[T]].arrayManifest - } - - /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassManifest[T] { - def erasure = clazz - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. - * todo: remove after next boostrap - */ - def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassManifest[T] { - def erasure = upperbound.erasure - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } -} - -/** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class: todo: we should try to merge this with Manifest's class */ -private class ClassTypeManifest[T]( - prefix: Option[OptManifest[_]], - val erasure: jClass[_], - override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] -{ - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString -} diff --git a/src/library/scala/reflect/ClassTags.scala b/src/library/scala/reflect/ClassTags.scala new file mode 100644 index 0000000000..2833e7cc8e --- /dev/null +++ b/src/library/scala/reflect/ClassTags.scala @@ -0,0 +1,158 @@ +package scala.reflect + +import java.lang.{ Class => jClass } +import scala.reflect.{ mirror => rm } + +/** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. + * This is useful in itself, but also enables very important use case. + * Having this knowledge ClassTag can instantiate `Arrays` + * in those cases where the element type is unknown at compile time. + * Hence, ClassTag[T] conforms to the ArrayTag[T] trait. + */ +// please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` +// class tags, and all tags in general, should be as minimalistic as possible +@annotation.implicitNotFound(msg = "No ClassTag available for ${T}") +abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { + // quick and dirty fix to a deadlock in Predef: + // http://groups.google.com/group/scala-internals/browse_thread/thread/977de028a4e75d6f + // todo. fix that in a sane way + // assert(erasure != null) + + /** A Scala reflection type representing T. + * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure). + * For TypeTags and GroundTypeTags the representation is almost precise, because it uses reification + * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */ + def tpe: rm.Type = rm.classToType(erasure) + + /** A Scala reflection symbol representing T. */ + def symbol: rm.Symbol = rm.classToSymbol(erasure) + + /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */ + def wrap: ClassTag[Array[T]] = { + val arrayClazz = java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]] + ClassTag[Array[T]](arrayClazz) + } + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] = + erasure match { + case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] + case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] + case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] + case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] + case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] + case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] + case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] + case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] + case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] + case _ => java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] + } +} + +object ClassTag { + private val ObjectTYPE = classOf[java.lang.Object] + private val StringTYPE = classOf[java.lang.String] + + val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte](java.lang.Byte.TYPE) { private def readResolve() = ClassTag.Byte } + val Short : ClassTag[scala.Short] = new ClassTag[scala.Short](java.lang.Short.TYPE) { private def readResolve() = ClassTag.Short } + val Char : ClassTag[scala.Char] = new ClassTag[scala.Char](java.lang.Character.TYPE) { private def readResolve() = ClassTag.Char } + val Int : ClassTag[scala.Int] = new ClassTag[scala.Int](java.lang.Integer.TYPE) { private def readResolve() = ClassTag.Int } + val Long : ClassTag[scala.Long] = new ClassTag[scala.Long](java.lang.Long.TYPE) { private def readResolve() = ClassTag.Long } + val Float : ClassTag[scala.Float] = new ClassTag[scala.Float](java.lang.Float.TYPE) { private def readResolve() = ClassTag.Float } + val Double : ClassTag[scala.Double] = new ClassTag[scala.Double](java.lang.Double.TYPE) { private def readResolve() = ClassTag.Double } + val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean](java.lang.Boolean.TYPE) { private def readResolve() = ClassTag.Boolean } + val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit](java.lang.Void.TYPE) { private def readResolve() = ClassTag.Unit } + val Any : ClassTag[scala.Any] = new ClassTag[scala.Any](ObjectTYPE) { private def readResolve() = ClassTag.Any } + val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object](ObjectTYPE) { private def readResolve() = ClassTag.Object } + val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal](ObjectTYPE) { private def readResolve() = ClassTag.AnyVal } + val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef](ObjectTYPE) { private def readResolve() = ClassTag.AnyRef } + val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing](ObjectTYPE) { private def readResolve() = ClassTag.Nothing } + val Null : ClassTag[scala.Null] = new ClassTag[scala.Null](ObjectTYPE) { private def readResolve() = ClassTag.Null } + val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String](StringTYPE) { private def readResolve() = ClassTag.String } + + def apply[T](clazz: jClass[_]): ClassTag[T] = + clazz match { + case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] + case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] + case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] + case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] + case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] + case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] + case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]] + case StringTYPE => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => new ClassTag[T](clazz) {} + } + + def apply[T](tpe: rm.Type): ClassTag[T] = + tpe match { + case rm.ByteTpe => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case rm.ShortTpe => ClassTag.Short.asInstanceOf[ClassTag[T]] + case rm.CharTpe => ClassTag.Char.asInstanceOf[ClassTag[T]] + case rm.IntTpe => ClassTag.Int.asInstanceOf[ClassTag[T]] + case rm.LongTpe => ClassTag.Long.asInstanceOf[ClassTag[T]] + case rm.FloatTpe => ClassTag.Float.asInstanceOf[ClassTag[T]] + case rm.DoubleTpe => ClassTag.Double.asInstanceOf[ClassTag[T]] + case rm.BooleanTpe => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case rm.UnitTpe => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case rm.AnyTpe => ClassTag.Any.asInstanceOf[ClassTag[T]] + case rm.ObjectTpe => ClassTag.Object.asInstanceOf[ClassTag[T]] + case rm.AnyValTpe => ClassTag.AnyVal.asInstanceOf[ClassTag[T]] + case rm.AnyRefTpe => ClassTag.AnyRef.asInstanceOf[ClassTag[T]] + case rm.NothingTpe => ClassTag.Nothing.asInstanceOf[ClassTag[T]] + case rm.NullTpe => ClassTag.Null.asInstanceOf[ClassTag[T]] + case rm.StringTpe => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => apply[T](rm.typeToClass(tpe.erasure)) + } + + implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) +} + +// this class should not be used directly in client code +class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { + import scala.collection.mutable.{ WrappedArray, ArrayBuilder } + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: ClassManifest[_]): Boolean = that <:< ctag + + @deprecated("Use `wrap` instead", "2.10.0") + def arrayManifest: ClassManifest[Array[T]] = ctag.wrap + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len) + + @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0") + def newWrappedArray(len: Int): WrappedArray[T] = + ctag.erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]] + case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] + } + + @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") + def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) + + @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.GroundTypeTag` to capture and analyze type arguments", "2.10.0") + def typeArguments: List[OptManifest[_]] = List() +} \ No newline at end of file diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala deleted file mode 100644 index e5df487be9..0000000000 --- a/src/library/scala/reflect/Manifest.scala +++ /dev/null @@ -1,302 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -import scala.collection.mutable.{ ArrayBuilder, WrappedArray } -import mirror._ - -/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use - * is to give access to the erasure of the type as a `Class` instance, as - * is necessary for the creation of native `Arrays` if the class is not - * known at compile time. - * - * The type-relation operators `<:<` and `=:=` should be considered - * approximations only, as there are numerous aspects of type conformance - * which are not yet adequately represented in manifests. - * - * Example usages: -{{{ - def arr[T] = new Array[T](0) // does not compile - def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles - def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding - - // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. - def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] - isApproxSubType[List[String], List[AnyRef]] // true - isApproxSubType[List[String], List[Int]] // false - - def methods[T: ClassManifest] = classManifest[T].erasure.getMethods - def retType[T: ClassManifest](name: String) = - methods[T] find (_.getName == name) map (_.getGenericReturnType) - - retType[Map[_, _]]("values") // Some(scala.collection.Iterable) -}}} - * - */ -@annotation.implicitNotFound(msg = "No Manifest available for ${T}.") -trait Manifest[T] extends ClassManifest[T] with Equals { - override def typeArguments: List[Manifest[_]] = Nil - - override def arrayManifest: Manifest[Array[T]] = - Manifest.classType[Array[T]](arrayClass[T](erasure), this) - - override def canEqual(that: Any): Boolean = that match { - case _: Manifest[_] => true - case _ => false - } - /** Note: testing for erasure here is important, as it is many times - * faster than <:< and rules out most comparisons. - */ - override def equals(that: Any): Boolean = that match { - case m: Manifest[_] => (m canEqual this) && (this.erasure == m.erasure) && (this <:< m) && (m <:< this) - case _ => false - } - override def hashCode = this.erasure.## -} - -abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { - override def <:<(that: ClassManifest[_]): Boolean = - (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) - override def canEqual(other: Any) = other match { - case _: AnyValManifest[_] => true - case _ => false - } - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override val hashCode = System.identityHashCode(this) -} - -/** The object `Manifest` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used - * in client code. - */ -object Manifest { - import mirror.{ definitions => mdefs } - - def valueManifests: List[AnyValManifest[_]] = - List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) - - val Byte: AnyValManifest[Byte] = new AnyValManifest[scala.Byte]("Byte") { - def erasure = java.lang.Byte.TYPE - override def newArray(len: Int): Array[Byte] = new Array[Byte](len) - override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) - override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() - private def readResolve(): Any = Manifest.Byte - } - - val Short: AnyValManifest[Short] = new AnyValManifest[scala.Short]("Short") { - def erasure = java.lang.Short.TYPE - override def newArray(len: Int): Array[Short] = new Array[Short](len) - override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) - override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() - private def readResolve(): Any = Manifest.Short - } - - val Char: AnyValManifest[Char] = new AnyValManifest[scala.Char]("Char") { - def erasure = java.lang.Character.TYPE - override def newArray(len: Int): Array[Char] = new Array[Char](len) - override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) - override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() - private def readResolve(): Any = Manifest.Char - } - - val Int: AnyValManifest[Int] = new AnyValManifest[scala.Int]("Int") { - def erasure = java.lang.Integer.TYPE - override def newArray(len: Int): Array[Int] = new Array[Int](len) - override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) - override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() - private def readResolve(): Any = Manifest.Int - } - - val Long: AnyValManifest[Long] = new AnyValManifest[scala.Long]("Long") { - def erasure = java.lang.Long.TYPE - override def newArray(len: Int): Array[Long] = new Array[Long](len) - override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) - override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() - private def readResolve(): Any = Manifest.Long - } - - val Float: AnyValManifest[Float] = new AnyValManifest[scala.Float]("Float") { - def erasure = java.lang.Float.TYPE - override def newArray(len: Int): Array[Float] = new Array[Float](len) - override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) - override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() - private def readResolve(): Any = Manifest.Float - } - - val Double: AnyValManifest[Double] = new AnyValManifest[scala.Double]("Double") { - def erasure = java.lang.Double.TYPE - override def newArray(len: Int): Array[Double] = new Array[Double](len) - override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) - override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() - private def readResolve(): Any = Manifest.Double - } - - val Boolean: AnyValManifest[Boolean] = new AnyValManifest[scala.Boolean]("Boolean") { - def erasure = java.lang.Boolean.TYPE - override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) - override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) - override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() - private def readResolve(): Any = Manifest.Boolean - } - - val Unit: AnyValManifest[Unit] = new AnyValManifest[scala.Unit]("Unit") { - def erasure = java.lang.Void.TYPE - override def newArray(len: Int): Array[Unit] = new Array[Unit](len) - override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) - override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() - private def readResolve(): Any = Manifest.Unit - } - - val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any]("Any") { - override def symbol = mdefs.AnyClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) - private def readResolve(): Any = Manifest.Any - } - - val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object]("Object") { - override def symbol = mdefs.ObjectClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.Object - } - - val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal]("AnyVal") { - override def symbol = mdefs.AnyValClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.AnyVal - } - - val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null]("Null") { - override def symbol = mdefs.NullClass - override def <:<(that: ClassManifest[_]): Boolean = - (that ne null) && (that ne Nothing) && !(that <:< AnyVal) - private def readResolve(): Any = Manifest.Null - } - - val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing]("Nothing") { - override def symbol = mdefs.NothingClass - override def <:<(that: ClassManifest[_]): Boolean = (that ne null) - private def readResolve(): Any = Manifest.Nothing - } - - private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { - lazy val erasure = value.getClass - override lazy val symbol = InstanceRefSymbol(value) // todo: change to freevar - override lazy val tpe = mirror.SingleType(mirror.NoPrefix, symbol) - override lazy val toString = value.toString + ".type" - } - - /** Manifest for the singleton type `value.type`. */ - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = - new SingletonTypeManifest[T](value) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: Predef.Class[_]): Manifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** Manifest for the class type `clazz`, where `clazz` is - * a top-level or static class and args are its type arguments. */ - def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - /** Phantom types have no runtime representation; they all erase to Object, - * but the Symbol preserves their identity. - */ - private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) { - override lazy val tpe = namedType(mirror.NoPrefix, symbol, Nil) - override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] - override val hashCode = System.identityHashCode(this) - } - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. */ - private class ClassTypeManifest[T](prefix: Option[Manifest[_]], - val erasure: Predef.Class[_], - override val typeArguments: List[Manifest[_]]) extends Manifest[T] { - - override lazy val tpe = { - val pre = prefix match { - case Some(pm) => pm.tpe - case None => symbol.owner.thisPrefix - } - namedType(pre, symbol, typeArguments map (_.tpe)) - } - - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString - } - - def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = - arg.asInstanceOf[Manifest[T]].arrayManifest - - /** Manifest for the abstract type `prefix # name'. `upperBound` is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def erasure = upperBound - override lazy val tpe = namedType(prefix.tpe, prefix.tpe.member(newTypeName(name)), args map (_.tpe) toList) - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** Manifest for the unknown type `_ >: L <: U` in an existential. - */ - def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = - new Manifest[T] { - def erasure = upperBound.erasure - override lazy val tpe = mirror.TypeBounds(lowerBound.tpe, upperBound.tpe) - override def toString = - "_" + - (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + - (if (upperBound eq Nothing) "" else " <: "+upperBound) - } - - /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ - def intersectionType[T](parents: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def erasure = parents.head.erasure - override lazy val tpe = mirror.RefinedType((parents map (_.tpe)).toList, newScope) - override def toString = parents.mkString(" with ") - } - - /** A generic manifest factory from a reflect.Type. Except where - * mandated by performance considerations, we should replace most - * other manifest factories by this one. There's just one thing - * that needs to be done first: A Manifest's type can refer - * to type variables that are controlled by manifests. In that - * case the reified type needs to contain the type passed in the manifest - * instead of the reference to the manifest. Note that splicing manifests - * into manfifests is completely analogous to splicing code blocks into - * code blocks. Manifest[T] and Code[T] are really the same thing, only one - * works for types, the other for trees. - * Another complication is that once we generate manifests from types, we really - * should have reflection as a standard component shipped with the standard library, - * instead of in scala-compiler.jar. - */ - def apply[T](_tpe: mirror.Type): Manifest[T] = new Manifest[T] { - override def symbol = _tpe.typeSymbol - override lazy val tpe = _tpe - override def erasure = mirror.typeToClass(_tpe.erasedType) - override def toString = _tpe.toString - } -} diff --git a/src/library/scala/reflect/NoManifest.scala b/src/library/scala/reflect/NoManifest.scala deleted file mode 100644 index 191e46ae39..0000000000 --- a/src/library/scala/reflect/NoManifest.scala +++ /dev/null @@ -1,15 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -/** One of the branches of an [[scala.reflect.OptManifest]]. - */ -object NoManifest extends OptManifest[Nothing] with Serializable { - override def toString = "" -} diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/reflect/OptManifest.scala deleted file mode 100644 index 2a955deb2c..0000000000 --- a/src/library/scala/reflect/OptManifest.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]]. - * - * It is either a `Manifest` or the value `NoManifest`. - * - * @author Martin Odersky - */ -trait OptManifest[+T] extends Serializable diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala index 510f0819c6..1be46eac55 100644 --- a/src/library/scala/reflect/ReflectionUtils.scala +++ b/src/library/scala/reflect/ReflectionUtils.scala @@ -27,7 +27,17 @@ object ReflectionUtils { case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex)) } - def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): AnyRef = { + def defaultReflectionClassLoader() = { + // say no to non-determinism of mirror classloaders + // default classloader will be instantiated using current system classloader + // if you wish so, you can rebind it by setting ``mirror.classLoader'' to whatever is necessary +// val cl = Thread.currentThread.getContextClassLoader +// if (cl == null) getClass.getClassLoader else cl +// cl + getClass.getClassLoader + } + + def singletonInstance(cl: ClassLoader, className: String): AnyRef = { val name = if (className endsWith "$") className else className + "$" val clazz = java.lang.Class.forName(name, true, cl) val singleton = clazz getField "MODULE$" get null @@ -35,7 +45,17 @@ object ReflectionUtils { } // Retrieves the MODULE$ field for the given class name. - def singletonInstanceOpt(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] = - try Some(singletonInstance(className, cl)) + def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] = + try Some(singletonInstance(cl, className)) + catch { case _: ClassNotFoundException => None } + + def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = { + val singleton = singletonInstance(cl, className) + val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader]) + method.invoke(singleton, args: _*) + } + + def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] = + try Some(invokeFactory(cl, className, methodName, args: _*)) catch { case _: ClassNotFoundException => None } } diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala new file mode 100644 index 0000000000..991feb3bac --- /dev/null +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -0,0 +1,154 @@ +package scala.reflect + +import api.Universe +import makro.Context + +// todo. unfortunately, current type inferencer doesn't infer type parameters of implicit values +// this means that during macro expansion these macros will get Nothing instead of real T +// Oh how much I'd love to implement this now, but I have to postpone this until we have a solution for type inference + +/** This object is required by the compiler and should not be used in client code. */ +object TagMaterialization { + def materializeClassTag[T: c.TypeTag](c: Context): c.Expr[ClassTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeClassTag(tpe) + } + + def materializeTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.TypeTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeTypeTag(tpe, requireGroundTypeTag = false) + } + + def materializeGroundTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.GroundTypeTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeTypeTag(tpe, requireGroundTypeTag = true) + } + + private implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils + + private abstract class Utils { + val c: Context + + import c.mirror._ + import definitions._ + + val coreTags = Map( + ByteClass.asType -> newTermName("Byte"), + ShortClass.asType -> newTermName("Short"), + CharClass.asType -> newTermName("Char"), + IntClass.asType -> newTermName("Int"), + LongClass.asType -> newTermName("Long"), + FloatClass.asType -> newTermName("Float"), + DoubleClass.asType -> newTermName("Double"), + BooleanClass.asType -> newTermName("Boolean"), + UnitClass.asType -> newTermName("Unit"), + AnyClass.asType -> newTermName("Any"), + ObjectClass.asType -> newTermName("Object"), + AnyValClass.asType -> newTermName("AnyVal"), + AnyRefClass.asType -> newTermName("AnyRef"), + NothingClass.asType -> newTermName("Nothing"), + NullClass.asType -> newTermName("Null")) + + val ReflectPackage = staticModule("scala.reflect.package") + val Reflect_mirror = selectTerm(ReflectPackage, "mirror") + val ClassTagClass = staticClass("scala.reflect.ClassTag") + val ClassTagErasure = selectTerm(ClassTagClass, "erasure") + val ClassTagModule = staticModule("scala.reflect.ClassTag") + val TypeTagsClass = staticClass("scala.reflect.api.TypeTags") + val TypeTagClass = selectType(TypeTagsClass, "TypeTag") + val TypeTagTpe = selectTerm(TypeTagClass, "tpe") + val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag") + val GroundTypeTagClass = selectType(TypeTagsClass, "GroundTypeTag") + val GroundTypeTagModule = selectTerm(TypeTagsClass, "GroundTypeTag") + + def materializeClassTag(tpe: Type): Tree = { + val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) + materializeClassTag(prefix, tpe) + } + + def materializeClassTag(prefix: Tree, tpe: Type): Tree = { + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) + case _ => + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Ident(ClassTagModule), coreTags(coreTpe)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) + val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) + Select(componentTag, newTermName("wrap")) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") + val erasure = + if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? + else tpe.erasure.normalize // necessary to deal with erasures of HK types + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + } + + def materializeTypeTag(tpe: Type, requireGroundTypeTag: Boolean): Tree = { + def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix + materializeTypeTag(prefix, tpe, requireGroundTypeTag) + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { + val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + case _ => + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case c.ReificationError(pos, msg) => + c.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case c.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + + private def fail(reason: Any): Nothing = { + val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication + val tpe = tpeTree.tpe + val PolyType(_, MethodType(_, tagTpe)) = fun.tpe + val tagModule = tagTpe.typeSymbol.companionSymbol + if (c.compilerSettings.contains("-Xlog-implicits")) + c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) + c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) + } + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Attachments.scala b/src/library/scala/reflect/api/Attachments.scala new file mode 100644 index 0000000000..dfd362ebe0 --- /dev/null +++ b/src/library/scala/reflect/api/Attachments.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +/** Attachment is a generalisation of Position. + * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. + * + * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree + * imposing an unnecessary memory tax because of something that will not be used in most cases. + */ +trait Attachment { + /** Gets the underlying position */ + def pos: Position + + /** Creates a copy of this attachment with its position updated */ + def withPos(pos: Position): Attachment +} diff --git a/src/library/scala/reflect/api/ClassLoaders.scala b/src/library/scala/reflect/api/ClassLoaders.scala new file mode 100644 index 0000000000..7be402d3df --- /dev/null +++ b/src/library/scala/reflect/api/ClassLoaders.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +trait ClassLoaders { self: Universe => + + /** The symbol corresponding to the globally accessible class with the + * given fully qualified name `fullName`. + */ + def staticClass(fullName: String): Symbol + + /** The symbol corresponding to the globally accessible object with the + * given fully qualified name `fullName`. + */ + def staticModule(fullName: String): Symbol + +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala new file mode 100644 index 0000000000..8c3f12783b --- /dev/null +++ b/src/library/scala/reflect/api/Exprs.scala @@ -0,0 +1,48 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api + +trait Exprs { self: Universe => + + /** An expression tree tagged with its type */ + case class Expr[+T: TypeTag](tree: Tree) { + def tpe: Type = implicitly[TypeTag[T]].tpe + def eval: T = mkToolBox().runExpr(tree).asInstanceOf[T] + lazy val value: T = eval + override def toString = "Expr["+tpe+"]("+tree+")" + } + + // [Eugene] had to move this to the companion of Tree to make stuff compile. weirdo! +// object Expr { +// // would be great if in future this generated an Expr[Magic] +// // where Magic is a magic untyped type that propagates through the entire quasiquote +// // and turns off typechecking whenever it's involved +// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked +// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo +// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree) +// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree +// +// // [Eugene] good idea? +// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr +// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +// } + + // [Eugene] even weirder - implicits didn't feel at home in Trees :( + + // would be great if in future this generated an Expr[Magic] + // where Magic is a magic untyped type that propagates through the entire quasiquote + // and turns off typechecking whenever it's involved + // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked + // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo + implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)(TypeTag.Nothing) + implicit def expr2tree(expr: Expr[_]): Tree = expr.tree + + // [Eugene] good idea? + implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr + implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +} + diff --git a/src/library/scala/reflect/api/FreeVars.scala b/src/library/scala/reflect/api/FreeVars.scala new file mode 100644 index 0000000000..0bef099a55 --- /dev/null +++ b/src/library/scala/reflect/api/FreeVars.scala @@ -0,0 +1,42 @@ +package scala.reflect +package api + +trait FreeVars { + self: Universe => + + /** Represents a free term captured by reification. + */ + type FreeTerm <: Symbol + + val FreeTerm: FreeTermExtractor + + abstract class FreeTermExtractor { + def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] + } + + /** Extracts free terms from a tree that is reified or contains reified subtrees. + */ + def freeTerms(tree: Tree): List[FreeTerm] + + /** Represents a free type captured by reification. + */ + type FreeType <: Symbol + + val FreeType: FreeTypeExtractor + + abstract class FreeTypeExtractor { + def unapply(freeType: FreeType): Option[(TypeName, Type, String)] + } + + /** Extracts free types from a tree that is reified or contains reified subtrees. + */ + def freeTypes(tree: Tree): List[FreeType] + + /** Substitutes free types in a reified tree. + */ + def substituteFreeTypes(tree: Tree, subs: Map[FreeType, Type]): Tree + + /** Substitutes free types in a reified type. + */ + def substituteFreeTypes(tpe: Type, subs: Map[FreeType, Type]): Type +} diff --git a/src/library/scala/reflect/api/Importers.scala b/src/library/scala/reflect/api/Importers.scala new file mode 100644 index 0000000000..1d8890b7db --- /dev/null +++ b/src/library/scala/reflect/api/Importers.scala @@ -0,0 +1,19 @@ +package scala.reflect +package api + +trait Importers { self: Universe => + + def mkImporter(from0: Universe): Importer { val from: from0.type } + + trait Importer { + val from: Universe + + val reverse: from.Importer { val from: self.type } + + def importSymbol(sym: from.Symbol): Symbol + + def importType(tpe: from.Type): Type + + def importTree(tree: from.Tree): Tree + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala index cea9e1a37d..ed8ead7aaf 100644 --- a/src/library/scala/reflect/api/Mirror.scala +++ b/src/library/scala/reflect/api/Mirror.scala @@ -5,7 +5,22 @@ package api * runtime entities such as class names and object instances * with a reflexive universe. */ -trait Mirror extends Universe with RuntimeTypes with TreeBuildUtil { +trait Mirror extends Universe { + + /** Class loader that is a mastermind behind the reflexive mirror. + * + * By default it is set to system classloader (more precisely, to the classloader that loads the `scala.reflect.package` class). + * However, sometimes it is useful to have a mirror services by a custom classloader. + * + * There are two ways to customize the `classLoader`: + * 1) Create a new mirror using the `scala.reflect.mkMirror(classLoader: ClassLoader)` method + * 2) Set `classLoader` to the new value + * + * The first, immutable, way should be strongly preferred in most situation. + * However sometimes it is necessary to migrate the default reflexive mirror (`scala.reflect.mirror`) to a new classloader. + * In that and only that case, use the setter, but be very careful not to introduce inconsistencies. + */ + var classLoader: ClassLoader /** The Scala class symbol that has given fully qualified name * @param name The fully qualified name of the class to be returned diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala index 91f1081b4d..8f01e0ced1 100644 --- a/src/library/scala/reflect/api/Positions.scala +++ b/src/library/scala/reflect/api/Positions.scala @@ -1,21 +1,202 @@ package scala.reflect package api -trait Positions { self: Universe => - /** TreeAnnotation is a generalisation of Position. - * - * TreeAnnotation cannot be an upperbound of Position since the corresponding classes - * must live outside of the universe for backwards compatibility (see scala.tools.nsc.util.Position). - * Thus, represent subtyping as coercions. - * - * Typically, positionToAnnotation is the identity, and annotationToPosition returns annot.pos - */ - type TreeAnnotation // <: { def pos: Position } - def NoTreeAnnotation: TreeAnnotation - implicit def positionToAnnotation(pos: Position): TreeAnnotation // = pos - def annotationToPosition(annot: TreeAnnotation): Position // = annot.pos - def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = () // check that annot may overwrite tree.annot - - type Position // <: TreeAnnotation, but not practical to enforce this (would require moving Position, SourceFile, Reporter,... into the universe) +trait Positions { + self: Universe => + + // [Eugene] in quite a lot of situations (mostly related to error reporting) we need positions in the API + // however it seems that neither runtime compilation, nor macros need facilities to create positions from scratch + // both emit ASTs, which can be automatically transformed into synthetic sources and assigned with synthetic positions + // hence I added possibilities to inspect everything we can, but add any position factories + // this simplified a lot of things, the biggest of them is that we don't need to expose SourceFile/AbstractFile + type Position <: scala.reflect.api.Position val NoPosition: Position -} \ No newline at end of file + + /** A position that wraps a set of trees. + * The point of the wrapping position is the point of the default position. + * If some of the trees are ranges, returns a range position enclosing all ranges + * Otherwise returns default position. + */ + def wrappingPos(default: Position, trees: List[Tree]): Position + + /** A position that wraps the non-empty set of trees. + * The point of the wrapping position is the point of the first trees' position. + * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees + * Otherwise returns a synthetic offset position to point. + */ + def wrappingPos(trees: List[Tree]): Position + + /** Ensure that given tree has no positions that overlap with + * any of the positions of `others`. This is done by + * shortening the range or assigning TransparentPositions + * to some of the nodes in `tree`. + */ + def ensureNonOverlapping(tree: Tree, others: List[Tree]) + + /** Assigns a given position to all position-less nodes of a given AST. + */ + def atPos[T <: Tree](pos: Position)(tree: T): T +} + +/** The Position class and its subclasses represent positions of ASTs and symbols. + * Except for NoPosition and FakePos, every position refers to a SourceFile + * and to an offset in the sourcefile (its `point`). For batch compilation, + * that's all. For interactive IDE's there are also RangePositions + * and TransparentPositions. A RangePosition indicates a start and an end + * in addition to its point. TransparentPositions are a subclass of RangePositions. + * Range positions that are not transparent are called opaque. + * Trees with RangePositions need to satisfy the following invariants. + * + * INV1: A tree with an offset position never contains a child + * with a range position + * INV2: If the child of a tree with a range position also has a range position, + * then the child's range is contained in the parent's range. + * INV3: Opaque range positions of children of the same node are non-overlapping + * (this means their overlap is at most a single point). + * + * The following tests are useful on positions: + * + * pos.isDefined true if position is not a NoPosition nor a FakePosition + * pos.isRange true if position is a range + * pos.isOpaqueRange true if position is an opaque range + * + * The following accessor methods are provided: + * + * pos.source The source file of the position, which must be defined + * pos.point The offset of the position's point, which must be defined + * pos.start The start of the position, which must be a range + * pos.end The end of the position, which must be a range + * + * There are also convenience methods, such as + * + * pos.startOrPoint + * pos.endOrPoint + * pos.pointOrElse(default) + * + * These are less strict about the kind of position on which they can be applied. + * + * The following conversion methods are often used: + * + * pos.focus converts a range position to an offset position, keeping its point; + * returns all other positions unchanged. + * pos.makeTransparent converts an opaque range position into a transparent one. + * returns all other positions unchanged. + */ +trait Position extends Attachment { + + /** Java file corresponding to the source file of this position. + */ + def fileInfo: java.io.File + + /** Content of the source file that contains this position. + */ + def fileContent: Array[Char] + + /** Is this position neither a NoPosition nor a FakePosition? + * If isDefined is true, offset and source are both defined. + */ + def isDefined: Boolean + + /** Is this position a transparent position? */ + def isTransparent: Boolean + + /** Is this position a range position? */ + def isRange: Boolean + + /** Is this position a non-transparent range position? */ + def isOpaqueRange: Boolean + + /** if opaque range, make this position transparent */ + def makeTransparent: Position + + /** The start of the position's range, error if not a range position */ + def start: Int + + /** The start of the position's range, or point if not a range position */ + def startOrPoint: Int + + /** The point (where the ^ is) of the position */ + def point: Int + + /** The point (where the ^ is) of the position, or else `default` if undefined */ + def pointOrElse(default: Int): Int + + /** The end of the position's range, error if not a range position */ + def end: Int + + /** The end of the position's range, or point if not a range position */ + def endOrPoint: Int + + /** The same position with a different start value (if a range) */ + def withStart(off: Int): Position + + /** The same position with a different end value (if a range) */ + def withEnd(off: Int): Position + + /** The same position with a different point value (if a range or offset) */ + def withPoint(off: Int): Position + + /** If this is a range, the union with the other range, with the point of this position. + * Otherwise, this position + */ + def union(pos: Position): Position + + /** If this is a range position, the offset position of its start. + * Otherwise the position itself + */ + def focusStart: Position + + /** If this is a range position, the offset position of its point. + * Otherwise the position itself + */ + def focus: Position + + /** If this is a range position, the offset position of its end. + * Otherwise the position itself + */ + def focusEnd: Position + + /** Does this position include the given position `pos`. + * This holds if `this` is a range position and its range [start..end] + * is the same or covers the range of the given position, which may or may not be a range position. + */ + def includes(pos: Position): Boolean + + /** Does this position properly include the given position `pos` ("properly" meaning their + * ranges are not the same)? + */ + def properlyIncludes(pos: Position): Boolean + + /** Does this position precede that position? + * This holds if both positions are defined and the end point of this position + * is not larger than the start point of the given position. + */ + def precedes(pos: Position): Boolean + + /** Does this position properly precede the given position `pos` ("properly" meaning their ranges + * do not share a common point). + */ + def properlyPrecedes(pos: Position): Boolean + + /** Does this position overlap with that position? + * This holds if both positions are ranges and there is an interval of + * non-zero length that is shared by both position ranges. + */ + def overlaps(pos: Position): Boolean + + /** Does this position cover the same range as that position? + * Holds only if both position are ranges + */ + def sameRange(pos: Position): Boolean + + def line: Int + + def column: Int + + /** Convert this to a position around `point` that spans a single source line */ + def toSingleLine: Position + + def lineContent: String + + def show: String +} diff --git a/src/library/scala/reflect/api/Reporters.scala b/src/library/scala/reflect/api/Reporters.scala new file mode 100644 index 0000000000..b7428e1599 --- /dev/null +++ b/src/library/scala/reflect/api/Reporters.scala @@ -0,0 +1,65 @@ +package scala.reflect +package api + +trait Reporters { self: Universe => + + trait Reporter { + object severity extends Enumeration + class Severity(val id: Int) extends severity.Value { + var count: Int = 0 + override def toString() = this match { + case INFO => "INFO" + case WARNING => "WARNING" + case ERROR => "ERROR" + case _ => "" + } + } + val INFO = new Severity(0) + val WARNING = new Severity(1) + val ERROR = new Severity(2) + + case class Info(val pos: Position, val msg: String, val severity: Severity) + val infos = new collection.mutable.LinkedHashSet[Info] + + /** Handles incoming info */ + def log(pos: Position, msg: String, severity: Severity) { + infos += new Info(pos, msg, severity) + severity.count += 1 + display(infos.last) + } + + /** Displays incoming info */ + def display(info: Info): Unit + + /** Services a request to drop into interactive mode */ + def interactive(): Unit + + /** Refreshes the UI */ + def flush(): Unit = {} + + /** Resets the reporter */ + def reset(): Unit = { + INFO.count = 0 + WARNING.count = 0 + ERROR.count = 0 + infos.clear() + } + } + + class SilentReporter extends Reporter { + def display(info: Info) {} + def interactive() {} + } + + /** Creates a UI-less reporter that simply accumulates all the messages + */ + def mkSilentReporter(): Reporter = new SilentReporter() + + /** Creates a reporter that prints messages to the console according to the settings. + * + * ``minSeverity'' determines minimum severity of the messages to be printed. + * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR. + */ + // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here! + def mkConsoleReporter(minSeverity: Int = 1): Reporter +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/RuntimeTypes.scala b/src/library/scala/reflect/api/RuntimeTypes.scala deleted file mode 100644 index f58b328868..0000000000 --- a/src/library/scala/reflect/api/RuntimeTypes.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scala.reflect -package api - -/** A mirror establishes connections of - * runtime entities such as class names and object instances - * with a refexive universe. - */ -private[reflect] trait RuntimeTypes extends Universe { - - type InstanceRefSymbol >: Null <: Symbol - - val InstanceRefSymbol: InstanceRefSymbolExtractor - - private[reflect] def namedType(pre: Type, sym: Symbol, args: List[Type]): Type - - abstract class InstanceRefSymbolExtractor { - def apply(value: AnyRef): InstanceRefSymbol - def unapply(tpe: InstanceRefSymbol): Option[AnyRef] - } -} diff --git a/src/library/scala/reflect/api/Scopes.scala b/src/library/scala/reflect/api/Scopes.scala index d4e4e24f29..4a5702eadc 100755 --- a/src/library/scala/reflect/api/Scopes.scala +++ b/src/library/scala/reflect/api/Scopes.scala @@ -5,7 +5,12 @@ trait Scopes { self: Universe => type Scope <: Iterable[Symbol] - def newScope(): Scope -} + /** Create a new scope */ + def newScope: Scope + /** Create a new scope nested in another one with which it shares its elements */ + def newNestedScope(outer: Scope): Scope + /** Create a new scope with given initial elements */ + def newScopeWith(elems: Symbol*): Scope +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index c3d989f971..b4fedbe055 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -8,6 +8,23 @@ package api trait StandardDefinitions { self: Universe => + val ByteTpe: Type + val ShortTpe: Type + val CharTpe: Type + val IntTpe: Type + val LongTpe: Type + val FloatTpe: Type + val DoubleTpe: Type + val BooleanTpe: Type + val UnitTpe: Type + val AnyTpe: Type + val ObjectTpe: Type + val AnyValTpe: Type + val AnyRefTpe: Type + val NothingTpe: Type + val NullTpe: Type + val StringTpe: Type + val definitions: AbsDefinitions abstract class AbsDefinitions { @@ -15,7 +32,11 @@ trait StandardDefinitions { self: Universe => def RootPackage: Symbol def RootClass: Symbol def EmptyPackage: Symbol + def EmptyPackageClass: Symbol def ScalaPackage: Symbol + def ScalaPackageClass: Symbol + def JavaLangPackage: Symbol + def JavaLangPackageClass: Symbol // top types def AnyClass : Symbol @@ -37,6 +58,7 @@ trait StandardDefinitions { self: Universe => def FloatClass : Symbol def DoubleClass : Symbol def BooleanClass: Symbol + def ScalaPrimitiveValueClasses: List[Symbol] // fundamental reference classes def SymbolClass : Symbol @@ -48,13 +70,57 @@ trait StandardDefinitions { self: Universe => def ProductClass : Array[Symbol] def FunctionClass : Array[Symbol] - // fundamental modules + // Option classes + def OptionClass: Symbol + def SomeClass: Symbol + def NoneModule: Symbol + def SomeModule: Symbol + + // collections classes + def ConsClass: Symbol + def IterableClass: Symbol + def IteratorClass: Symbol + def ListClass: Symbol + def SeqClass: Symbol + def StringBuilderClass: Symbol + def TraversableClass: Symbol + + // collections modules def PredefModule: Symbol + def ListModule: Symbol + def List_apply: Symbol + def NilModule: Symbol + def SeqModule: Symbol + def IteratorModule: Symbol + def Iterator_apply: Symbol + + // arrays and their members + def ArrayModule: Symbol + def ArrayModule_overloadedApply: Symbol + def ArrayClass: Symbol + def Array_apply: Symbol + def Array_update: Symbol + def Array_length: Symbol + def Array_clone: Symbol + + // special parameter types + def ByNameParamClass: Symbol + def JavaRepeatedParamClass: Symbol + def RepeatedParamClass: Symbol + + // type tags + def ClassTagClass: Symbol + def ClassTagModule: Symbol + def TypeTagClass: Symbol + def TypeTagModule: Symbol + def GroundTypeTagClass: Symbol + def GroundTypeTagModule: Symbol /** Given a type T, returns the type corresponding to the VM's * representation: ClassClass's type constructor applied to `arg`. */ def vmClassType(arg: Type): Type // !!! better name? + // [Eugene] we already have arg.erasure, right? /** The string representation used by the given type in the VM. */ diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala index 81517d2a6b..bfc165f613 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -8,14 +8,166 @@ package api trait StandardNames { self: Universe => + abstract class AbsNames { + type NameType <: Name + + val EMPTY: NameType + val ANON_FUN_NAME: NameType + val ANON_CLASS_NAME: NameType + val EMPTY_PACKAGE_NAME: NameType + val IMPORT: NameType + val MODULE_VAR_SUFFIX: NameType + val ROOT: NameType + val PACKAGE: NameType + val SPECIALIZED_SUFFIX: NameType + + val ERROR: NameType + val NO_NAME: NameType + val WILDCARD: NameType + + def flattenedName(segments: Name*): NameType + } + val nme: AbsTermNames - abstract class AbsTermNames { + abstract class AbsTermNames extends AbsNames { + val EXPAND_SEPARATOR_STRING: String + + val ANYNAME: TermName val CONSTRUCTOR: TermName + val FAKE_LOCAL_THIS: TermName + val INITIALIZER: TermName + val LAZY_LOCAL: TermName + val LOCAL_SUFFIX_STRING: String + val MIRROR_PREFIX: TermName + val MIRROR_SHORT: TermName + val MIRROR_FREE_PREFIX: TermName + val MIRROR_FREE_THIS_SUFFIX: TermName + val MIRROR_FREE_VALUE_SUFFIX: TermName + val MIXIN_CONSTRUCTOR: TermName + val MODULE_INSTANCE_FIELD: TermName + val OUTER: TermName + val OUTER_LOCAL: TermName + val OUTER_SYNTH: TermName + val SELECTOR_DUMMY: TermName + val SELF: TermName + val SPECIALIZED_INSTANCE: TermName + val STAR: TermName + val THIS: TermName + + val BITMAP_NORMAL: TermName + val BITMAP_TRANSIENT: TermName + val BITMAP_PRIVATE: TermName + val BITMAP_CHECKINIT: TermName + val BITMAP_CHECKINIT_TRANSIENT: TermName + + val INTERPRETER_IMPORT_WRAPPER: String + val INTERPRETER_LINE_PREFIX: String + val INTERPRETER_VAR_PREFIX: String + val INTERPRETER_WRAPPER_SUFFIX: String + + val ROOTPKG: TermName + + val ADD: TermName + val AND: TermName + val ASR: TermName + val DIV: TermName + val EQ: TermName + val EQL: TermName + val GE: TermName + val GT: TermName + val HASHHASH: TermName + val LE: TermName + val LSL: TermName + val LSR: TermName + val LT: TermName + val MINUS: TermName + val MOD: TermName + val MUL: TermName + val NE: TermName + val OR: TermName + val PLUS : TermName + val SUB: TermName + val XOR: TermName + val ZAND: TermName + val ZOR: TermName + + // [Eugene] this doesn't compile. why?! +// val UNARY_~: TermName +// val UNARY_+: TermName +// val UNARY_-: TermName +// val UNARY_!: TermName + val UNARY_TILDE: TermName + val UNARY_PLUS: TermName + val UNARY_MINUS: TermName + val UNARY_NOT: TermName + + // [Eugene] this doesn't compile. why?! +// val ???: TermName + val QQQ: TermName + + val MODULE_SUFFIX_NAME: TermName + val NAME_JOIN_NAME: TermName + val IMPL_CLASS_SUFFIX: String + val LOCALDUMMY_PREFIX: String + val PROTECTED_PREFIX: String + val PROTECTED_SET_PREFIX: String + val SINGLETON_SUFFIX: String + val SUPER_PREFIX_STRING: String + val TRAIT_SETTER_SEPARATOR_STRING: String + val SETTER_SUFFIX: TermName + + def isConstructorName(name: Name): Boolean + def isExceptionResultName(name: Name): Boolean + def isImplClassName(name: Name): Boolean + def isLocalDummyName(name: Name): Boolean + def isLocalName(name: Name): Boolean + def isLoopHeaderLabel(name: Name): Boolean + def isProtectedAccessorName(name: Name): Boolean + def isSuperAccessorName(name: Name): Boolean + def isReplWrapperName(name: Name): Boolean + def isSetterName(name: Name): Boolean + def isTraitSetterName(name: Name): Boolean + def isSingletonName(name: Name): Boolean + def isModuleName(name: Name): Boolean + def isOpAssignmentName(name: Name): Boolean + + def segments(name: String, assumeTerm: Boolean): List[Name] + def originalName(name: Name): Name + def stripModuleSuffix(name: Name): Name + def unspecializedName(name: Name): Name + def splitSpecializedName(name: Name): (Name, String, String) + def dropLocalSuffix(name: Name): Name + + def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName + def expandedSetterName(name: TermName, base: Symbol): TermName + def protName(name: Name): TermName + def protSetterName(name: Name): TermName + def getterName(name: TermName): TermName + def getterToLocal(name: TermName): TermName + def getterToSetter(name: TermName): TermName + def localToGetter(name: TermName): TermName + def setterToGetter(name: TermName): TermName + def defaultGetterName(name: Name, pos: Int): TermName + def defaultGetterToMethod(name: Name): TermName + + def dropSingletonName(name: Name): TypeName + def singletonName(name: Name): TypeName + def implClassName(name: Name): TypeName + def interfaceName(implname: Name): TypeName + def localDummyName(clazz: Symbol): TermName + def superName(name: Name): TermName } val tpnme: AbsTypeNames - abstract class AbsTypeNames { + abstract class AbsTypeNames extends AbsNames { + val REFINE_CLASS_NAME: TypeName + val BYNAME_PARAM_CLASS_NAME: TypeName + val EQUALS_PATTERN_NAME: TypeName + val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName + val LOCAL_CHILD: TypeName + val REPEATED_PARAM_CLASS_NAME: TypeName + val WILDCARD_STAR: TypeName } } diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index ab59a4a39a..a154e5f7a0 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -7,6 +7,10 @@ trait Symbols { self: Universe => abstract class AbsSymbol { this: Symbol => + /** The position of this symbol + */ + def pos: Position + /** The modifiers of this symbol */ def modifiers: Set[Modifier] @@ -47,6 +51,10 @@ trait Symbols { self: Universe => /** An id number which is unique for all symbols in this universe */ def id: Int + /** ... + */ + def orElse[T](alt: => Symbol): Symbol + /** * Set when symbol has a modifier of the form private[X], NoSymbol otherwise. * @@ -112,6 +120,20 @@ trait Symbols { self: Universe => */ def isTerm : Boolean + /** Does this symbol represent the definition of method? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isMethod : Boolean + + /** Is this symbol an overloaded method? + */ + def isOverloaded : Boolean + + /** Does this symbol represent a free term captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeTerm : Boolean + /** Does this symbol represent the definition of type? * Note that every symbol is either a term or a type. * So for every symbol `sym`, either `sym.isTerm` is true @@ -124,6 +146,17 @@ trait Symbols { self: Universe => */ def isClass : Boolean + /** Does this symbol represent the definition of a primitive class? + * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], + * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? + */ + def isPrimitiveValueClass: Boolean + + /** Does this symbol represent the definition of a custom value class? + * Namely, is AnyVal among its parent classes? + */ + def isDerivedValueClass: Boolean + /** Does this symbol represent the definition of a type alias? * If yes, `isType` is also guaranteed to be true. */ @@ -134,9 +167,28 @@ trait Symbols { self: Universe => */ def isAbstractType : Boolean - /** Is this symbol an overloaded method? + /** Does this symbol represent the definition of a skolem? + * Skolems are used during typechecking to represent type parameters viewed from inside their scopes. + * If yes, `isType` is also guaranteed to be true. */ - def isOverloaded: Boolean + def isSkolem : Boolean + + /** Does this symbol represent a free type captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeType : Boolean + + /** Is the type parameter represented by this symbol contravariant? + */ + def isContravariant : Boolean + + /** Is the type parameter represented by this symbol contravariant? + */ + def isCovariant : Boolean + + /** Does this symbol or its underlying type represent a typechecking error? + */ + def isErroneous : Boolean /** The type signature of this symbol. * Note if the symbol is a member of a class, one almost always is interested @@ -192,7 +244,7 @@ trait Symbols { self: Universe => /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has * the current symbol as its owner. */ - def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol // needed by LiftCode + def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol // needed by LiftCode !!! not enough reason to have in the api /** Low-level operation to set the symbol's flags * @return the symbol itself @@ -207,6 +259,9 @@ trait Symbols { self: Universe => /** Set symbol's annotations to given annotations `annots`. */ def setAnnotations(annots: AnnotationInfo*): this.type // needed by LiftCode !!! not enough reason to have in the api + + /** The kind of this symbol; used for debugging */ + def kind: String } val NoSymbol: Symbol diff --git a/src/library/scala/reflect/api/ToolBoxes.scala b/src/library/scala/reflect/api/ToolBoxes.scala new file mode 100644 index 0000000000..387ef5163b --- /dev/null +++ b/src/library/scala/reflect/api/ToolBoxes.scala @@ -0,0 +1,90 @@ +package scala.reflect +package api + +trait ToolBoxes { self: Universe => + + type ToolBox <: AbsToolBox + + def mkToolBox(reporter: Reporter = mkSilentReporter(), options: String = ""): AbsToolBox + + // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part. + trait AbsToolBox { + + /** UI of the toolbox. + * + * Accumulates and displays warnings and errors, can drop to interactive mode (if supported). + * The latter can be useful to study the typechecker or to debug complex macros. + */ + def reporter: Reporter + + /** Typechecks a tree using this ToolBox. + * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings. + * + * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), + * then they might, might be partially or might not be specified in the ``freeTypes'' parameter. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Ydebug. + * + * Typechecking can be steered with the following optional parameters: + * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + */ + def typeCheck(tree: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + * + * Otional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. + * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree + + /** Recursively resets symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetAllAttrs[T <: Tree](tree: T): T + + /** Recursively resets locally defined symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetLocalAttrs[T <: Tree](tree: T): T + + /** Compiles and runs a tree using this ToolBox. + * + * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), + * then they all have to be specified in the ``freeTypes'' parameter or an error occurs. + * + * This spawns the compiler at the Namer phase, and pipelines the tree through that compiler. + * Currently ``runExpr'' does not accept trees that already typechecked, because typechecking isn't idempotent. + * For more info, take a look at https://issues.scala-lang.org/browse/SI-5464. + */ + def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any + + /** Represents an error during toolboxing + */ + type ToolBoxError <: Throwable + val ToolBoxError: ToolBoxErrorExtractor + abstract class ToolBoxErrorExtractor { + def unapply(error: ToolBoxError): Option[(ToolBox, String)] + } + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala index f28008bc21..32d7eefa5b 100644 --- a/src/library/scala/reflect/api/TreeBuildUtil.scala +++ b/src/library/scala/reflect/api/TreeBuildUtil.scala @@ -1,46 +1,127 @@ -package scala.reflect.api +package scala.reflect +package api -trait TreeBuildUtil extends Universe { +trait TreeBuildUtil { self: Universe => - /** The symbol corresponding to the globally accessible class with the - * given fully qualified name `fullName`. + /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. + * Unlike `staticClassIfDefined`, throws `MissingRequirementError` is requested class cannot be found. */ def staticClass(fullName: String): Symbol - /** The symbol corresponding to the globally accessible object with the - * given fully qualified name `fullName`. + /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. + * Unlike `staticClass`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested class cannot be found. + */ + def staticClassIfDefined(fullName: String): Symbol + + /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. + * Unlike `staticModuleIfDefined`, throws `MissingRequirementError` is requested object cannot be found. */ def staticModule(fullName: String): Symbol + /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. + * Unlike `staticModule`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested object cannot be found. + */ + def staticModuleIfDefined(fullName: String): Symbol + /** The this-ptype of the globally accessible object with the * given fully qualified name `fullName`. */ def thisModuleType(fullName: String): Type /** Selects type symbol with given simple name `name` from the defined members of `owner`. + * Unlike `selectTypeIfDefined`, throws `MissingRequirementError` is requested type symbol cannot be found. */ def selectType(owner: Symbol, name: String): Symbol + /** Selects type symbol with given simple name `name` from the defined members of `owner`. + * Unlike `selectType`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested type symbol cannot be found. + */ + def selectTypeIfDefined(owner: Symbol, name: String): Symbol + /** Selects term symbol with given name and type from the defined members of prefix type - * @pre The prefix type - * @name The name of the selected member + * Unlike `selectTermIfDefined`, throws `MissingRequirementError` is requested term symbol cannot be found. */ def selectTerm(owner: Symbol, name: String): Symbol - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol + /** Selects term symbol with given name and type from the defined members of prefix type + * Unlike `selectTerm`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested term symbol cannot be found. + */ + def selectTermIfDefined(owner: Symbol, name: String): Symbol - def selectParam(owner: Symbol, idx: Int): Symbol + /** Selects overloaded method symbol with given name and index + * Unlike `selectOverloadedMethodIfDefined`, throws `MissingRequirementError` is requested overloaded method cannot be found. + */ + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol - def newScopeWith(decls: Symbol*): Scope + /** Selects overloaded method symbol with given name and index + * Unlike `selectOverloadedMethod`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested overloaded method cannot be found. + */ + def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol - /** Create a fresh free variable symbol. + /** Create a fresh free term symbol. * @param name the name of the free variable - * @param tsig the type signature of the free variable + * @param info the type signature of the free variable * @param value the value of the free variable at runtime + * @param origin debug information that tells where this symbol comes from */ - def newFreeVar(name: String, info: Type, value: Any): Symbol + def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol + + /** Create a fresh free type symbol. + * @param name the name of the free variable + * @param info the type signature of the free variable + * @param value a type tag that captures the value of the free variable + * is completely phantom, since the captured type cannot be propagated to the runtime + * if it could be, we wouldn't be creating a free type to begin with + * the only usage for it is preserving the captured symbol for compile-time analysis + * @param origin debug information that tells where this symbol comes from + */ + def newFreeType(name: String, info: Type, value: => Any, origin: String): Symbol /** Create a Modiiers structure given internal flags, qualifier, annotations */ def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers -} \ No newline at end of file + val gen: TreeGen { val global: TreeBuildUtil.this.type } + + type TreeGen <: AbsTreeGen +} + +// [Eugene to Paul] we need to expose some of the functionality provided by TreeGen +// I added some stuff that was necessary for typetag materialization macros +// but we should think it over and pick other generally useful stuff +// same goes for tree traversers/transformers, type maps, etc +// and once we expose all that, there's another question: how do we stay in sync? +trait AbsTreeGen { + val global: Universe + + import global._ + import definitions._ + + /** Builds a reference to value whose type is given stable prefix. + * The type must be suitable for this. For example, it + * must not be a TypeRef pointing to an abstract type variable. + */ + def mkAttributedQualifier(tpe: Type): Tree + + /** Builds a reference to value whose type is given stable prefix. + * If the type is unsuitable, e.g. it is a TypeRef for an + * abstract type variable, then an Ident will be made using + * termSym as the Ident's symbol. In that case, termSym must + * not be NoSymbol. + */ + def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree + + /** Builds a typed reference to given symbol with given stable prefix. */ + def mkAttributedRef(pre: Type, sym: Symbol): Tree + + /** Builds a typed reference to given symbol. */ + def mkAttributedRef(sym: Symbol): Tree + + /** Builds a typed This reference to given symbol. */ + def mkAttributedThis(sym: Symbol): Tree + + /** Builds a typed Ident with an underlying symbol. */ + def mkAttributedIdent(sym: Symbol): Tree + + /** Builds a typed Select with an underlying symbol. */ + def mkAttributedSelect(qual: Tree, sym: Symbol): Tree +} diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala index 43865915d3..3d64ec8e40 100644 --- a/src/library/scala/reflect/api/TreePrinters.scala +++ b/src/library/scala/reflect/api/TreePrinters.scala @@ -29,17 +29,21 @@ trait TreePrinters { self: Universe => def newTreePrinter(out: PrintWriter): TreePrinter // emits more or less verbatim representation of the provided tree - // todo. when LiftCode becomes a macro, throw this code away and use that macro class RawTreePrinter(out: PrintWriter) extends TreePrinter { + val EmptyValDef = self.emptyValDef def print(args: Any*): Unit = args foreach { case EmptyTree => print("EmptyTree") + case EmptyValDef => + print("emptyValDef") case tree @ TypeTree() => print("TypeTree()") if (tree.tpe != null) print(".setType(", tree.tpe, ")") else if (tree.original != null) print(".setOriginal(", tree.original, ")") + case Literal(Constant(s: String)) => + print("Literal(Constant(\"" + s + "\"))") case tree: Tree => print(tree.printingPrefix+"(") val it = tree.productIterator diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index d8180fe029..01f948809c 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -14,6 +14,7 @@ trait Trees { self: Universe => private[scala] var nodeCount = 0 type Modifiers >: Null <: AbsModifiers + val NoMods: Modifiers abstract class AbsModifiers { def modifiers: Set[Modifier] @@ -80,18 +81,14 @@ trait Trees { self: Universe => */ def printingPrefix = productPrefix - def pos: Position = annotationToPosition(rawannot) - def pos_=(pos: Position): Unit = annotation = pos + def pos: Position = rawatt.pos.asInstanceOf[Position] // [Eugene] how do we get rid of this cast? + def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness def setPos(newpos: Position): this.type = { pos = newpos; this } - private[this] var rawannot: TreeAnnotation = NoTreeAnnotation - def annotation: TreeAnnotation = rawannot - def annotation_=(annot: TreeAnnotation): Unit = { - _checkSetAnnotation(this, annot) - rawannot = annot - } - - def setAnnotation(annot: TreeAnnotation): this.type = { annotation = annot; this } + private[this] var rawatt: Attachment = NoPosition + def attachment: Attachment = rawatt + def attachment_=(att: Attachment): Unit = rawatt = att + def setAttachment(att: Attachment): this.type = { rawatt = att; this } private[this] var rawtpe: Type = _ @@ -143,6 +140,7 @@ trait Trees { self: Universe => def hasSymbol = false def isDef = false def isEmpty = false + def orElse(alt: => Tree) = if (!isEmpty) this else alt def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol) @@ -179,6 +177,13 @@ trait Trees { self: Universe => } def filter(f: Tree => Boolean): List[Tree] = withFilter(f) + /** Apply `pf' to each subtree on which the function is defined */ + def collect[T](pf: PartialFunction[Tree, T]): List[T] = { + val ctt = new CollectTreeTraverser[T](pf) + ctt.traverse(this) + ctt.results.toList + } + /** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`, * or None if none exists. */ @@ -188,9 +193,12 @@ trait Trees { self: Universe => ft.result } - /** Is there part of this tree which satisfies predicate `p`? */ + /** Is there exists a part of this tree which satisfies predicate `p`? */ def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty + /** Do all parts of this tree satisfy predicate `p`? */ + def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty + def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _) def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean = f(this, that) || ((this.productArity == that.productArity) && { @@ -230,7 +238,7 @@ trait Trees { self: Universe => duplicateTree(this).asInstanceOf[this.type] private[scala] def copyAttrs(tree: Tree): this.type = { - annotation = tree.annotation + attachment = tree.attachment tpe = tree.tpe if (hasSymbol) symbol = tree.symbol this @@ -241,6 +249,34 @@ trait Trees { self: Universe => override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] } + // [Eugene] uh-oh + // locker.comp: + // [mkdir] Created dir: C:\Projects\Kepler\build\locker\classes\compiler + // [scalacfork] Compiling 471 files to C:\Projects\Kepler\build\locker\classes\compiler + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree +// object Tree { +// // would be great if in future this generated an Expr[Magic] +// // where Magic is a magic untyped type that propagates through the entire quasiquote +// // and turns off typechecking whenever it's involved +// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked +// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo +// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree) +// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree +// +// // [Eugene] good idea? +// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr +// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +// } + /** A tree for a term. Not all terms are TermTrees; use isTerm * to reliably identify terms. */ @@ -319,12 +355,23 @@ trait Trees { self: Universe => case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template) extends ImplDef + /** @param sym the class symbol + * @return the implementation template + */ + def ClassDef(sym: Symbol, impl: Template): ClassDef + /** An object definition, e.g. `object Foo`. Internally, objects are * quite frequently called modules to reduce ambiguity. */ case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) extends ImplDef + /** + * @param sym the class symbol + * @param impl the implementation template + */ + def ModuleDef(sym: Symbol, impl: Template): ModuleDef + /** A common base class for ValDefs and DefDefs. */ abstract class ValOrDefDef extends MemberDef { @@ -343,17 +390,37 @@ trait Trees { self: Universe => */ case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef + def ValDef(sym: Symbol, rhs: Tree): ValDef + + def ValDef(sym: Symbol): ValDef + /** A method or macro definition. * @param name The name of the method or macro. Can be a type name in case this is a type macro */ case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef + def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef + /** An abstract type, a type parameter, or a type alias. */ case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) extends MemberDef + /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */ + def TypeDef(sym: Symbol, rhs: Tree): TypeDef + + /** A TypeDef node which defines abstract type or type parameter for given `sym` */ + def TypeDef(sym: Symbol): TypeDef + /** A labelled expression. Not expressible in language syntax, but * generated by the compiler to simulate while/do-while loops, and * also by the pattern matcher. @@ -371,6 +438,8 @@ trait Trees { self: Universe => case class LabelDef(name: TermName, params: List[Ident], rhs: Tree) extends DefTree with TermTree + def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef + /** Import selector * * Representation of an imported name its optional rename and their optional positions @@ -415,12 +484,19 @@ trait Trees { self: Universe => case class Block(stats: List[Tree], expr: Tree) extends TermTree + /** Block factory that flattens directly nested blocks. + */ + def Block(stats: Tree*): Block + /** Case clause in a pattern match, eliminated during explicitouter * (except for occurrences in switch statements) */ case class CaseDef(pat: Tree, guard: Tree, body: Tree) extends Tree + /** casedef shorthand */ + def CaseDef(pat: Tree, body: Tree): CaseDef + /** Alternatives of patterns, eliminated by explicitouter, except for * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...)) */ @@ -439,6 +515,8 @@ trait Trees { self: Universe => case class Bind(name: Name, body: Tree) extends DefTree + def Bind(sym: Symbol, body: Tree): Bind + case class UnApply(fun: Tree, args: List[Tree]) extends TermTree @@ -489,10 +567,14 @@ trait Trees { self: Universe => case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) extends TermTree + def Try(body: Tree, cases: (Tree, Tree)*): Try + /** Throw expression */ case class Throw(expr: Tree) extends TermTree + def Throw(tpe: Type, args: Tree*): Throw + /** Object instantiation * One should always use factory method below to build a user level new. * @@ -503,14 +585,13 @@ trait Trees { self: Universe => /** Factory method for object creation `new tpt(args_1)...(args_n)` * A `New(t, as)` is expanded to: `(new t).(as)` */ - def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { - case Nil => new ApplyConstructor(tpt, Nil) - case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply) - } + def New(tpt: Tree, argss: List[List[Tree]]): Tree + /** 0-1 argument list new, based on a type. */ - def New(tpe: Type, args: Tree*): Tree = - new ApplyConstructor(TypeTree(tpe), args.toList) + def New(tpe: Type, args: Tree*): Tree + + def New(sym: Symbol, args: Tree*): Tree /** Type annotation, eliminated by explicit outer */ case class Typed(expr: Tree, tpt: Tree) @@ -545,6 +626,8 @@ trait Trees { self: Universe => override def symbol_=(sym: Symbol) { fun.symbol = sym } } + def Apply(sym: Symbol, args: Tree*): Tree + class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args) class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args) @@ -563,7 +646,9 @@ trait Trees { self: Universe => extends TermTree with SymTree // The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none. - /** Super reference, qual = corresponding this reference */ + /** Super reference, qual = corresponding this reference + * A super reference C.super[M] is represented as Super(This(C), M). + */ case class Super(qual: Tree, mix: TypeName) extends TermTree { // The symbol of a Super is the class _from_ which the super reference is made. // For instance in C.super(...), it would be C. @@ -571,38 +656,47 @@ trait Trees { self: Universe => override def symbol_=(sym: Symbol) { qual.symbol = sym } } + def Super(sym: Symbol, mix: TypeName): Tree + /** Self reference */ case class This(qual: TypeName) extends TermTree with SymTree // The symbol of a This is the class to which the this refers. // For instance in C.this, it would be C. - def This(sym: Symbol): Tree = - This(sym.name.toTypeName) setSymbol sym + def This(sym: Symbol): Tree /** Designator . */ case class Select(qualifier: Tree, name: Name) extends RefTree - def Select(qualifier: Tree, name: String): Select = - Select(qualifier, newTermName(name)) + def Select(qualifier: Tree, name: String): Select - def Select(qualifier: Tree, sym: Symbol): Select = - Select(qualifier, sym.name) setSymbol sym + def Select(qualifier: Tree, sym: Symbol): Select /** Identifier */ case class Ident(name: Name) extends RefTree { def qualifier: Tree = EmptyTree } - def Ident(name: String): Ident = - Ident(newTermName(name)) + def Ident(name: String): Ident - def Ident(sym: Symbol): Ident = - Ident(sym.name) setSymbol sym + def Ident(sym: Symbol): Ident class BackQuotedIdent(name: Name) extends Ident(name) + /** Marks underlying reference to id as boxed. + * @pre: id must refer to a captured variable + * A reference such marked will refer to the boxed entity, no dereferencing + * with `.elem` is done on it. + * This tree node can be emitted by macros such as reify that call referenceCapturedVariable. + * It is eliminated in LambdaLift, where the boxing conversion takes place. + */ + case class ReferenceToBoxed(ident: Ident) extends TermTree { + override def symbol: Symbol = ident.symbol + override def symbol_=(sym: Symbol) { ident.symbol = sym } + } + /** Literal */ case class Literal(value: Constant) extends TermTree { @@ -873,6 +967,8 @@ trait Trees { self: Universe => traverse(qualifier) case Ident(_) => ; + case ReferenceToBoxed(idt) => + traverse(idt) case Literal(_) => ; case TypeTree() => @@ -958,6 +1054,7 @@ trait Trees { self: Universe => def This(tree: Tree, qual: Name): This def Select(tree: Tree, qualifier: Tree, selector: Name): Select def Ident(tree: Tree, name: Name): Ident + def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed def Literal(tree: Tree, value: Constant): Literal def TypeTree(tree: Tree): TypeTree def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated @@ -1040,6 +1137,8 @@ trait Trees { self: Universe => new Select(qualifier, selector).copyAttrs(tree) def Ident(tree: Tree, name: Name) = new Ident(name).copyAttrs(tree) + def ReferenceToBoxed(tree: Tree, idt: Ident) = + new ReferenceToBoxed(idt).copyAttrs(tree) def Literal(tree: Tree, value: Constant) = new Literal(value).copyAttrs(tree) def TypeTree(tree: Tree) = @@ -1228,6 +1327,11 @@ trait Trees { self: Universe => if name0 == name => t case _ => treeCopy.Ident(tree, name) } + def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { + case t @ ReferenceToBoxed(idt0) + if (idt0 == idt) => t + case _ => this.treeCopy.ReferenceToBoxed(tree, idt) + } def Literal(tree: Tree, value: Constant) = tree match { case t @ Literal(value0) if value0 == value => t @@ -1372,6 +1476,8 @@ trait Trees { self: Universe => treeCopy.Select(tree, transform(qualifier), selector) case Ident(name) => treeCopy.Ident(tree, name) + case ReferenceToBoxed(idt) => + treeCopy.ReferenceToBoxed(tree, transform(idt) match { case idt1: Ident => idt1 }) case Literal(value) => treeCopy.Literal(tree, value) case TypeTree() => @@ -1443,6 +1549,14 @@ trait Trees { self: Universe => } } + class CollectTreeTraverser[T](pf: PartialFunction[Tree, T]) extends Traverser { + val results = new ListBuffer[T] + override def traverse(t: Tree) { + if (pf.isDefinedAt(t)) results += pf(t) + super.traverse(t) + } + } + class FindTreeTraverser(p: Tree => Boolean) extends Traverser { var result: Option[Tree] = None override def traverse(t: Tree) { @@ -1535,7 +1649,7 @@ trait Trees { self: Universe => case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup) // fun(args) case Super(qual, mix) => - // qual.super[mix] if qual and/or mix is empty, ther are tpnme.EMPTY + // qual.super[mix] qual is always This(something), if mix is empty, it is tpnme.EMPTY case This(qual) => // qual.this case Select(qualifier, selector) => @@ -1544,6 +1658,10 @@ trait Trees { self: Universe => // name // note: type checker converts idents that refer to enclosing fields or methods // to selects; name ==> this.name + case ReferenceToBoxed(ident) => (created by typer, eliminated by lambdalift) + // synthetic node emitted by macros to reference capture vars directly without going through ``elem'' + // var x = ...; fun { x } will emit Ident(x), which gets transformed to Select(Ident(x), "elem") + // if ReferenceToBoxed were used instead of Ident, no transformation would be performed case Literal(value) => // value case TypeTree() => (introduced by refcheck) diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala new file mode 100644 index 0000000000..a38c21a9d4 --- /dev/null +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -0,0 +1,193 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api + +import scala.reflect.{ mirror => rm } + +/** + * Type tags encapsulate a representation of type T. + * They are supposed to replace the pre-2.10 concept of a [[scala.reflect.Manifest]]. + * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler. + * + * Type tags are organized in a hierarchy of two classes: + * [[scala.reflect.ClassTag]], [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#GroundTypeTag]]. + * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. + * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. + * A [[scala.reflect.api.Universe#GroundTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * + * TypeTags correspond loosely to Manifests. More precisely: + * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag, + * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.GroundTypeTag, + * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]]. + * + * Implicit in the contract for all Tag classes is that the reified type tpe represents the type parameter T. + * Tags are typically created by the compiler, which makes sure that this contract is kept. + * + * An example that illustrates the TypeTag embedding, consider the following function: + * + * import reflect.mirror._ + * def f[T: TypeTag, U] = { + * type L = T => U + * implicitly[TypeTag[L]] + * } + * + * Then a call of f[String, Int] will yield a result of the form + * + * TypeTag(<[ String => U ]>). + * + * Note that T has been replaced by String, because it comes with a TypeTag in f, whereas U was left as a type parameter. + */ +trait TypeTags { self: Universe => + + /** + * If an implicit value of type u.TypeTag[T] is required, the compiler will make one up on demand. + * The implicitly created value contains in its tpe field a value of type u.Type that is a reflective representation of T. + * In that value, any occurrences of type parameters or abstract types U + * which come themselves with a TypeTag are represented by the type referenced by that TypeTag. + * + * @see [[scala.reflect.api.TypeTags]] + */ + @annotation.implicitNotFound(msg = "No TypeTag available for ${T}") + abstract case class TypeTag[T](tpe: Type) { + // it's unsafe to use assert here, because we might run into deadlocks with Predef + // also see comments in ClassTags.scala + // assert(tpe != null) + + def sym = tpe.typeSymbol + + def isGround = !isNotGround + def isNotGround = tpe exists (_.typeSymbol.isAbstractType) + + def toGround: GroundTypeTag[T] = { + assert(isGround, tpe) + GroundTypeTag[T](tpe) + } + + override def toString = { + var prefix = if (isGround) "GroundTypeTag" else "TypeTag" + if (prefix != this.productPrefix) prefix = "*" + prefix + prefix + "[" + tpe + "]" + } + } + + object TypeTag { + val Byte : TypeTag[scala.Byte] = GroundTypeTag.Byte + val Short : TypeTag[scala.Short] = GroundTypeTag.Short + val Char : TypeTag[scala.Char] = GroundTypeTag.Char + val Int : TypeTag[scala.Int] = GroundTypeTag.Int + val Long : TypeTag[scala.Long] = GroundTypeTag.Long + val Float : TypeTag[scala.Float] = GroundTypeTag.Float + val Double : TypeTag[scala.Double] = GroundTypeTag.Double + val Boolean : TypeTag[scala.Boolean] = GroundTypeTag.Boolean + val Unit : TypeTag[scala.Unit] = GroundTypeTag.Unit + val Any : TypeTag[scala.Any] = GroundTypeTag.Any + val Object : TypeTag[java.lang.Object] = GroundTypeTag.Object + val AnyVal : TypeTag[scala.AnyVal] = GroundTypeTag.AnyVal + val AnyRef : TypeTag[scala.AnyRef] = GroundTypeTag.AnyRef + val Nothing : TypeTag[scala.Nothing] = GroundTypeTag.Nothing + val Null : TypeTag[scala.Null] = GroundTypeTag.Null + val String : TypeTag[java.lang.String] = GroundTypeTag.String + + def apply[T](tpe: Type): TypeTag[T] = + tpe match { + case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]] + case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]] + case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]] + case IntTpe => TypeTag.Int.asInstanceOf[TypeTag[T]] + case LongTpe => TypeTag.Long.asInstanceOf[TypeTag[T]] + case FloatTpe => TypeTag.Float.asInstanceOf[TypeTag[T]] + case DoubleTpe => TypeTag.Double.asInstanceOf[TypeTag[T]] + case BooleanTpe => TypeTag.Boolean.asInstanceOf[TypeTag[T]] + case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]] + case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]] + case ObjectTpe => TypeTag.Object.asInstanceOf[TypeTag[T]] + case AnyValTpe => TypeTag.AnyVal.asInstanceOf[TypeTag[T]] + case AnyRefTpe => TypeTag.AnyRef.asInstanceOf[TypeTag[T]] + case NothingTpe => TypeTag.Nothing.asInstanceOf[TypeTag[T]] + case NullTpe => TypeTag.Null.asInstanceOf[TypeTag[T]] + case StringTpe => TypeTag.String.asInstanceOf[TypeTag[T]] + case _ => new TypeTag[T](tpe) {} + } + } + + /** + * If an implicit value of type u.GroundTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. + * However, if the resulting type still contains references to type parameters or abstract types, a static error results. + * + * @see [[scala.reflect.api.TypeTags]] + */ + @annotation.implicitNotFound(msg = "No GroundTypeTag available for ${T}") + class GroundTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + assert(isGround, tpe) + override def productPrefix = "GroundTypeTag" + } + + object GroundTypeTag { + val Byte : GroundTypeTag[scala.Byte] = new GroundTypeTag[scala.Byte](ByteTpe) { private def readResolve() = GroundTypeTag.Byte } + val Short : GroundTypeTag[scala.Short] = new GroundTypeTag[scala.Short](ShortTpe) { private def readResolve() = GroundTypeTag.Short } + val Char : GroundTypeTag[scala.Char] = new GroundTypeTag[scala.Char](CharTpe) { private def readResolve() = GroundTypeTag.Char } + val Int : GroundTypeTag[scala.Int] = new GroundTypeTag[scala.Int](IntTpe) { private def readResolve() = GroundTypeTag.Int } + val Long : GroundTypeTag[scala.Long] = new GroundTypeTag[scala.Long](LongTpe) { private def readResolve() = GroundTypeTag.Long } + val Float : GroundTypeTag[scala.Float] = new GroundTypeTag[scala.Float](FloatTpe) { private def readResolve() = GroundTypeTag.Float } + val Double : GroundTypeTag[scala.Double] = new GroundTypeTag[scala.Double](DoubleTpe) { private def readResolve() = GroundTypeTag.Double } + val Boolean : GroundTypeTag[scala.Boolean] = new GroundTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = GroundTypeTag.Boolean } + val Unit : GroundTypeTag[scala.Unit] = new GroundTypeTag[scala.Unit](UnitTpe) { private def readResolve() = GroundTypeTag.Unit } + val Any : GroundTypeTag[scala.Any] = new GroundTypeTag[scala.Any](AnyTpe) { private def readResolve() = GroundTypeTag.Any } + val Object : GroundTypeTag[java.lang.Object] = new GroundTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = GroundTypeTag.Object } + val AnyVal : GroundTypeTag[scala.AnyVal] = new GroundTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = GroundTypeTag.AnyVal } + val AnyRef : GroundTypeTag[scala.AnyRef] = new GroundTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = GroundTypeTag.AnyRef } + val Nothing : GroundTypeTag[scala.Nothing] = new GroundTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = GroundTypeTag.Nothing } + val Null : GroundTypeTag[scala.Null] = new GroundTypeTag[scala.Null](NullTpe) { private def readResolve() = GroundTypeTag.Null } + val String : GroundTypeTag[java.lang.String] = new GroundTypeTag[java.lang.String](StringTpe) { private def readResolve() = GroundTypeTag.String } + + def apply[T](tpe: Type): GroundTypeTag[T] = + tpe match { + case ByteTpe => GroundTypeTag.Byte.asInstanceOf[GroundTypeTag[T]] + case ShortTpe => GroundTypeTag.Short.asInstanceOf[GroundTypeTag[T]] + case CharTpe => GroundTypeTag.Char.asInstanceOf[GroundTypeTag[T]] + case IntTpe => GroundTypeTag.Int.asInstanceOf[GroundTypeTag[T]] + case LongTpe => GroundTypeTag.Long.asInstanceOf[GroundTypeTag[T]] + case FloatTpe => GroundTypeTag.Float.asInstanceOf[GroundTypeTag[T]] + case DoubleTpe => GroundTypeTag.Double.asInstanceOf[GroundTypeTag[T]] + case BooleanTpe => GroundTypeTag.Boolean.asInstanceOf[GroundTypeTag[T]] + case UnitTpe => GroundTypeTag.Unit.asInstanceOf[GroundTypeTag[T]] + case AnyTpe => GroundTypeTag.Any.asInstanceOf[GroundTypeTag[T]] + case ObjectTpe => GroundTypeTag.Object.asInstanceOf[GroundTypeTag[T]] + case AnyValTpe => GroundTypeTag.AnyVal.asInstanceOf[GroundTypeTag[T]] + case AnyRefTpe => GroundTypeTag.AnyRef.asInstanceOf[GroundTypeTag[T]] + case NothingTpe => GroundTypeTag.Nothing.asInstanceOf[GroundTypeTag[T]] + case NullTpe => GroundTypeTag.Null.asInstanceOf[GroundTypeTag[T]] + case StringTpe => GroundTypeTag.String.asInstanceOf[GroundTypeTag[T]] + case _ => new GroundTypeTag[T](tpe) {} + } + + def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isGround) Some(ttag.tpe) else None + + implicit def toClassTag[T](ttag: rm.GroundTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + + implicit def toDeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) + + // this class should not be used directly in client code + class DeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: Manifest[_]): Boolean = that <:< ttag + + @deprecated("Use `tpe` to analyze the type arguments", "2.10.0") + override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.GroundTypeTag(targ)) + } + } + + // incantations for summoning + // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros +// def tag[T](implicit ttag: TypeTag[T]) = ttag +// def typeTag[T](implicit ttag: TypeTag[T]) = ttag +// def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag +// def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 0371e2c5df..12aad453b1 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -105,7 +105,8 @@ trait Types { self: Universe => /** The erased type corresponding to this type after * all transformations from Scala to Java have been performed. */ - def erasedType: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased") + def erasure: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased") + // why not name it "erasure"? /** Apply `f` to each part of this type, returning * a new type. children get mapped before their parents */ @@ -146,6 +147,33 @@ trait Types { self: Universe => * .widen = o.C */ def widen: Type + + /** The kind of this type; used for debugging */ + def kind: String + } + + /** An object representing an unknown type, used during type inference. + * If you see WildcardType outside of inference it is almost certainly a bug. + */ + val WildcardType: Type + + /** BoundedWildcardTypes, used only during type inference, are created in + * two places that I can find: + * + * 1. If the expected type of an expression is an existential type, + * its hidden symbols are replaced with bounded wildcards. + * 2. When an implicit conversion is being sought based in part on + * the name of a method in the converted type, a HasMethodMatching + * type is created: a MethodType with parameters typed as + * BoundedWildcardTypes. + */ + type BoundedWildcardType >: Null <: Type + + val BoundedWildcardType: BoundedWildcardTypeExtractor + + abstract class BoundedWildcardTypeExtractor { + def apply(bounds: TypeBounds): BoundedWildcardType + def unapply(tpe: BoundedWildcardType): Option[TypeBounds] } /** The type of Scala types, and also Scala type signatures. @@ -424,5 +452,66 @@ trait Types { self: Universe => /** The greatest lower bound wrt <:< of a list of types */ def glb(ts: List[Type]): Type + + // Creators --------------------------------------------------------------- + // too useful and too non-trivial to be left out of public API + // [Eugene to Paul] needs review! + + /** The canonical creator for single-types */ + def singleType(pre: Type, sym: Symbol): Type + + /** the canonical creator for a refined type with a given scope */ + def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type + + /** The canonical creator for a refined type with an initially empty scope. + * + * @param parents ... + * @param owner ... + * @return ... + */ + def refinedType(parents: List[Type], owner: Symbol): Type + + /** The canonical creator for typerefs + */ + def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself. */ + def intersectionType(tps: List[Type]): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself, and repeated parent classes are merged. + * + * !!! Repeated parent classes are not merged - is this a bug in the + * comment or in the code? + */ + def intersectionType(tps: List[Type], owner: Symbol): Type + + /** A creator for type applications */ + def appliedType(tycon: Type, args: List[Type]): Type + + /** A creator for type parameterizations that strips empty type parameter lists. + * Use this factory method to indicate the type has kind * (it's a polymorphic value) + * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty). + */ + def polyType(tparams: List[Symbol], tpe: Type): Type + + /** A creator for existential types. This generates: + * + * tpe1 where { tparams } + * + * where `tpe1` is the result of extrapolating `tpe` wrt to `tparams`. + * Extrapolating means that type variables in `tparams` occurring + * in covariant positions are replaced by upper bounds, (minus any + * SingletonClass markers), type variables in `tparams` occurring in + * contravariant positions are replaced by upper bounds, provided the + * resulting type is legal wrt to stability, and does not contain any type + * variable in `tparams`. + * + * The abstraction drops all type parameters that are not directly or + * indirectly referenced by type `tpe1`. If there are no remaining type + * parameters, simply returns result type `tpe`. + */ + def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type } diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index a3cec3271b..60abd267cb 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -2,18 +2,87 @@ package scala.reflect package api abstract class Universe extends Symbols + with FreeVars with Types with Constants with Scopes with Names with Trees - with Positions - with TreePrinters with AnnotationInfos + with Positions + with Exprs with StandardDefinitions - with StandardNames { - type Position - val NoPosition: Position + with TypeTags + with TreePrinters + with StandardNames + with ClassLoaders + with TreeBuildUtil + with ToolBoxes + with Reporters + with Importers { + /** Given an expression, generate a tree that when compiled and executed produces the original tree. + * The produced tree will be bound to the Universe it was called from. + * + * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression: + * + * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) + * + * The reifier transforms it to the following expression: + * + * <[ + * val $mr: scala.reflect.api.Universe = + * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", , x), "+"), List($mr.Literal($mr.Constant(1)))))) + * ]> + * + * Reification performs expression splicing (when processing Expr.eval and Expr.value) + * and type splicing (for every type T that has a TypeTag[T] implicit in scope): + * + * val two = mirror.reify(2) // Literal(Constant(2)) + * val four = mirror.reify(two.eval + two.eval) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree)) + * + * def macroImpl[T](c: Context) = { + * ... + * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion + * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl) + * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation + * val factory = c.reify{ new Queryable[T] } + * ... + * } + * + * The transformation looks mostly straightforward, but it has its tricky parts: + * * Reifier retains symbols and types defined outside the reified tree, however + * locally defined entities get erased and replaced with their original trees + * * Free variables are detected and wrapped in symbols of the type FreeVar + * * Mutable variables that are accessed from a local function are wrapped in refs + * * Since reified trees can be compiled outside of the scope they've been created in, + * special measures are taken to ensure that all members accessed in the reifee remain visible + */ + def reify[T](expr: T): Expr[T] = macro Universe.reify[T] } +object Universe { + def reify[T](cc: scala.reflect.makro.Context{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = { + import cc.mirror._ + try cc.reifyTree(cc.prefix, expr) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case cc.ReificationError(pos, msg) => + cc.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case cc.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } +} diff --git a/src/library/scala/reflect/macro/Context.scala b/src/library/scala/reflect/macro/Context.scala deleted file mode 100644 index 2fd9bb6484..0000000000 --- a/src/library/scala/reflect/macro/Context.scala +++ /dev/null @@ -1,36 +0,0 @@ -package scala.reflect -package macro - -trait Context extends api.Universe { - - /** Mark a variable as captured; i.e. force boxing in a *Ref type. - */ - def captureVariable(vble: Symbol): Unit - - /** Mark given identifier as a reference to a captured variable itself - * suppressing dereferencing with the `elem` field. - */ - def referenceCapturedVariable(id: Ident): Tree - - /** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type. - * For instance, given the abstract syntax tree representation of the `x + 1` expression: - * - * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) - * - * The reifier transforms it to the following tree: - * - * $mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", , x), "+"), List($mr.Literal($mr.Constant(1)))))) - * - * The transformation looks mostly straightforward, but it has its tricky parts: - * * Reifier retains symbols and types defined outside the reified tree, however - * locally defined entities get erased and replaced with their original trees - * * Free variables are detected and wrapped in symbols of the type FreeVar - * * Mutable variables that are accessed from a local function are wrapped in refs - * * Since reified trees can be compiled outside of the scope they've been created in, - * special measures are taken to ensure that all freeVars remain visible - * - * Typical usage of this function is to retain some of the trees received/created by a macro - * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime. - */ - def reify(tree: Tree): Tree -} diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala new file mode 100644 index 0000000000..e8b847600c --- /dev/null +++ b/src/library/scala/reflect/makro/Aliases.scala @@ -0,0 +1,26 @@ +package scala.reflect.makro + +trait Aliases { + self: Context => + + /** Aliases of mirror types */ + type Symbol = mirror.Symbol + type Type = mirror.Type + type Name = mirror.Name + type Tree = mirror.Tree + type Position = mirror.Position + type Scope = mirror.Scope + type Modifiers = mirror.Modifiers + type Expr[+T] = mirror.Expr[T] + type TypeTag[T] = mirror.TypeTag[T] + + /** Creator/extractor objects for Expr and TypeTag values */ + val TypeTag = mirror.TypeTag + val Expr = mirror.Expr + + /** incantations for summoning tags */ + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +} diff --git a/src/library/scala/reflect/makro/CapturedVariables.scala b/src/library/scala/reflect/makro/CapturedVariables.scala new file mode 100644 index 0000000000..6ce832b2b3 --- /dev/null +++ b/src/library/scala/reflect/makro/CapturedVariables.scala @@ -0,0 +1,20 @@ +package scala.reflect.makro + +trait CapturedVariables { + self: Context => + + import mirror._ + + /** Mark a variable as captured; i.e. force boxing in a *Ref type. + */ + def captureVariable(vble: Symbol): Unit + + /** Mark given identifier as a reference to a captured variable itself + * suppressing dereferencing with the `elem` field. + */ + def referenceCapturedVariable(vble: Symbol): Tree + + /** Convert type of a captured variable to *Ref type. + */ + def capturedVariableType(vble: Symbol): Type +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala new file mode 100644 index 0000000000..96a41377b3 --- /dev/null +++ b/src/library/scala/reflect/makro/Context.scala @@ -0,0 +1,59 @@ +package scala.reflect.makro + +// todo. introduce context hierarchy +// the most lightweight context should just expose the stuff from the SIP +// the full context should include all traits from scala.reflect.makro (and probably reside in scala-compiler.jar) + +trait Context extends Aliases + with CapturedVariables + with Enclosures + with Infrastructure + with Names + with Reifiers + with Reporters + with Settings + with Symbols + with Typers + with Util { + + /** The mirror that corresponds to the compile-time universe */ + val mirror: scala.reflect.api.Universe + + /** The type of the prefix tree from which the macro is selected */ + type PrefixType + + /** The prefix tree from which the macro is selected */ + val prefix: Expr[PrefixType] + + /** Alias to the underlying mirror's reify */ + def reify[T](expr: T): Expr[T] = macro Context.reify[T] +} + +object Context { + def reify[T](cc: Context{ type PrefixType = Context })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = { + import cc.mirror._ + // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? + val prefix: Tree = Select(cc.prefix, newTermName("mirror")) + val prefixTpe = cc.typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe + prefix setType prefixTpe + try cc.reifyTree(prefix, expr) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case cc.ReificationError(pos, msg) => + cc.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case cc.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } +} diff --git a/src/library/scala/reflect/makro/Enclosures.scala b/src/library/scala/reflect/makro/Enclosures.scala new file mode 100644 index 0000000000..136d39498e --- /dev/null +++ b/src/library/scala/reflect/makro/Enclosures.scala @@ -0,0 +1,53 @@ +package scala.reflect.makro + +trait Enclosures { + self: Context => + + /** The tree that undergoes macro expansion. + * Can be useful to get an offset or a range position of the entire tree being processed. + */ + val macroApplication: Tree + + /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only. + * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. + * + * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees. + * In that dire case navigate the ``enclosingMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application. + * See ``enclosingPosition'' for a default implementation of this logic. + * + * Unlike `openMacros`, this is a val, which means that it gets initialized when the context is created + * and always stays the same regardless of whatever happens during macro expansion. + */ + val enclosingMacros: List[Context] + + /** Types along with corresponding trees for which implicit arguments are currently searched. + * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion. + * + * Unlike `openImplicits`, this is a val, which means that it gets initialized when the context is created + * and always stays the same regardless of whatever happens during macro expansion. + */ + val enclosingImplicits: List[(Type, Tree)] + + /** Tries to guess a position for the enclosing application. + * But that is simple, right? Just dereference ``pos'' of ``macroApplication''? Not really. + * If we're in a synthetic macro expansion (no positions), we must do our best to infer the position of something that triggerd this expansion. + * Surprisingly, quite often we can do this by navigation the ``enclosingMacros'' stack. + */ + val enclosingPosition: Position + + /** Tree that corresponds to the enclosing application, or EmptyTree if not applicable. + */ + val enclosingApplication: Tree + + /** Tree that corresponds to the enclosing method, or EmptyTree if not applicable. + */ + val enclosingMethod: Tree + + /** Tree that corresponds to the enclosing class, or EmptyTree if not applicable. + */ + val enclosingClass: Tree + + /** Compilation unit that contains this macro application. + */ + val enclosingUnit: CompilationUnit +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Infrastructure.scala b/src/library/scala/reflect/makro/Infrastructure.scala new file mode 100644 index 0000000000..2bf49dca77 --- /dev/null +++ b/src/library/scala/reflect/makro/Infrastructure.scala @@ -0,0 +1,73 @@ +package scala.reflect.makro + +trait Infrastructure { + self: Context => + + /** Determines whether the compiler expanding a macro targets JVM. + */ + val forJVM: Boolean + + /** Determines whether the compiler expanding a macro targets CLR. + */ + val forMSIL: Boolean + + /** Determines whether the compiler expanding a macro is a presentation compiler. + */ + val forInteractive: Boolean + + /** Determines whether the compiler expanding a macro is a Scaladoc compiler. + */ + val forScaladoc: Boolean + + /** Exposes current compilation run. + */ + val currentRun: Run + + /** As seen by macro API, compilation run is an opaque type that can be deconstructed into: + * 1) Current compilation unit + * 2) List of all compilation units that comprise the run + */ + type Run + + val Run: RunExtractor + + abstract class RunExtractor { + def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] + } + + /** As seen by macro API, compilation unit is an opaque type that can be deconstructed into: + * 1) File that corresponds to the unit (if not applicable, null) + * 2) Content of the file (if not applicable, empty array) + * 3) Body, i.e. the AST that represents the compilation unit + */ + type CompilationUnit + + val CompilationUnit: CompilationUnitExtractor + + abstract class CompilationUnitExtractor { + def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] + } + + /** Returns a macro definition which triggered this macro expansion. + */ + val currentMacro: Symbol + + // todo. redo caches as discussed on Reflecting Meeting 2012/03/29 + // https://docs.google.com/document/d/1oUZGQpdt2qwioTlJcSt8ZFQwVLTvpxn8xa67P8OGVpU/edit + + /** A cache shared by all invocations of all macros across all compilation runs. + * + * Needs to be used with extreme care, since memory leaks here will swiftly crash the presentation compiler. + * For example, Scala IDE typically launches a compiler run on every edit action so there might be hundreds of runs per minute. + */ + val globalCache: collection.mutable.Map[Any, Any] + + /** A cache shared by all invocations of the same macro within a single compilation run. + * + * This cache is cleared automatically after a compilation run is completed or abandoned. + * It is also specific to a particular macro definition. + * + * To share data between different macros and/or different compilation runs, use ``globalCache''. + */ + val cache: collection.mutable.Map[Any, Any] +} diff --git a/src/library/scala/reflect/makro/Names.scala b/src/library/scala/reflect/makro/Names.scala new file mode 100644 index 0000000000..8a823d19cb --- /dev/null +++ b/src/library/scala/reflect/makro/Names.scala @@ -0,0 +1,14 @@ +package scala.reflect.makro + +trait Names { + self: Context => + + /** Creates a fresh string */ + def fresh(): String + + /** Creates a fresh string from the provided string */ + def fresh(name: String): String + + /** Creates a fresh name from the provided name */ + def fresh(name: Name): Name +} diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala new file mode 100644 index 0000000000..9bd25cf0f8 --- /dev/null +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -0,0 +1,82 @@ +package scala.reflect.makro + +trait Reifiers { + self: Context => + + /** Reification prefix that refers to the standard reflexive mirror, ``scala.reflect.mirror''. + * Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a tree that can be inspected at runtime. + */ + val reflectMirrorPrefix: Tree + + /** Given a tree, generate a tree that when compiled and executed produces the original tree. + * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). + * For more information and examples see the documentation for ``Universe.reify''. + * + * This function is deeply connected to ``Universe.reify'', a macro that reifies arbitrary expressions into runtime trees. + * They do very similar things (``Universe.reify'' calls ``Context.reifyTree'' to implement itself), but they operate on different metalevels (see below). + * + * Let's study the differences between ``Context.reifyTree'' and ``Universe.reify'' on an example of using them inside a ``fooMacro'' macro: + * + * * Since reify itself is a macro, it will be executed when fooMacro is being compiled (metalevel -1) + * and will produce a tree that when evaluated during macro expansion of fooMacro (metalevel 0) will recreate the input tree. + * + * This provides a facility analogous to quasi-quoting. Writing "reify{ expr }" will generate an AST that represents expr. + * Afterwards this AST (or its parts) can be used to construct the return value of fooMacro. + * + * * reifyTree is evaluated during macro expansion (metalevel 0) + * and will produce a tree that when evaluated during the runtime of the program (metalevel 1) will recreate the input tree. + * + * This provides a way to retain certain trees from macro expansion time to be inspected later, in the runtime. + * For example, DSL authors may find it useful to capture DSL snippets into ASTs that are then processed at runtime in a domain-specific way. + * + * Also note the difference between universes of the runtime trees produced by two reifies: + * + * * The result of compiling and running the result of reify will be bound to the Universe that called reify. + * This is possible because it's a macro, so it can generate whatever code it wishes. + * + * * The result of compiling and running the result of reifyTree will be the ``prefix'' that needs to be passed explicitly. + * This happens because the Universe of the evaluated result is from a different metalevel than the Context the called reify. + * + * Typical usage of this function is to retain some of the trees received/created by a macro + * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime. + */ + def reifyTree(prefix: Tree, tree: Tree): Tree + + /** Given a type, generate a tree that when compiled and executed produces the original type. + * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). + * For more information and examples see the documentation for ``Context.reifyTree'' and ``Universe.reify''. + */ + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree + + /** Undoes reification of a tree. + * + * This reversion doesn't simply restore the original tree (that would lose the context of reification), + * but does something more involved that conforms to the following laws: + * + * 1) unreifyTree(reifyTree(tree)) != tree // unreified tree is tree + saved context + * // in current implementation, the result of unreify is opaque + * // i.e. there's no possibility to inspect underlying tree/context + * + * 2) reifyTree(unreifyTree(reifyTree(tree))) == reifyTree(tree) // the result of reifying a tree in its original context equals to + * // the result of reifying a tree along with its saved context + * + * 3) compileAndEval(unreifyTree(reifyTree(tree))) ~ compileAndEval(tree) // at runtime original and unreified trees are behaviorally equivalent + */ + def unreifyTree(tree: Tree): Tree + + /** Represents an error during reification + */ + type ReificationError <: Throwable + val ReificationError: ReificationErrorExtractor + abstract class ReificationErrorExtractor { + def unapply(error: ReificationError): Option[(Position, String)] + } + + /** Wraps an unexpected error during reification + */ + type UnexpectedReificationError <: Throwable + val UnexpectedReificationError: UnexpectedReificationErrorExtractor + abstract class UnexpectedReificationErrorExtractor { + def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] + } +} diff --git a/src/library/scala/reflect/makro/Reporters.scala b/src/library/scala/reflect/makro/Reporters.scala new file mode 100644 index 0000000000..7341b0e0b7 --- /dev/null +++ b/src/library/scala/reflect/makro/Reporters.scala @@ -0,0 +1,39 @@ +package scala.reflect.makro + +trait Reporters { + self: Context => + + import mirror._ + + /** Exposes means to control the compiler UI */ + def reporter: Reporter + def setReporter(reporter: Reporter): this.type + def withReporter[T](reporter: Reporter)(op: => T): T + + /** For sending a message which should not be labeled as a warning/error, + * but also shouldn't require -verbose to be visible. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def echo(pos: Position, msg: String): Unit + + /** Informational messages, suppressed unless -verbose or force=true. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def info(pos: Position, msg: String, force: Boolean): Unit + + /** Warnings and errors. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def hasWarnings: Boolean + def hasErrors: Boolean + def warning(pos: Position, msg: String): Unit + def error(pos: Position, msg: String): Unit + + /** Abruptly terminates current macro expansion leaving a note about what happened. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def abort(pos: Position, msg: String): Nothing + + /** Drops into interactive mode if supported by the compiler UI */ + def interactive(): Unit +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Settings.scala b/src/library/scala/reflect/makro/Settings.scala new file mode 100644 index 0000000000..c4a8ebd1b5 --- /dev/null +++ b/src/library/scala/reflect/makro/Settings.scala @@ -0,0 +1,38 @@ +package scala.reflect.makro + +trait Settings { + self: Context => + + /** Exposes macro-specific settings as a list of strings. + * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option. + */ + def settings: List[String] + + /** Exposes current compiler settings as a list of options. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + // [Eugene] ugly? yes, but I don't really fancy copy/pasting all our settings here and keep it synchronized at all times + // why all settings? because macros need to be in full control of the stuff going on + // maybe later we can implement a gettable/settable list of important settings, but for now let's leave it like that + def compilerSettings: List[String] + + /** Updates current compiler settings with an option string. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def setCompilerSettings(options: String): this.type + + /** Updates current compiler settings with a list of options. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def setCompilerSettings(options: List[String]): this.type + + /** Temporary sets compiler settings to a given option string and executes a given closure. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def withCompilerSettings[T](options: String)(op: => T): T + + /** Temporary sets compiler settings to a given list of options and executes a given closure. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def withCompilerSettings[T](options: List[String])(op: => T): T +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Symbols.scala b/src/library/scala/reflect/makro/Symbols.scala new file mode 100644 index 0000000000..91a5f6d8a5 --- /dev/null +++ b/src/library/scala/reflect/makro/Symbols.scala @@ -0,0 +1,17 @@ +package scala.reflect.makro + +trait Symbols { + self: Context => + + /** Can this symbol be loaded by a reflective mirror? + * + * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. + * Such annotations (also called "pickles") are applied on top-level classes and include information + * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block) + * are typically unreachable and information about them gets lost. + * + * This method is useful for macro writers who wish to save certain ASTs to be used at runtime. + * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment. + */ + def isLocatable(sym: Symbol): Boolean +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Typers.scala b/src/library/scala/reflect/makro/Typers.scala new file mode 100644 index 0000000000..1ced2daccd --- /dev/null +++ b/src/library/scala/reflect/makro/Typers.scala @@ -0,0 +1,85 @@ +package scala.reflect.makro + +trait Typers { + self: Context => + + import mirror._ + + /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only. + * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. + * + * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees. + * In that dire case navigate the ``openMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application. + * See ``enclosingPosition'' for a default implementation of this logic. + * + * Unlike `enclosingMacros`, this is a def, which means that it gets recalculated on every invocation, + * so it might change depending on what is going on during macro expansion. + */ + def openMacros: List[Context] + + /** Types along with corresponding trees for which implicit arguments are currently searched. + * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion. + * + * Unlike `enclosingImplicits`, this is a def, which means that it gets recalculated on every invocation, + * so it might change depending on what is going on during macro expansion. + */ + def openImplicits: List[(Type, Tree)] + + /** Typechecks the provided tree against the expected type ``pt'' in the macro callsite context. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Ymacro-debug. + * Unlike in ``inferImplicitValue'' and ``inferImplicitView'', ``silent'' is false by default. + * + * Typechecking can be steered with the following optional parameters: + * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + */ + def typeCheck(tree: Tree, pt: Type = WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. + * Optional ``pos'' parameter provides a position that will be associated with the implicit search. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree + + /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + * + * Optional ``pos'' parameter provides a position that will be associated with the implicit search. + * Another optional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. + * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree + + /** Recursively resets symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetAllAttrs[T <: Tree](tree: T): T + + /** Recursively resets locally defined symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetLocalAttrs[T <: Tree](tree: T): T + + /** Represents an error during typechecking + */ + type TypeError <: Throwable + val TypeError: TypeErrorExtractor + abstract class TypeErrorExtractor { + def unapply(error: TypeError): Option[(Position, String)] + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Util.scala b/src/library/scala/reflect/makro/Util.scala new file mode 100644 index 0000000000..16eb2395a9 --- /dev/null +++ b/src/library/scala/reflect/makro/Util.scala @@ -0,0 +1,31 @@ +package scala.reflect.makro + +trait Util { + self: Context => + + def literalNull: Expr[Null] + + def literalUnit: Expr[Unit] + + def literalTrue: Expr[Boolean] + + def literalFalse: Expr[Boolean] + + def literal(x: Boolean): Expr[Boolean] + + def literal(x: Byte): Expr[Byte] + + def literal(x: Short): Expr[Short] + + def literal(x: Int): Expr[Int] + + def literal(x: Long): Expr[Long] + + def literal(x: Float): Expr[Float] + + def literal(x: Double): Expr[Double] + + def literal(x: String): Expr[String] + + def literal(x: Char): Expr[Char] +} diff --git a/src/library/scala/reflect/makro/internal/macroImpl.scala b/src/library/scala/reflect/makro/internal/macroImpl.scala new file mode 100644 index 0000000000..86600ba0a1 --- /dev/null +++ b/src/library/scala/reflect/makro/internal/macroImpl.scala @@ -0,0 +1,5 @@ +package scala.reflect.makro +package internal + +/** This type is required by the compiler and should not be used in client code. */ +class macroImpl(val referenceToMacroImpl: Any) extends StaticAnnotation diff --git a/src/library/scala/reflect/makro/internal/typeTagImpl.scala b/src/library/scala/reflect/makro/internal/typeTagImpl.scala new file mode 100644 index 0000000000..6c49ef45de --- /dev/null +++ b/src/library/scala/reflect/makro/internal/typeTagImpl.scala @@ -0,0 +1,133 @@ +package scala.reflect.makro + +import scala.reflect.api.Universe + +/** This package is required by the compiler and should not be used in client code. */ +package object internal { + /** This method is required by the compiler and should not be used in client code. */ + def materializeClassTag[T](u: Universe): ClassTag[T] = macro materializeClassTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeClassTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ClassTag[T]] = + c.Expr[Nothing](c.materializeClassTag(u.tree, implicitly[c.TypeTag[T]].tpe))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + def materializeTypeTag[T](u: Universe): u.TypeTag[T] = macro materializeTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = false))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + def materializeGroundTypeTag[T](u: Universe): u.GroundTypeTag[T] = macro materializeGroundTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeGroundTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.GroundTypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = true))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils +} + +package internal { + private[scala] abstract class Utils { + val c: Context + + import c.mirror._ + import definitions._ + + val coreTags = Map( + ByteClass.asType -> newTermName("Byte"), + ShortClass.asType -> newTermName("Short"), + CharClass.asType -> newTermName("Char"), + IntClass.asType -> newTermName("Int"), + LongClass.asType -> newTermName("Long"), + FloatClass.asType -> newTermName("Float"), + DoubleClass.asType -> newTermName("Double"), + BooleanClass.asType -> newTermName("Boolean"), + UnitClass.asType -> newTermName("Unit"), + AnyClass.asType -> newTermName("Any"), + ObjectClass.asType -> newTermName("Object"), + AnyValClass.asType -> newTermName("AnyVal"), + AnyRefClass.asType -> newTermName("AnyRef"), + NothingClass.asType -> newTermName("Nothing"), + NullClass.asType -> newTermName("Null")) + + def materializeClassTag(prefix: Tree, tpe: Type): Tree = { + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) + case _ => + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Ident(ClassTagModule), coreTags(coreTpe)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) + val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) + Select(componentTag, newTermName("wrap")) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") + val erasure = + if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? + else tpe.erasure.normalize // necessary to deal with erasures of HK types + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { + val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + case _ => + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case c.ReificationError(pos, msg) => + c.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case c.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + + private def fail(reason: Any): Nothing = { + val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication + val tpe = tpeTree.tpe + val PolyType(_, MethodType(_, tagTpe)) = fun.tpe + val tagModule = tagTpe.typeSymbol.companionSymbol + if (c.compilerSettings.contains("-Xlog-implicits")) + c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) + c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) + } + } +} diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 1c3e618520..7a8267e689 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -2,21 +2,28 @@ package scala package object reflect { + import ReflectionUtils._ + // !!! This was a val; we can't throw exceptions that aggressively without breaking // non-standard environments, e.g. google app engine. I made it a lazy val, but // I think it would be better yet to throw the exception somewhere else - not during // initialization, but in response to a doomed attempt to utilize it. - lazy val mirror: api.Mirror = { + + // todo. default mirror (a static object) might become a source for memory leaks (because it holds a strong reference to a classloader)! + lazy val mirror: api.Mirror = mkMirror(defaultReflectionClassLoader) + + def mkMirror(classLoader: ClassLoader): api.Mirror = { // we use (Java) reflection here so that we can keep reflect.runtime and reflect.internals in a seperate jar - ReflectionUtils.singletonInstanceOpt("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse { - throw new UnsupportedOperationException("Scala reflection not available on this platform") + // note that we must instantiate the mirror with current classloader, otherwise we won't be able to cast it to api.Mirror + // that's not a problem, though, because mirror can service classes from arbitrary classloaders + val instance = invokeFactoryOpt(getClass.getClassLoader, "scala.reflect.runtime.package", "mkMirror", classLoader) + instance match { + case Some(x: api.Mirror) => x + case Some(_) => throw new UnsupportedOperationException("Available scala reflection implementation is incompatible with this interface") + case None => throw new UnsupportedOperationException("Scala reflection not available on this platform") } } - type Symbol = mirror.Symbol - type Type = mirror.Type - type Tree = mirror.Tree - @deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0") type BeanDescription = scala.beans.BeanDescription @deprecated("Use `@scala.beans.BeanDisplayName` instead", "2.10.0") @@ -31,4 +38,26 @@ package object reflect { type BooleanBeanProperty = scala.beans.BooleanBeanProperty @deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0") type ScalaBeanInfo = scala.beans.ScalaBeanInfo + + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") + type ClassManifest[T] = ClassTag[T] + @deprecated("OptManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") + type OptManifest[T] = TypeTag[T] + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + type Manifest[T] = GroundTypeTag[T] + + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") + val ClassManifest = ClassTag + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + lazy val Manifest = GroundTypeTag + @deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") + object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable + + // ClassTag class is defined separately from the mirror + type TypeTag[T] = scala.reflect.mirror.TypeTag[T] + type GroundTypeTag[T] = scala.reflect.mirror.GroundTypeTag[T] + + // ClassTag object is defined separately from the mirror + lazy val TypeTag = scala.reflect.mirror.TypeTag + lazy val GroundTypeTag = scala.reflect.mirror.GroundTypeTag } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 8bc63ae3a0..d06eba8f7d 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -31,7 +31,7 @@ object ScalaRunTime { clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: Class[_]) = clazz.isPrimitive() - def isTuple(x: Any) = tupleNames(x.getClass.getName) + def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName) def isAnyVal(x: Any) = x match { case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true case _ => false diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala index daeaf4c53b..c2269cde45 100644 --- a/src/library/scala/util/Marshal.scala +++ b/src/library/scala/util/Marshal.scala @@ -35,7 +35,8 @@ object Marshal { def load[A](buffer: Array[Byte])(implicit expected: ClassManifest[A]): A = { val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) val found = in.readObject.asInstanceOf[ClassManifest[_]] - if (found <:< expected) { + // todo. [Eugene] needs review, since ClassManifests no longer capture typeArguments + if (found.tpe <:< expected.tpe) { val o = in.readObject.asInstanceOf[A] in.close() o diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala index fa533eeb10..8d239a84bd 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala @@ -96,6 +96,7 @@ class ConsoleFileManager extends FileManager { latestActorsFile = dir / "lib/scala-actors.jar" latestCompFile = dir / "lib/scala-compiler.jar" latestPartestFile = dir / "lib/scala-partest.jar" + latestFjbgFile = testParent / "lib" / "fjbg.jar" } else { def setupQuick() { diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala index fc5792e886..1aa0a7baf6 100644 --- a/src/partest/scala/tools/partest/nest/TestFile.scala +++ b/src/partest/scala/tools/partest/nest/TestFile.scala @@ -35,7 +35,9 @@ abstract class TestFile(val kind: String) extends TestFileCommon { if (setOutDir) settings.outputDirs setSingleOutput setOutDirTo.path - // adding code.jar to the classpath (to provide Code.lift services for reification tests) + // adding codelib.jar to the classpath + // codelib provides the possibility to override standard reify + // this shields the massive amount of reification tests from changes in the API settings.classpath prepend PathSettings.srcCodeLib.toString if (propIsSet("java.class.path")) setProp("java.class.path", PathSettings.srcCodeLib.toString + ";" + propOrElse("java.class.path", "")) diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index cb6f2a0edc..00ee8ba857 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -181,7 +181,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor // private def replaceSlashes(dir: File, s: String): String = { val base = (dir.getAbsolutePath + File.separator).replace('\\', '/') - s.replace('\\', '/').replaceAll("""\Q%s\E""" format base, "") + var regex = """\Q%s\E""" format base + if (isWin) regex = "(?i)" + regex + s.replace('\\', '/').replaceAll(regex, "") } private def currentFileString = { @@ -521,9 +523,15 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor runTestCommon(file, expectFailure = false)((logFile, outDir) => { val dir = file.getParentFile - // adding code.jar to the classpath (to provide Code.lift services for reification tests) - execTest(outDir, logFile, PathSettings.srcCodeLib.toString) && - diffCheck(compareOutput(dir, logFile)) + // adding codelib.jar to the classpath + // codelib provides the possibility to override standard reify + // this shields the massive amount of reification tests from changes in the API + execTest(outDir, logFile, PathSettings.srcCodeLib.toString) && { + // cannot replace paths here since this also inverts slashes + // which affects a bunch of tests + //fileManager.mapFile(logFile, replaceSlashes(dir, _)) + diffCheck(compareOutput(dir, logFile)) + } }) // Apache Ant 1.6 or newer diff --git a/test/files/codelib/code.jar.desired.sha1 b/test/files/codelib/code.jar.desired.sha1 index 8dabf404b9..21c4dccb30 100644 --- a/test/files/codelib/code.jar.desired.sha1 +++ b/test/files/codelib/code.jar.desired.sha1 @@ -1 +1 @@ -e76a8883d275ca4870f745b505fb0a1cb9cbe446 ?code.jar +3ddb9fded6e19ca591a78b8a294284c9e945da30 ?code.jar diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 243c9aa3be..d93e314d8e 100755 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -1,372 +1,372 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> - -scala> // basics - -scala> 3+4 -res0: Int = 7 - -scala> def gcd(x: Int, y: Int): Int = { - if (x == 0) y - else if (y == 0) x - else gcd(y%x, x) -} -gcd: (x: Int, y: Int)Int - -scala> val five = gcd(15,35) -five: Int = 5 - -scala> var x = 1 -x: Int = 1 - -scala> x = 2 -x: Int = 2 - -scala> val three = x+1 -three: Int = 3 - -scala> type anotherint = Int -defined type alias anotherint - -scala> val four: anotherint = 4 -four: anotherint = 4 - -scala> val bogus: anotherint = "hello" -:8: error: type mismatch; - found : String("hello") - required: anotherint - (which expands to) Int - val bogus: anotherint = "hello" - ^ - -scala> trait PointlessTrait -defined trait PointlessTrait - -scala> val (x,y) = (2,3) -x: Int = 2 -y: Int = 3 - -scala> println("hello") -hello - -scala> - -scala> // ticket #1513 - -scala> val t1513 = Array(null) -t1513: Array[Null] = Array(null) - -scala> // ambiguous toString problem from #547 - -scala> val atom = new scala.xml.Atom() -atom: scala.xml.Atom[Unit] = () - -scala> // overriding toString problem from #1404 - -scala> class S(override val toString : String) -defined class S - -scala> val fish = new S("fish") -fish: S = fish - -scala> // Test that arrays pretty print nicely. - -scala> val arr = Array("What's", "up", "doc?") -arr: Array[String] = Array(What's, up, doc?) - -scala> // Test that arrays pretty print nicely, even when we give them type Any - -scala> val arrInt : Any = Array(1,2,3) -arrInt: Any = Array(1, 2, 3) - -scala> // Test that nested arrays are pretty-printed correctly - -scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) -arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) - -scala> - -scala> // implicit conversions - -scala> case class Foo(n: Int) -defined class Foo - -scala> case class Bar(n: Int) -defined class Bar - -scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) -foo2bar: (foo: Foo)Bar - -scala> val bar: Bar = Foo(3) -bar: Bar = Bar(3) - -scala> - -scala> // importing from a previous result - -scala> import bar._ -import bar._ - -scala> val m = n -m: Int = 3 - -scala> - -scala> // stressing the imports mechanism - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> - -scala> - -scala> val x1 = 1 -x1: Int = 1 - -scala> val x2 = 1 -x2: Int = 1 - -scala> val x3 = 1 -x3: Int = 1 - -scala> val x4 = 1 -x4: Int = 1 - -scala> val x5 = 1 -x5: Int = 1 - -scala> val x6 = 1 -x6: Int = 1 - -scala> val x7 = 1 -x7: Int = 1 - -scala> val x8 = 1 -x8: Int = 1 - -scala> val x9 = 1 -x9: Int = 1 - -scala> val x10 = 1 -x10: Int = 1 - -scala> val x11 = 1 -x11: Int = 1 - -scala> val x12 = 1 -x12: Int = 1 - -scala> val x13 = 1 -x13: Int = 1 - -scala> val x14 = 1 -x14: Int = 1 - -scala> val x15 = 1 -x15: Int = 1 - -scala> val x16 = 1 -x16: Int = 1 - -scala> val x17 = 1 -x17: Int = 1 - -scala> val x18 = 1 -x18: Int = 1 - -scala> val x19 = 1 -x19: Int = 1 - -scala> val x20 = 1 -x20: Int = 1 - -scala> - -scala> val two = one + x5 -two: Int = 2 - -scala> - -scala> // handling generic wildcard arrays (#2386) - -scala> // It's put here because type feedback is an important part of it. - -scala> val xs: Array[_] = Array(1, 2) -xs: Array[_] = Array(1, 2) - -scala> xs.size -res2: Int = 2 - -scala> xs.head -res3: Any = 1 - -scala> xs filter (_ == 2) -res4: Array[_] = Array(2) - -scala> xs map (_ => "abc") -res5: Array[String] = Array(abc, abc) - -scala> xs map (x => x) -res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) - -scala> xs map (x => (x, x)) -res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) - -scala> - -scala> // interior syntax errors should *not* go into multi-line input mode. - -scala> // both of the following should abort immediately: - -scala> def x => y => z -:1: error: '=' expected but '=>' found. - def x => y => z - ^ - -scala> [1,2,3] -:1: error: illegal start of definition - [1,2,3] - ^ - -scala> - -scala> - -scala> // multi-line XML - -scala> - -res8: scala.xml.Elem = - - - -scala> - -scala> - -scala> /* - /* - multi-line comment - */ -*/ - -scala> - -scala> - -scala> // multi-line string - -scala> """ -hello -there -""" -res9: String = -" -hello -there -" - -scala> - -scala> (1 + // give up early by typing two blank lines - - -You typed two blank lines. Starting a new command. - -scala> // defining and using quoted names should work (ticket #323) - -scala> def `match` = 1 -match: Int - -scala> val x = `match` -x: Int = 1 - -scala> - -scala> // multiple classes defined on one line - -scala> sealed class Exp; class Fact extends Exp; class Term extends Exp -defined class Exp -defined class Fact -defined class Term - -scala> def f(e: Exp) = e match { // non-exhaustive warning here - case _:Fact => 3 -} -:18: warning: match is not exhaustive! -missing combination Exp -missing combination Term - - def f(e: Exp) = e match { // non-exhaustive warning here - ^ -f: (e: Exp)Int - -scala> - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> // basics + +scala> 3+4 +res0: Int = 7 + +scala> def gcd(x: Int, y: Int): Int = { + if (x == 0) y + else if (y == 0) x + else gcd(y%x, x) +} +gcd: (x: Int, y: Int)Int + +scala> val five = gcd(15,35) +five: Int = 5 + +scala> var x = 1 +x: Int = 1 + +scala> x = 2 +x: Int = 2 + +scala> val three = x+1 +three: Int = 3 + +scala> type anotherint = Int +defined type alias anotherint + +scala> val four: anotherint = 4 +four: anotherint = 4 + +scala> val bogus: anotherint = "hello" +:8: error: type mismatch; + found : String("hello") + required: anotherint + (which expands to) Int + val bogus: anotherint = "hello" + ^ + +scala> trait PointlessTrait +defined trait PointlessTrait + +scala> val (x,y) = (2,3) +x: Int = 2 +y: Int = 3 + +scala> println("hello") +hello + +scala> + +scala> // ticket #1513 + +scala> val t1513 = Array(null) +t1513: Array[Null] = Array(null) + +scala> // ambiguous toString problem from #547 + +scala> val atom = new scala.xml.Atom() +atom: scala.xml.Atom[Unit] = () + +scala> // overriding toString problem from #1404 + +scala> class S(override val toString : String) +defined class S + +scala> val fish = new S("fish") +fish: S = fish + +scala> // Test that arrays pretty print nicely. + +scala> val arr = Array("What's", "up", "doc?") +arr: Array[String] = Array(What's, up, doc?) + +scala> // Test that arrays pretty print nicely, even when we give them type Any + +scala> val arrInt : Any = Array(1,2,3) +arrInt: Any = Array(1, 2, 3) + +scala> // Test that nested arrays are pretty-printed correctly + +scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) +arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) + +scala> + +scala> // implicit conversions + +scala> case class Foo(n: Int) +defined class Foo + +scala> case class Bar(n: Int) +defined class Bar + +scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) +foo2bar: (foo: Foo)Bar + +scala> val bar: Bar = Foo(3) +bar: Bar = Bar(3) + +scala> + +scala> // importing from a previous result + +scala> import bar._ +import bar._ + +scala> val m = n +m: Int = 3 + +scala> + +scala> // stressing the imports mechanism + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> + +scala> + +scala> val x1 = 1 +x1: Int = 1 + +scala> val x2 = 1 +x2: Int = 1 + +scala> val x3 = 1 +x3: Int = 1 + +scala> val x4 = 1 +x4: Int = 1 + +scala> val x5 = 1 +x5: Int = 1 + +scala> val x6 = 1 +x6: Int = 1 + +scala> val x7 = 1 +x7: Int = 1 + +scala> val x8 = 1 +x8: Int = 1 + +scala> val x9 = 1 +x9: Int = 1 + +scala> val x10 = 1 +x10: Int = 1 + +scala> val x11 = 1 +x11: Int = 1 + +scala> val x12 = 1 +x12: Int = 1 + +scala> val x13 = 1 +x13: Int = 1 + +scala> val x14 = 1 +x14: Int = 1 + +scala> val x15 = 1 +x15: Int = 1 + +scala> val x16 = 1 +x16: Int = 1 + +scala> val x17 = 1 +x17: Int = 1 + +scala> val x18 = 1 +x18: Int = 1 + +scala> val x19 = 1 +x19: Int = 1 + +scala> val x20 = 1 +x20: Int = 1 + +scala> + +scala> val two = one + x5 +two: Int = 2 + +scala> + +scala> // handling generic wildcard arrays (#2386) + +scala> // It's put here because type feedback is an important part of it. + +scala> val xs: Array[_] = Array(1, 2) +xs: Array[_] = Array(1, 2) + +scala> xs.size +res2: Int = 2 + +scala> xs.head +res3: Any = 1 + +scala> xs filter (_ == 2) +res4: Array[_] = Array(2) + +scala> xs map (_ => "abc") +res5: Array[String] = Array(abc, abc) + +scala> xs map (x => x) +res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) + +scala> xs map (x => (x, x)) +res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) + +scala> + +scala> // interior syntax errors should *not* go into multi-line input mode. + +scala> // both of the following should abort immediately: + +scala> def x => y => z +:1: error: '=' expected but '=>' found. + def x => y => z + ^ + +scala> [1,2,3] +:1: error: illegal start of definition + [1,2,3] + ^ + +scala> + +scala> + +scala> // multi-line XML + +scala> + +res8: scala.xml.Elem = + + + +scala> + +scala> + +scala> /* + /* + multi-line comment + */ +*/ + +scala> + +scala> + +scala> // multi-line string + +scala> """ +hello +there +""" +res9: String = +" +hello +there +" + +scala> + +scala> (1 + // give up early by typing two blank lines + + +You typed two blank lines. Starting a new command. + +scala> // defining and using quoted names should work (ticket #323) + +scala> def `match` = 1 +match: Int + +scala> val x = `match` +x: Int = 1 + +scala> + +scala> // multiple classes defined on one line + +scala> sealed class Exp; class Fact extends Exp; class Term extends Exp +defined class Exp +defined class Fact +defined class Term + +scala> def f(e: Exp) = e match { // non-exhaustive warning here + case _:Fact => 3 +} +:18: warning: match is not exhaustive! +missing combination Exp +missing combination Term + + def f(e: Exp) = e match { // non-exhaustive warning here + ^ +f: (e: Exp)Int + +scala> + +scala> plusOne: (x: Int)Int res0: Int = 6 res0: String = after reset diff --git a/test/files/jvm/interpreter.scala b/test/files/jvm/interpreter.scala index f0bc8b5818..1f289d9335 100644 --- a/test/files/jvm/interpreter.scala +++ b/test/files/jvm/interpreter.scala @@ -2,6 +2,7 @@ import scala.tools.nsc._ import scala.tools.partest.ReplTest object Test extends ReplTest { + override def extraSettings = "-deprecation" def code = // basics 3+4 @@ -29,7 +30,7 @@ val atom = new scala.xml.Atom() class S(override val toString : String) val fish = new S("fish") // Test that arrays pretty print nicely. -val arr = Array("What's", "up", "doc?") +val arr = Array("What's", "up", "doc?") // Test that arrays pretty print nicely, even when we give them type Any val arrInt : Any = Array(1,2,3) // Test that nested arrays are pretty-printed correctly @@ -132,8 +133,8 @@ there // defining and using quoted names should work (ticket #323) -def `match` = 1 -val x = `match` +def `match` = 1 +val x = `match` // multiple classes defined on one line sealed class Exp; class Fact extends Exp; class Term extends Exp @@ -153,6 +154,6 @@ def f(e: Exp) = e match {{ // non-exhaustive warning here interp.interpret("\"after reset\"") interp.interpret("plusOne(5) // should be undefined now") } - + appendix() } diff --git a/test/files/jvm/manifests.check b/test/files/jvm/manifests.check deleted file mode 100644 index 54f504b929..0000000000 --- a/test/files/jvm/manifests.check +++ /dev/null @@ -1,55 +0,0 @@ -x=(), m=Unit -x=true, m=Boolean -x=a, m=Char -x=1, m=Int -x=abc, m=java.lang.String -x='abc, m=scala.Symbol - -x=List(()), m=scala.collection.immutable.List[Unit] -x=List(true), m=scala.collection.immutable.List[Boolean] -x=List(1), m=scala.collection.immutable.List[Int] -x=List(abc), m=scala.collection.immutable.List[java.lang.String] -x=List('abc), m=scala.collection.immutable.List[scala.Symbol] - -x=[Z, m=Array[Boolean] -x=[C, m=Array[Char] -x=[I, m=Array[Int] -x=[Ljava.lang.String;, m=Array[java.lang.String] -x=[Lscala.Symbol;, m=Array[scala.Symbol] - -x=((),()), m=scala.Tuple2[Unit, Unit] -x=(true,false), m=scala.Tuple2[Boolean, Boolean] -x=(1,2), m=scala.Tuple2[Int, Int] -x=(abc,xyz), m=scala.Tuple2[java.lang.String, java.lang.String] -x=('abc,'xyz), m=scala.Tuple2[scala.Symbol, scala.Symbol] - - -x=Foo, m=Foo[Int] -x=Foo, m=Foo[scala.collection.immutable.List[Int]] -x=Foo, m=Foo[Foo[Int]] -x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]] - -x=Test1$$anon$1, m=Object with Bar[java.lang.String] - -()=() -true=true -a=a -1=1 -'abc='abc - -List(())=List(()) -List(true)=List(true) -List('abc)=List('abc) - -Array()=Array() -Array(true)=Array(true) -Array(a)=Array(a) -Array(1)=Array(1) - -((),())=((),()) -(true,false)=(true,false) - -List(List(1), List(2))=List(List(1), List(2)) - -Array(Array(1), Array(2))=Array(Array(1), Array(2)) - diff --git a/test/files/jvm/manifests.check.temporarily.disabled b/test/files/jvm/manifests.check.temporarily.disabled new file mode 100644 index 0000000000..54f504b929 --- /dev/null +++ b/test/files/jvm/manifests.check.temporarily.disabled @@ -0,0 +1,55 @@ +x=(), m=Unit +x=true, m=Boolean +x=a, m=Char +x=1, m=Int +x=abc, m=java.lang.String +x='abc, m=scala.Symbol + +x=List(()), m=scala.collection.immutable.List[Unit] +x=List(true), m=scala.collection.immutable.List[Boolean] +x=List(1), m=scala.collection.immutable.List[Int] +x=List(abc), m=scala.collection.immutable.List[java.lang.String] +x=List('abc), m=scala.collection.immutable.List[scala.Symbol] + +x=[Z, m=Array[Boolean] +x=[C, m=Array[Char] +x=[I, m=Array[Int] +x=[Ljava.lang.String;, m=Array[java.lang.String] +x=[Lscala.Symbol;, m=Array[scala.Symbol] + +x=((),()), m=scala.Tuple2[Unit, Unit] +x=(true,false), m=scala.Tuple2[Boolean, Boolean] +x=(1,2), m=scala.Tuple2[Int, Int] +x=(abc,xyz), m=scala.Tuple2[java.lang.String, java.lang.String] +x=('abc,'xyz), m=scala.Tuple2[scala.Symbol, scala.Symbol] + + +x=Foo, m=Foo[Int] +x=Foo, m=Foo[scala.collection.immutable.List[Int]] +x=Foo, m=Foo[Foo[Int]] +x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]] + +x=Test1$$anon$1, m=Object with Bar[java.lang.String] + +()=() +true=true +a=a +1=1 +'abc='abc + +List(())=List(()) +List(true)=List(true) +List('abc)=List('abc) + +Array()=Array() +Array(true)=Array(true) +Array(a)=Array(a) +Array(1)=Array(1) + +((),())=((),()) +(true,false)=(true,false) + +List(List(1), List(2))=List(List(1), List(2)) + +Array(Array(1), Array(2))=Array(Array(1), Array(2)) + diff --git a/test/files/jvm/manifests.scala b/test/files/jvm/manifests.scala deleted file mode 100644 index 6bbea4d052..0000000000 --- a/test/files/jvm/manifests.scala +++ /dev/null @@ -1,119 +0,0 @@ -object Test extends App { - Test1 - Test2 - //Test3 // Java 1.5+ only -} - -class Foo[T](x: T) -trait Bar[T] { def f: T } - -object Test1 extends TestUtil { - print(()) - print(true) - print('a') - print(1) - print("abc") - print('abc) - println() - - print(List(())) - print(List(true)) - print(List(1)) - print(List("abc")) - print(List('abc)) - println() - - //print(Array(())) //Illegal class name "[V" in class file Test$ - print(Array(true)) - print(Array('a')) - print(Array(1)) - print(Array("abc")) - print(Array('abc)) - println() - - print(((), ())) - print((true, false)) - print((1, 2)) - print(("abc", "xyz")) - print(('abc, 'xyz)) - println() - - // Disabled: should these work? changing the inference for objects from - // "object Test" to "Test.type" drags in a singleton manifest which for - // some reason leads to serialization failure. - // print(Test) - // print(List) - println() - - print(new Foo(2)) - print(new Foo(List(2))) - print(new Foo(new Foo(2))) - print(new Foo(List(new Foo(2)))) - println() - - print(new Bar[String] { def f = "abc" }) - println() -} - -object Test2 { - import scala.util.Marshal._ - println("()="+load[Unit](dump(()))) - println("true="+load[Boolean](dump(true))) - println("a="+load[Char](dump('a'))) - println("1="+load[Int](dump(1))) - println("'abc="+load[Symbol](dump('abc))) - println() - - println("List(())="+load[List[Unit]](dump(List(())))) - println("List(true)="+load[List[Boolean]](dump(List(true)))) - println("List('abc)="+load[List[Symbol]](dump(List('abc)))) - println() - - def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = - load[Array[T]](x)(m).deep.toString - println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) - println("Array(true)="+loadArray[Boolean](dump(Array(true)))) - println("Array(a)="+loadArray[Char](dump(Array('a')))) - println("Array(1)="+loadArray[Int](dump(Array(1)))) - println() - - println("((),())="+load[(Unit, Unit)](dump(((), ())))) - println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) - println() - - println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) - println() - - println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) - println() -} - -object Test3 extends TestUtil { - import scala.reflect.Manifest._ - val ct1 = classType(classOf[Char]) - val ct2 = classType(classOf[List[_]], ct1) - print(ct1) - //print(ct2) // ??? x=scala.List[char], m=scala.reflect.Manifest[scala.runtime.Nothing$] - println() -} - -trait TestUtil { - import java.io._ - def write[A](o: A): Array[Byte] = { - val ba = new ByteArrayOutputStream(512) - val out = new ObjectOutputStream(ba) - out.writeObject(o) - out.close() - ba.toByteArray() - } - def read[A](buffer: Array[Byte]): A = { - val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) - in.readObject().asInstanceOf[A] - } - import scala.reflect._ - def print[T](x: T)(implicit m: Manifest[T]) { - val m1: Manifest[T] = read(write(m)) - val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") - println("x="+x1+", m="+m1) - } -} diff --git a/test/files/jvm/manifests.scala.temporarily.disabled b/test/files/jvm/manifests.scala.temporarily.disabled new file mode 100644 index 0000000000..241966fd9d --- /dev/null +++ b/test/files/jvm/manifests.scala.temporarily.disabled @@ -0,0 +1,109 @@ +object Test extends App { + Test1 + Test2 +} + +class Foo[T](x: T) +trait Bar[T] { def f: T } + +object Test1 extends TestUtil { + print(()) + print(true) + print('a') + print(1) + print("abc") + print('abc) + println() + + print(List(())) + print(List(true)) + print(List(1)) + print(List("abc")) + print(List('abc)) + println() + + //print(Array(())) //Illegal class name "[V" in class file Test$ + print(Array(true)) + print(Array('a')) + print(Array(1)) + print(Array("abc")) + print(Array('abc)) + println() + + print(((), ())) + print((true, false)) + print((1, 2)) + print(("abc", "xyz")) + print(('abc, 'xyz)) + println() + + // Disabled: should these work? changing the inference for objects from + // "object Test" to "Test.type" drags in a singleton manifest which for + // some reason leads to serialization failure. + // print(Test) + // print(List) + println() + + print(new Foo(2)) + print(new Foo(List(2))) + print(new Foo(new Foo(2))) + print(new Foo(List(new Foo(2)))) + println() + + print(new Bar[String] { def f = "abc" }) + println() +} + +object Test2 { + import scala.util.Marshal._ + println("()="+load[Unit](dump(()))) + println("true="+load[Boolean](dump(true))) + println("a="+load[Char](dump('a'))) + println("1="+load[Int](dump(1))) + println("'abc="+load[Symbol](dump('abc))) + println() + + println("List(())="+load[List[Unit]](dump(List(())))) + println("List(true)="+load[List[Boolean]](dump(List(true)))) + println("List('abc)="+load[List[Symbol]](dump(List('abc)))) + println() + + def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = + load[Array[T]](x)(m).deep.toString + println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) + println("Array(true)="+loadArray[Boolean](dump(Array(true)))) + println("Array(a)="+loadArray[Char](dump(Array('a')))) + println("Array(1)="+loadArray[Int](dump(Array(1)))) + println() + + println("((),())="+load[(Unit, Unit)](dump(((), ())))) + println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) + println() + + println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) + println() + + println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) + println() +} + +trait TestUtil { + import java.io._ + def write[A](o: A): Array[Byte] = { + val ba = new ByteArrayOutputStream(512) + val out = new ObjectOutputStream(ba) + out.writeObject(o) + out.close() + ba.toByteArray() + } + def read[A](buffer: Array[Byte]): A = { + val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) + in.readObject().asInstanceOf[A] + } + import scala.reflect._ + def print[T](x: T)(implicit m: Manifest[T]) { + val m1: Manifest[T] = read(write(m)) + val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") + println("x="+x1+", m="+m1) + } +} diff --git a/test/files/macros/Printf.scala b/test/files/macros/Printf.scala deleted file mode 100644 index 4a88e5b069..0000000000 --- a/test/files/macros/Printf.scala +++ /dev/null @@ -1,39 +0,0 @@ -// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work -// 1) first build this file with "scalac -Xmacros Printf.scala" -// 2) the build the test with "scalac -cp Test.scala" - -object Printf extends App { - def macro printf(format: String, params: Any*) : String = { - var i = 0 - def gensym(name: String) = { i += 1; newTermName(name + i) } - - def createTempValDef(value: Tree, clazz: Class[_]): (Option[Tree], Tree) = { - val local = gensym("temp") - val tpe = if (clazz == classOf[Int]) Ident(newTypeName("Int")) - else if (clazz == classOf[String]) Select(Select(Ident(newTermName("java")), newTermName("lang")), newTypeName("String")) - else throw new Exception("unknown class " + clazz.toString) - (Some(ValDef(Modifiers(), local, tpe, value)), Ident(local)) - } - - def tree_printf(format: Tree, params: Tree*) = { - val Literal(Constant(s_format: String)) = format - val paramsStack = scala.collection.mutable.Stack(params: _*) - val parsed = s_format.split("(?<=%[\\w%])|(?=%[\\w%])") map { - case "%d" => createTempValDef(paramsStack.pop, classOf[Int]) - case "%s" => createTempValDef(paramsStack.pop, classOf[String]) - case "%%" => (None, Literal(Constant("%"))) - case part => (None, Literal(Constant(part))) - } - - val evals = for ((Some(eval), _) <- parsed if eval != None) yield eval - val prints = for ((_, ref) <- parsed) yield { - val print = Select(Select(Ident(newTermName("scala")), newTermName("Predef")), newTermName("print")) - Apply(print, List(ref)) - } - - Block((evals ++ prints).toList, Literal(Constant(()))) - } - - tree_printf(format, params: _*) - } -} diff --git a/test/files/macros/Test.scala b/test/files/macros/Test.scala deleted file mode 100644 index d8cdcf6756..0000000000 --- a/test/files/macros/Test.scala +++ /dev/null @@ -1,8 +0,0 @@ -// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work -// 1) first build the printf macro with "scalac -Xmacros Printf.scala" -// 2) the build this file with "scalac -cp Test.scala" - -object Test extends App { - import Printf._ - printf("hello %s", "world") -} \ No newline at end of file diff --git a/test/files/macros/macros_v0001.bat b/test/files/macros/macros_v0001.bat deleted file mode 100644 index 3395d2e3c1..0000000000 --- a/test/files/macros/macros_v0001.bat +++ /dev/null @@ -1,40 +0,0 @@ -@echo off - -set scalahome=%~dp0\..\..\.. -set scaladeps=%scalahome%\lib\jline.jar;%scalahome%\lib\fjbg.jar -set scalalib=%scalahome%\build\pack\lib\scala-library.jar -if not exist "%scalalib%" set scalalib=%scalahome%\build\locker\classes\library -set scalacomp="%scalahome%\build\pack\lib\scala-compiler.jar" -if not exist "%scalacomp%" set scalacomp=%scalahome%\build\locker\classes\compiler -set stdcp=%scaladeps%;%scalalib%;%scalacomp% - -echo Compiling macros... -set cp=%stdcp% -call :scalac -Xmacros "%~dp0\Printf.scala" - -echo Compiling the program... -set cp=%stdcp%;%~dp0. -call :scalac "%~dp0\Test.scala" - -echo. -echo NOW LOOK!!! -echo =============================================== -set cp=%stdcp%;%~dp0. -call :scala Test -echo. -echo =============================================== -goto :eof - -:scalac -setlocal -call set args=%* -rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args% -java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args% -endlocal&goto :eof - -:scala -setlocal -call set args=%* -rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args% -java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args% -endlocal&goto :eof diff --git a/test/files/macros/macros_v0001.sh b/test/files/macros/macros_v0001.sh deleted file mode 100644 index abe09836bb..0000000000 --- a/test/files/macros/macros_v0001.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -set -o errexit - -if [[ $(uname -s) == CYGWIN* ]]; then cpsep=";"; else cpsep=":"; fi -scripthome="$(dirname "$0")" -scalahome="$scripthome/../../.." -scaladeps="$scalahome/lib/jline.jar;$scalahome/lib/fjbg.jar" -scalalib="$scalahome/build/pack/lib/scala-library.jar" -if [ ! -f "$scalalib" ]; then scalalib="$scalahome/build/locker/classes/library"; fi -scalacomp="$scalahome/build/pack/lib/scala-compiler.jar" -if [ ! -f "$scalacomp" ]; then scalacomp="$scalahome/build/locker/classes/compiler"; fi -stdcp="$scaladeps$cpsep$scalalib$cpsep$scalacomp" -function scalac { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.Main $*; } -function scala { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner $*; } - -echo "Compiling macros..." -cp="$stdcp" -scalac -Xmacros "$scripthome/Printf.scala" - -echo "Compiling the program..." -cp="$stdcp$cpsep$scripthome" -scalac "$scripthome/Test.scala" - -echo "" -echo "NOW LOOK" -echo "===============================================" -cp="$stdcp$cpsep$scripthome" -scala Test -echo "" -echo "===============================================" diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check index d785179a56..23af94180a 100644 --- a/test/files/neg/checksensible.check +++ b/test/files/neg/checksensible.check @@ -1,100 +1,100 @@ -checksensible.scala:13: error: comparing a fresh object using `eq' will always yield false - (new AnyRef) eq (new AnyRef) - ^ -checksensible.scala:14: error: comparing a fresh object using `ne' will always yield true - (new AnyRef) ne (new AnyRef) - ^ -checksensible.scala:15: error: comparing a fresh object using `eq' will always yield false - Shmoopie eq (new AnyRef) - ^ -checksensible.scala:16: error: comparing a fresh object using `eq' will always yield false - (Shmoopie: AnyRef) eq (new AnyRef) - ^ -checksensible.scala:17: error: comparing a fresh object using `eq' will always yield false - (new AnyRef) eq Shmoopie - ^ -checksensible.scala:18: error: comparing a fresh object using `eq' will always yield false - (new AnyRef) eq null - ^ -checksensible.scala:19: error: comparing a fresh object using `eq' will always yield false - null eq new AnyRef - ^ -checksensible.scala:26: error: comparing values of types Unit and Int using `==' will always yield false - (c = 1) == 0 - ^ -checksensible.scala:27: error: comparing values of types Int and Unit using `==' will always yield false - 0 == (c = 1) - ^ -checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false - 1 == "abc" - ^ -checksensible.scala:33: error: comparing values of types Some[Int] and Int using `==' will always yield false - Some(1) == 1 // as above - ^ -checksensible.scala:38: error: comparing a fresh object using `==' will always yield false - new AnyRef == 1 - ^ -checksensible.scala:41: error: comparing values of types Int and Boolean using `==' will always yield false - 1 == (new java.lang.Boolean(true)) - ^ -checksensible.scala:43: error: comparing values of types Int and Boolean using `!=' will always yield true - 1 != true - ^ -checksensible.scala:44: error: comparing values of types Unit and Boolean using `==' will always yield false - () == true - ^ -checksensible.scala:45: error: comparing values of types Unit and Unit using `==' will always yield true - () == () - ^ -checksensible.scala:46: error: comparing values of types Unit and Unit using `==' will always yield true - () == println - ^ -checksensible.scala:47: error: comparing values of types Unit and scala.runtime.BoxedUnit using `==' will always yield true - () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false - ^ -checksensible.scala:48: error: comparing values of types scala.runtime.BoxedUnit and Unit using `!=' will always yield false - scala.runtime.BoxedUnit.UNIT != () - ^ -checksensible.scala:51: error: comparing values of types Int and Unit using `!=' will always yield true - (1 != println) - ^ -checksensible.scala:52: error: comparing values of types Int and Symbol using `!=' will always yield true - (1 != 'sym) - ^ -checksensible.scala:58: error: comparing a fresh object using `==' will always yield false - ((x: Int) => x + 1) == null - ^ -checksensible.scala:59: error: comparing a fresh object using `==' will always yield false - Bep == ((_: Int) + 1) - ^ -checksensible.scala:61: error: comparing a fresh object using `==' will always yield false - new Object == new Object - ^ -checksensible.scala:62: error: comparing a fresh object using `==' will always yield false - new Object == "abc" - ^ -checksensible.scala:63: error: comparing a fresh object using `!=' will always yield true - new Exception() != new Exception() - ^ -checksensible.scala:66: error: comparing values of types Int and Null using `==' will always yield false - if (foo.length == null) "plante" else "plante pas" - ^ -checksensible.scala:71: error: comparing values of types Bip and Bop using `==' will always yield false - (x1 == x2) - ^ -checksensible.scala:81: error: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==' will always yield false - c3 == z1 - ^ -checksensible.scala:82: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `==' will always yield false - z1 == c3 - ^ -checksensible.scala:83: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `!=' will always yield true - z1 != c3 - ^ -checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and String using `!=' will always yield true - c3 != "abc" - ^ -checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true - while ((c = in.read) != -1) - ^ -33 errors found +checksensible.scala:13: error: comparing a fresh object using `eq' will always yield false + (new AnyRef) eq (new AnyRef) + ^ +checksensible.scala:14: error: comparing a fresh object using `ne' will always yield true + (new AnyRef) ne (new AnyRef) + ^ +checksensible.scala:15: error: comparing a fresh object using `eq' will always yield false + Shmoopie eq (new AnyRef) + ^ +checksensible.scala:16: error: comparing a fresh object using `eq' will always yield false + (Shmoopie: AnyRef) eq (new AnyRef) + ^ +checksensible.scala:17: error: comparing a fresh object using `eq' will always yield false + (new AnyRef) eq Shmoopie + ^ +checksensible.scala:18: error: comparing a fresh object using `eq' will always yield false + (new AnyRef) eq null + ^ +checksensible.scala:19: error: comparing a fresh object using `eq' will always yield false + null eq new AnyRef + ^ +checksensible.scala:26: error: comparing values of types Unit and Int using `==' will always yield false + (c = 1) == 0 + ^ +checksensible.scala:27: error: comparing values of types Int and Unit using `==' will always yield false + 0 == (c = 1) + ^ +checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false + 1 == "abc" + ^ +checksensible.scala:33: error: comparing values of types Some[Int] and Int using `==' will always yield false + Some(1) == 1 // as above + ^ +checksensible.scala:38: error: comparing a fresh object using `==' will always yield false + new AnyRef == 1 + ^ +checksensible.scala:41: error: comparing values of types Int and Boolean using `==' will always yield false + 1 == (new java.lang.Boolean(true)) + ^ +checksensible.scala:43: error: comparing values of types Int and Boolean using `!=' will always yield true + 1 != true + ^ +checksensible.scala:44: error: comparing values of types Unit and Boolean using `==' will always yield false + () == true + ^ +checksensible.scala:45: error: comparing values of types Unit and Unit using `==' will always yield true + () == () + ^ +checksensible.scala:46: error: comparing values of types Unit and Unit using `==' will always yield true + () == println + ^ +checksensible.scala:47: error: comparing values of types Unit and scala.runtime.BoxedUnit using `==' will always yield true + () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false + ^ +checksensible.scala:48: error: comparing values of types scala.runtime.BoxedUnit and Unit using `!=' will always yield false + scala.runtime.BoxedUnit.UNIT != () + ^ +checksensible.scala:51: error: comparing values of types Int and Unit using `!=' will always yield true + (1 != println) + ^ +checksensible.scala:52: error: comparing values of types Int and Symbol using `!=' will always yield true + (1 != 'sym) + ^ +checksensible.scala:58: error: comparing a fresh object using `==' will always yield false + ((x: Int) => x + 1) == null + ^ +checksensible.scala:59: error: comparing a fresh object using `==' will always yield false + Bep == ((_: Int) + 1) + ^ +checksensible.scala:61: error: comparing a fresh object using `==' will always yield false + new Object == new Object + ^ +checksensible.scala:62: error: comparing a fresh object using `==' will always yield false + new Object == "abc" + ^ +checksensible.scala:63: error: comparing a fresh object using `!=' will always yield true + new Exception() != new Exception() + ^ +checksensible.scala:66: error: comparing values of types Int and Null using `==' will always yield false + if (foo.length == null) "plante" else "plante pas" + ^ +checksensible.scala:71: error: comparing values of types Bip and Bop using `==' will always yield false + (x1 == x2) + ^ +checksensible.scala:81: error: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==' will always yield false + c3 == z1 + ^ +checksensible.scala:82: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `==' will always yield false + z1 == c3 + ^ +checksensible.scala:83: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `!=' will always yield true + z1 != c3 + ^ +checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and String using `!=' will always yield true + c3 != "abc" + ^ +checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true + while ((c = in.read) != -1) + ^ +33 errors found diff --git a/test/files/neg/classtags_contextbound_a.check b/test/files/neg/classtags_contextbound_a.check new file mode 100644 index 0000000000..f4b6ff5af1 --- /dev/null +++ b/test/files/neg/classtags_contextbound_a.check @@ -0,0 +1,4 @@ +classtags_contextbound_a.scala:2: error: No ClassTag available for T + def foo[T] = Array[T]() + ^ +one error found diff --git a/test/files/neg/classtags_contextbound_a.scala b/test/files/neg/classtags_contextbound_a.scala new file mode 100644 index 0000000000..d18beda341 --- /dev/null +++ b/test/files/neg/classtags_contextbound_a.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[T] = Array[T]() + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/neg/classtags_contextbound_b.check b/test/files/neg/classtags_contextbound_b.check new file mode 100644 index 0000000000..f1f48bed72 --- /dev/null +++ b/test/files/neg/classtags_contextbound_b.check @@ -0,0 +1,4 @@ +classtags_contextbound_b.scala:3: error: No ClassTag available for T + def foo[T] = mkArray[T] + ^ +one error found diff --git a/test/files/neg/classtags_contextbound_b.scala b/test/files/neg/classtags_contextbound_b.scala new file mode 100644 index 0000000000..3247a8ff29 --- /dev/null +++ b/test/files/neg/classtags_contextbound_b.scala @@ -0,0 +1,5 @@ +object Test extends App { + def mkArray[T: ClassTag] = Array[T]() + def foo[T] = mkArray[T] + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/neg/classtags_contextbound_c.check b/test/files/neg/classtags_contextbound_c.check new file mode 100644 index 0000000000..54f630862a --- /dev/null +++ b/test/files/neg/classtags_contextbound_c.check @@ -0,0 +1,4 @@ +classtags_contextbound_c.scala:2: error: No ClassTag available for T + def mkArray[T] = Array[T]() + ^ +one error found diff --git a/test/files/neg/classtags_contextbound_c.scala b/test/files/neg/classtags_contextbound_c.scala new file mode 100644 index 0000000000..0b63f8407e --- /dev/null +++ b/test/files/neg/classtags_contextbound_c.scala @@ -0,0 +1,5 @@ +object Test extends App { + def mkArray[T] = Array[T]() + def foo[T: ClassTag] = mkArray[T] + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/neg/macro-argtype-mismatch/Macros_1.scala b/test/files/neg/macro-argtype-mismatch/Macros_1.scala deleted file mode 100644 index 4b5f98ba37..0000000000 --- a/test/files/neg/macro-argtype-mismatch/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo(x: Int) = x -} \ No newline at end of file diff --git a/test/files/neg/macro-argtype-mismatch/Test_2.scala b/test/files/neg/macro-argtype-mismatch/Test_2.scala deleted file mode 100644 index 18feb69425..0000000000 --- a/test/files/neg/macro-argtype-mismatch/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo("2") -} \ No newline at end of file diff --git a/test/files/neg/macro-basic-mamdmi.check b/test/files/neg/macro-basic-mamdmi.check new file mode 100644 index 0000000000..eef444f7b3 --- /dev/null +++ b/test/files/neg/macro-basic-mamdmi.check @@ -0,0 +1,5 @@ +Impls_Macros_Test_1.scala:36: error: macro implementation not found: foo (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) +if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath in the second phase pointing to the output of the first phase + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) + ^ +one error found diff --git a/test/files/neg/macro-basic-mamdmi.flags b/test/files/neg/macro-basic-mamdmi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/neg/macro-basic-mamdmi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala b/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala new file mode 100644 index 0000000000..e9876e32e9 --- /dev/null +++ b/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala @@ -0,0 +1,37 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} + +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/macro-cyclic.check b/test/files/neg/macro-cyclic.check new file mode 100644 index 0000000000..608381e0e8 --- /dev/null +++ b/test/files/neg/macro-cyclic.check @@ -0,0 +1,4 @@ +Impls_Macros_1.scala:5: error: could not find implicit value for parameter e: SourceLocation + c.reify { implicitly[SourceLocation] } + ^ +one error found diff --git a/test/files/neg/macro-cyclic.flags b/test/files/neg/macro-cyclic.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-cyclic.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-cyclic/Impls_Macros_1.scala b/test/files/neg/macro-cyclic/Impls_Macros_1.scala new file mode 100644 index 0000000000..1ea06fc968 --- /dev/null +++ b/test/files/neg/macro-cyclic/Impls_Macros_1.scala @@ -0,0 +1,25 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context) = { + c.reify { implicitly[SourceLocation] } + } + + implicit def sourceLocation: SourceLocation1 = macro impl +} + +trait SourceLocation { + /** Source location of the outermost call */ + val outer: SourceLocation + + /** The name of the source file */ + val fileName: String + + /** The line number */ + val line: Int + + /** The character offset */ + val charOffset: Int +} + +case class SourceLocation1(val outer: SourceLocation, val fileName: String, val line: Int, val charOffset: Int) extends SourceLocation diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check new file mode 100644 index 0000000000..c97be5d9f6 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check @@ -0,0 +1,14 @@ +Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro` + ^ +Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro`.bar + ^ +Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro`.foo + ^ +Main.scala:2: error: Unmatched closing brace '}' ignored here +} +^ +three warnings found +one error found diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala new file mode 100644 index 0000000000..97c07b04a0 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(`macro`) = Some(42) + `macro` match { + case `macro` => println(`macro`) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala new file mode 100644 index 0000000000..f0037b5f82 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala new file mode 100644 index 0000000000..a6d0903cbb --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala new file mode 100644 index 0000000000..6af8e1d65e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def `macro` = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala new file mode 100644 index 0000000000..29dab017d2 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala new file mode 100644 index 0000000000..6cbcac55ca --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala new file mode 100644 index 0000000000..4985d6691e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package `macro` + +package `macro`.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala new file mode 100644 index 0000000000..35ed610637 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package `macro`.foo diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala new file mode 100644 index 0000000000..7895cf9a43 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala new file mode 100644 index 0000000000..90ba2207b7 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala new file mode 100644 index 0000000000..7a2196c9cd --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type `macro` = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala new file mode 100644 index 0000000000..9ad08b8ba0 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val `macro` = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala new file mode 100644 index 0000000000..4fbe152e76 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var `macro` = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala new file mode 100644 index 0000000000..f5278d9e7e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala @@ -0,0 +1,2 @@ +object Test extends App +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check new file mode 100644 index 0000000000..5fa1dc84d0 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.check @@ -0,0 +1,50 @@ +Macros_Bind_12.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + val Some(macro) = Some(42) + ^ +Macros_Bind_12.scala:4: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + case macro => println(macro) + ^ +Macros_Class_4.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +class macro + ^ +Macros_Class_5.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro + ^ +Macros_Def_13.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + def macro = 2 + ^ +Macros_Object_6.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +object macro + ^ +Macros_Object_7.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro + ^ +Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro.bar + ^ +Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro.foo + ^ +Macros_Trait_8.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +trait macro + ^ +Macros_Trait_9.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro + ^ +Macros_Type_3.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + type macro = Int + ^ +Macros_Val_1.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + val macro = ??? + ^ +Macros_Var_2.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + var macro = ??? + ^ +Main.scala:2: error: Unmatched closing brace '}' ignored here +} +^ +15 warnings found +one error found diff --git a/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala new file mode 100644 index 0000000000..f4e25bfdfc --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Main.scala b/test/files/neg/macro-deprecate-idents/Main.scala new file mode 100644 index 0000000000..f5278d9e7e --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Main.scala @@ -0,0 +1,2 @@ +object Test extends App +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-a.check b/test/files/neg/macro-invalidimpl-a.check new file mode 100644 index 0000000000..855fe2d169 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-a.flags b/test/files/neg/macro-invalidimpl-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-a/Impls_1.scala b/test/files/neg/macro-invalidimpl-a/Impls_1.scala new file mode 100644 index 0000000000..c2f1843b8b --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +class Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala new file mode 100644 index 0000000000..2220ddae0c --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + val impls = new Impls + def foo(x: Any) = macro impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b.check b/test/files/neg/macro-invalidimpl-b.check new file mode 100644 index 0000000000..855fe2d169 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-b.flags b/test/files/neg/macro-invalidimpl-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b/Impls_1.scala b/test/files/neg/macro-invalidimpl-b/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala new file mode 100644 index 0000000000..81e40837d2 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + val impls = Impls + def foo(x: Any) = macro impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c.check b/test/files/neg/macro-invalidimpl-c.check new file mode 100644 index 0000000000..722ec3c7bd --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c.check @@ -0,0 +1,4 @@ +Impls_Macros_1.scala:8: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-c.flags b/test/files/neg/macro-invalidimpl-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala new file mode 100644 index 0000000000..657e2d4260 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +class Macros { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? + } + + def foo(x: Any) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c/Test_2.scala b/test/files/neg/macro-invalidimpl-c/Test_2.scala new file mode 100644 index 0000000000..e75a8ba101 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + new Macros().foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d.check b/test/files/neg/macro-invalidimpl-d.check new file mode 100644 index 0000000000..6fedfa74fc --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: macro implementation must be in statically accessible object + def foo(x: Any) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-d.flags b/test/files/neg/macro-invalidimpl-d.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d/Impls_1.scala b/test/files/neg/macro-invalidimpl-d/Impls_1.scala new file mode 100644 index 0000000000..f18e699a1e --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d/Impls_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.makro.{Context => Ctx} + +trait MacroHelpers { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = x + } +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala new file mode 100644 index 0000000000..067ab1ddec --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala @@ -0,0 +1,7 @@ +class Macros extends MacroHelpers { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + println(new Macros().foo(42)) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e.check b/test/files/neg/macro-invalidimpl-e.check new file mode 100644 index 0000000000..61d1e05b87 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e.check @@ -0,0 +1,13 @@ +Macros_Test_2.scala:2: error: ambiguous reference to overloaded definition, +both method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any) = macro Impls.foo + ^ +Macros_Test_2.scala:3: error: ambiguous reference to overloaded definition, +both method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any, y: Any) = macro Impls.foo + ^ +two errors found diff --git a/test/files/neg/macro-invalidimpl-e.flags b/test/files/neg/macro-invalidimpl-e.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e/Impls_1.scala b/test/files/neg/macro-invalidimpl-e/Impls_1.scala new file mode 100644 index 0000000000..ad3eed5cd5 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e/Impls_1.scala @@ -0,0 +1,6 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? + def foo(c: Ctx)(x: c.Expr[Any], y: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala new file mode 100644 index 0000000000..6edde08167 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + def foo(x: Any) = macro Impls.foo + def foo(x: Any, y: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f.check b/test/files/neg/macro-invalidimpl-f.check new file mode 100644 index 0000000000..ec82faa58c --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(): c.Expr[Unit] + found : (c: scala.reflect.makro.Context): c.Expr[Unit] +number of parameter sections differ + def bar1() = macro Impls.fooNullary + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-f.flags b/test/files/neg/macro-invalidimpl-f.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f/Impls_1.scala b/test/files/neg/macro-invalidimpl-f/Impls_1.scala new file mode 100644 index 0000000000..06c6efbb1f --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def fooNullary(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooEmpty(c: Ctx)() = fooNullary(c) +} diff --git a/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala new file mode 100644 index 0000000000..493edf1df8 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + def bar1() = macro Impls.fooNullary +} + +object Test extends App { + Macros.bar1 + Macros.bar1() + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g.check b/test/files/neg/macro-invalidimpl-g.check new file mode 100644 index 0000000000..9c01f01dc8 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Unit] + found : (c: scala.reflect.makro.Context)(): c.Expr[Unit] +number of parameter sections differ + def foo1 = macro Impls.fooEmpty + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-g.flags b/test/files/neg/macro-invalidimpl-g.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g/Impls_1.scala b/test/files/neg/macro-invalidimpl-g/Impls_1.scala new file mode 100644 index 0000000000..06c6efbb1f --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def fooNullary(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooEmpty(c: Ctx)() = fooNullary(c) +} diff --git a/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala new file mode 100644 index 0000000000..5561db9f9a --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo1 = macro Impls.fooEmpty +} + +object Test extends App { + Macros.foo1 + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h.check b/test/files/neg/macro-invalidimpl-h.check new file mode 100644 index 0000000000..cc7fc794d3 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int] + def foo = macro Impls.foo[String] + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-h.flags b/test/files/neg/macro-invalidimpl-h.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h/Impls_1.scala b/test/files/neg/macro-invalidimpl-h/Impls_1.scala new file mode 100644 index 0000000000..7db8bcd324 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: Int](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala new file mode 100644 index 0000000000..218c7aec7f --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo[String] +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree.check b/test/files/neg/macro-invalidret-nontree.check new file mode 100644 index 0000000000..7fcc396463 --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.makro.Context): Int +type mismatch for return type : c.Expr[Any] does not conform to Int + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidret-nontree.flags b/test/files/neg/macro-invalidret-nontree.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree/Impls_1.scala b/test/files/neg/macro-invalidret-nontree/Impls_1.scala new file mode 100644 index 0000000000..efc8d4bfec --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = 2 +} diff --git a/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree.check b/test/files/neg/macro-invalidret-nonuniversetree.check new file mode 100644 index 0000000000..a97d6daaa9 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.makro.Context): reflect.mirror.Literal +type mismatch for return type : c.Expr[Any] does not conform to reflect.mirror.Literal + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidret-nonuniversetree.flags b/test/files/neg/macro-invalidret-nonuniversetree.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala new file mode 100644 index 0000000000..86b7c8d8d0 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = scala.reflect.mirror.Literal(scala.reflect.mirror.Constant(42)) +} diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a.check b/test/files/neg/macro-invalidshape-a.check new file mode 100644 index 0000000000..246b5c3226 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:2: error: macro body has wrong shape: + required: macro . + or : macro + def foo(x: Any) = macro 2 + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-a.flags b/test/files/neg/macro-invalidshape-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a/Impls_1.scala b/test/files/neg/macro-invalidshape-a/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala new file mode 100644 index 0000000000..ffff17d1e7 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro 2 +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b.check b/test/files/neg/macro-invalidshape-b.check new file mode 100644 index 0000000000..59701d023b --- /dev/null +++ b/test/files/neg/macro-invalidshape-b.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:2: error: macro body has wrong shape: + required: macro . + or : macro + def foo(x: Any) = macro Impls.foo(null)(null) + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-b.flags b/test/files/neg/macro-invalidshape-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b/Impls_1.scala b/test/files/neg/macro-invalidshape-b/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-b/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala new file mode 100644 index 0000000000..b67cd32a6e --- /dev/null +++ b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo(null)(null) +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c.check b/test/files/neg/macro-invalidshape-c.check new file mode 100644 index 0000000000..84d8c35222 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:2: error: macro body has wrong shape: + required: macro . + or : macro + def foo(x: Any) = macro {2; Impls.foo} + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-c.flags b/test/files/neg/macro-invalidshape-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c/Impls_1.scala b/test/files/neg/macro-invalidshape-c/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala new file mode 100644 index 0000000000..552c3710c7 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro {2; Impls.foo} +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d.check b/test/files/neg/macro-invalidshape-d.check new file mode 100644 index 0000000000..031aa653ab --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: illegal start of statement + def foo(x: Any) = {2; macro Impls.foo} + ^ +one error found diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d/Impls_1.scala b/test/files/neg/macro-invalidshape-d/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-invalidshape-d/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala new file mode 100644 index 0000000000..bacd9a6e7c --- /dev/null +++ b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = {2; macro Impls.foo} +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds.check b/test/files/neg/macro-invalidsig-context-bounds.check new file mode 100644 index 0000000000..dd68e5db1b --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds.check @@ -0,0 +1,4 @@ +Impls_1.scala:4: error: macro implementations cannot have implicit parameters other than TypeTag evidences + def foo[U: c.TypeTag: Numeric](c: Ctx) = { + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-context-bounds.flags b/test/files/neg/macro-invalidsig-context-bounds.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala new file mode 100644 index 0000000000..2eb2ab3947 --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag: Numeric](c: Ctx) = { + import c.mirror._ + Literal(Constant(42)) + } +} diff --git a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala new file mode 100644 index 0000000000..5b4602f328 --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + println(foo[String]) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badargc.check b/test/files/neg/macro-invalidsig-ctx-badargc.check new file mode 100644 index 0000000000..1e1621ab61 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : : Nothing +number of parameter sections differ + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-badargc.flags b/test/files/neg/macro-invalidsig-ctx-badargc.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala new file mode 100644 index 0000000000..da28944d27 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.api.{Mirror => Ctx} + +object Impls { + def foo = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badtype.check b/test/files/neg/macro-invalidsig-ctx-badtype.check new file mode 100644 index 0000000000..3913a8e3cb --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.api.Mirror): Nothing +type mismatch for parameter c: scala.reflect.makro.Context does not conform to scala.reflect.api.Mirror + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-badtype.flags b/test/files/neg/macro-invalidsig-ctx-badtype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala new file mode 100644 index 0000000000..747a2e9ca8 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.api.{Mirror => Ctx} + +object Impls { + def foo(c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs.check b/test/files/neg/macro-invalidsig-ctx-badvarargs.check new file mode 100644 index 0000000000..18e3d6201f --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (cs: scala.reflect.makro.Context*): Nothing +types incompatible for parameter cs: corresponding is not a vararg parameter + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs.flags b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala new file mode 100644 index 0000000000..b2fb2539ec --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(cs: Ctx*) = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-noctx.check b/test/files/neg/macro-invalidsig-ctx-noctx.check new file mode 100644 index 0000000000..66fa7c3514 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Any]): c.Expr[Any] + found : (c: scala.reflect.makro.Context): Nothing +number of parameter sections differ + def foo(x: Any) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-ctx-noctx.flags b/test/files/neg/macro-invalidsig-ctx-noctx.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala new file mode 100644 index 0000000000..1e0ed755af --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala new file mode 100644 index 0000000000..e053cf99df --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params.check b/test/files/neg/macro-invalidsig-implicit-params.check new file mode 100644 index 0000000000..0dd1c27b50 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params.check @@ -0,0 +1,4 @@ +Impls_Macros_1.scala:4: error: macro implementations cannot have implicit parameters other than TypeTag evidences + def foo_targs[T, U: c.TypeTag](c: Ctx)(implicit x: c.Expr[Int]) = { + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-implicit-params.flags b/test/files/neg/macro-invalidsig-implicit-params.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala new file mode 100644 index 0000000000..662ad2ab52 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_targs[T, U: c.TypeTag](c: Ctx)(implicit x: c.Expr[Int]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Block( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.tpe)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + implicitly[c.TypeTag[U]].tpe)))), + Literal(Constant(()))) + Expr[Unit](body) + } +} + +class Macros[T] { + def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U] +} diff --git a/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala new file mode 100644 index 0000000000..90e850df21 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println("foo_targs:") + new Macros[Int]().foo_targs[String](42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badargc.check b/test/files/neg/macro-invalidsig-params-badargc.check new file mode 100644 index 0000000000..6de8c5e95a --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): Nothing +parameter lists have different length, found extra parameter y: c.Expr[Int] + def foo(x: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-badargc.flags b/test/files/neg/macro-invalidsig-params-badargc.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala new file mode 100644 index 0000000000..4b449f35ed --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = ??? +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype.check b/test/files/neg/macro-invalidsig-params-badtype.check new file mode 100644 index 0000000000..71a65aec84 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(x: c.mirror.Tree): Nothing +type mismatch for parameter x: c.Expr[Int] does not conform to c.mirror.Tree + def foo(x: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-badtype.flags b/test/files/neg/macro-invalidsig-params-badtype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala new file mode 100644 index 0000000000..29220c1c82 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.mirror.Tree) = ??? +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badvarargs.check b/test/files/neg/macro-invalidsig-params-badvarargs.check new file mode 100644 index 0000000000..0827680299 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(xs: c.Expr[Int]*): Nothing +parameter lists have different length, required extra parameter y: c.Expr[Int] + def foo(x: Int, y: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-badvarargs.flags b/test/files/neg/macro-invalidsig-params-badvarargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala new file mode 100644 index 0000000000..2ee1c2767c --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = ??? +} + +object Macros { + def foo(x: Int, y: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.check b/test/files/neg/macro-invalidsig-params-namemismatch.check new file mode 100644 index 0000000000..ca7270cca8 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch.check @@ -0,0 +1,7 @@ +Impls_Macros_1.scala:8: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(y: c.Expr[Int], x: c.Expr[Int]): Nothing +parameter names differ: x != y + def foo(x: Int, y: Int) = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.flags b/test/files/neg/macro-invalidsig-params-namemismatch.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala new file mode 100644 index 0000000000..89c5347647 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(y: c.Expr[Int], x: c.Expr[Int]) = ??? +} + +object Macros { + def foo(x: Int, y: Int) = macro Impls.foo +} diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-badtype.check b/test/files/neg/macro-invalidsig-tparams-badtype.check new file mode 100644 index 0000000000..bd1acc4a0a --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype.check @@ -0,0 +1,7 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.makro.Context): c.Expr[Any] + found : (c: scala.reflect.makro.Context)(U: c.mirror.Type): Nothing +number of parameter sections differ + def foo[U] = macro Impls.foo[U] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-badtype.flags b/test/files/neg/macro-invalidsig-tparams-badtype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala new file mode 100644 index 0000000000..b43251df33 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U](c: Ctx)(U: c.mirror.Type) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala new file mode 100644 index 0000000000..a82e813221 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a.check b/test/files/neg/macro-invalidsig-tparams-bounds-a.check new file mode 100644 index 0000000000..6ba80b45c0 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U] = macro Impls.foo[U] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a.flags b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala new file mode 100644 index 0000000000..88b85d48f4 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala new file mode 100644 index 0000000000..a82e813221 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b.check b/test/files/neg/macro-invalidsig-tparams-bounds-b.check new file mode 100644 index 0000000000..50f0944acc --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U <: Int] = macro Impls.foo[U] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b.flags b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala new file mode 100644 index 0000000000..88b85d48f4 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala new file mode 100644 index 0000000000..eed6369a16 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U <: Int] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a.check b/test/files/neg/macro-invalidsig-tparams-notparams-a.check new file mode 100644 index 0000000000..5b4ef42ea5 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: macro implementation reference needs type arguments + def foo = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a.flags b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala new file mode 100644 index 0000000000..bbe5b4e519 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala new file mode 100644 index 0000000000..96a8de2832 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b.check b/test/files/neg/macro-invalidsig-tparams-notparams-b.check new file mode 100644 index 0000000000..261e3b8293 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: macro implementation reference needs type arguments + def foo[V] = macro Impls.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b.flags b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala new file mode 100644 index 0000000000..7bc46ff876 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T: c.TypeTag, U: c.TypeTag, V](c: Ctx)(implicit V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + println(implicitly[c.TypeTag[T]]) + println(implicitly[c.TypeTag[U]]) + println(V) + Literal(Constant(())) + } +} diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala new file mode 100644 index 0000000000..7d02bf613a --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala @@ -0,0 +1,11 @@ +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo + } +} + +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c.check b/test/files/neg/macro-invalidsig-tparams-notparams-c.check new file mode 100644 index 0000000000..b64a469cc3 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.makro.Context)(implicit evidence$1: c.TypeTag[T], implicit evidence$2: c.TypeTag[U], implicit V: c.TypeTag[V])c.Expr[Unit] + def foo[V] = macro Impls.foo[V] + ^ +one error found diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c.flags b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala new file mode 100644 index 0000000000..7bc46ff876 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T: c.TypeTag, U: c.TypeTag, V](c: Ctx)(implicit V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + println(implicitly[c.TypeTag[T]]) + println(implicitly[c.TypeTag[U]]) + println(V) + Literal(Constant(())) + } +} diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala new file mode 100644 index 0000000000..109e142e52 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala @@ -0,0 +1,11 @@ +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[V] + } +} + +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check new file mode 100644 index 0000000000..52beda5b61 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs.check @@ -0,0 +1,6 @@ +Macros_Test_2.scala:7: error: type mismatch; + found : String("42") + required: Int + val s: String = foo("42") + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-badargs.flags b/test/files/neg/macro-invalidusage-badargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badargs/Impls_1.scala b/test/files/neg/macro-invalidusage-badargs/Impls_1.scala new file mode 100644 index 0000000000..2346a6106d --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} diff --git a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala new file mode 100644 index 0000000000..a6af1bb277 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Int) = macro Impls.foo +} + +object Test extends App { + import Macros._ + val s: String = foo("42") +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds.check b/test/files/neg/macro-invalidusage-badbounds.check new file mode 100644 index 0000000000..fd0b64533e --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:7: error: type arguments [Int] do not conform to macro method foo's type parameter bounds [U <: String] + foo[Int] + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-badbounds.flags b/test/files/neg/macro-invalidusage-badbounds.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala new file mode 100644 index 0000000000..88b85d48f4 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx) = ??? +} diff --git a/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala new file mode 100644 index 0000000000..3139599108 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U <: String] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badtargs.check b/test/files/neg/macro-invalidusage-badtargs.check new file mode 100644 index 0000000000..61ef6f5af7 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:7: error: macro method foo: (x: Int)Int does not take type parameters. + val s: String = foo[String](42) + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-badtargs.flags b/test/files/neg/macro-invalidusage-badtargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala b/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala new file mode 100644 index 0000000000..2346a6106d --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} diff --git a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala new file mode 100644 index 0000000000..c54093b637 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Int) = macro Impls.foo +} + +object Test extends App { + import Macros._ + val s: String = foo[String](42) +} \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax.check b/test/files/neg/macro-invalidusage-methodvaluesyntax.check new file mode 100644 index 0000000000..27b2023202 --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:6: error: macros cannot be eta-expanded + val firstClassFoo = Macros.foo _ + ^ +one error found diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax.flags b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala b/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala new file mode 100644 index 0000000000..8e52613b6d --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } +} diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala new file mode 100644 index 0000000000..343cec99b5 --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + val firstClassFoo = Macros.foo _ + firstClassFoo +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword.check b/test/files/neg/macro-keyword.check new file mode 100644 index 0000000000..fd63db951c --- /dev/null +++ b/test/files/neg/macro-keyword.check @@ -0,0 +1,49 @@ +Macros_Bind_12.scala:2: error: illegal start of simple pattern + val Some(macro) = Some(42) + ^ +Macros_Bind_12.scala:6: error: ')' expected but '}' found. +} +^ +Macros_Class_4.scala:3: error: identifier expected but 'macro' found. +class macro + ^ +Macros_Class_5.scala:2: error: identifier expected but 'macro' found. + class macro + ^ +Macros_Def_13.scala:2: error: identifier expected but 'macro' found. + def macro = 2 + ^ +Macros_Object_6.scala:3: error: identifier expected but 'macro' found. +object macro + ^ +Macros_Object_7.scala:2: error: identifier expected but 'macro' found. + object macro + ^ +Macros_Package_10.scala:1: error: identifier expected but 'macro' found. +package macro + ^ +Macros_Package_11.scala:3: error: identifier expected but 'macro' found. +package macro.foo + ^ +Macros_Trait_8.scala:3: error: identifier expected but 'macro' found. +trait macro + ^ +Macros_Trait_9.scala:2: error: identifier expected but 'macro' found. + trait macro + ^ +Macros_Type_3.scala:2: error: identifier expected but 'macro' found. + type macro = Int + ^ +Macros_Val_1.scala:2: error: illegal start of simple pattern + val macro = ??? + ^ +Macros_Val_1.scala:3: error: '=' expected but '}' found. +} +^ +Macros_Var_2.scala:2: error: illegal start of simple pattern + var macro = ??? + ^ +Macros_Var_2.scala:3: error: '=' expected but '}' found. +} +^ +16 errors found diff --git a/test/files/neg/macro-keyword.flags b/test/files/neg/macro-keyword.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Bind_12.scala b/test/files/neg/macro-keyword/Macros_Bind_12.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Class_4.scala b/test/files/neg/macro-keyword/Macros_Class_4.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/files/neg/macro-keyword/Macros_Class_5.scala b/test/files/neg/macro-keyword/Macros_Class_5.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/files/neg/macro-keyword/Macros_Def_13.scala b/test/files/neg/macro-keyword/Macros_Def_13.scala new file mode 100644 index 0000000000..f4e25bfdfc --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Object_6.scala b/test/files/neg/macro-keyword/Macros_Object_6.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/files/neg/macro-keyword/Macros_Object_7.scala b/test/files/neg/macro-keyword/Macros_Object_7.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/files/neg/macro-keyword/Macros_Package_10.scala b/test/files/neg/macro-keyword/Macros_Package_10.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Package_11.scala b/test/files/neg/macro-keyword/Macros_Package_11.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/files/neg/macro-keyword/Macros_Trait_8.scala b/test/files/neg/macro-keyword/Macros_Trait_8.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/files/neg/macro-keyword/Macros_Trait_9.scala b/test/files/neg/macro-keyword/Macros_Trait_9.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/files/neg/macro-keyword/Macros_Type_3.scala b/test/files/neg/macro-keyword/Macros_Type_3.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Val_1.scala b/test/files/neg/macro-keyword/Macros_Val_1.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Var_2.scala b/test/files/neg/macro-keyword/Macros_Var_2.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-noexpand.check b/test/files/neg/macro-noexpand.check index c15d54bb32..c829bbab71 100644 --- a/test/files/neg/macro-noexpand.check +++ b/test/files/neg/macro-noexpand.check @@ -1,4 +1,4 @@ -Test_2.scala:3: error: not found: value x +Macros_Test_2.scala:7: error: not found: value x foo(x) ^ one error found diff --git a/test/files/neg/macro-noexpand/Impls_1.scala b/test/files/neg/macro-noexpand/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-noexpand/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-noexpand/Macros_1.scala b/test/files/neg/macro-noexpand/Macros_1.scala deleted file mode 100644 index 7a6aadf6a1..0000000000 --- a/test/files/neg/macro-noexpand/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo(x: Any) = ??? -} \ No newline at end of file diff --git a/test/files/neg/macro-noexpand/Macros_Test_2.scala b/test/files/neg/macro-noexpand/Macros_Test_2.scala new file mode 100644 index 0000000000..e783e2b53e --- /dev/null +++ b/test/files/neg/macro-noexpand/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo(x) +} \ No newline at end of file diff --git a/test/files/neg/macro-noexpand/Test_2.scala b/test/files/neg/macro-noexpand/Test_2.scala deleted file mode 100644 index 0bed592883..0000000000 --- a/test/files/neg/macro-noexpand/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(x) -} \ No newline at end of file diff --git a/test/files/neg/macro-noncompilertree/Macros_1.scala b/test/files/neg/macro-noncompilertree/Macros_1.scala deleted file mode 100644 index eb1253e5e9..0000000000 --- a/test/files/neg/macro-noncompilertree/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo = scala.reflect.mirror.Literal(scala.reflect.mirror.Constant(2)) -} \ No newline at end of file diff --git a/test/files/neg/macro-nontree/Macros_1.scala b/test/files/neg/macro-nontree/Macros_1.scala deleted file mode 100644 index 2433974a85..0000000000 --- a/test/files/neg/macro-nontree/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo = 2 -} \ No newline at end of file diff --git a/test/files/neg/macro-nontypeablebody.check b/test/files/neg/macro-nontypeablebody.check new file mode 100644 index 0000000000..0cfc864df8 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: value foo2 is not a member of object Impls + def foo(x: Any) = macro Impls.foo2 + ^ +one error found diff --git a/test/files/neg/macro-nontypeablebody.flags b/test/files/neg/macro-nontypeablebody.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-nontypeablebody/Impls_1.scala b/test/files/neg/macro-nontypeablebody/Impls_1.scala new file mode 100644 index 0000000000..7b1620d117 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = ??? +} diff --git a/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala b/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala new file mode 100644 index 0000000000..2031893970 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(x: Any) = macro Impls.foo2 +} + +object Test extends App { + import Macros._ + foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.check b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check new file mode 100644 index 0000000000..4d95dfc45c --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check @@ -0,0 +1,5 @@ +Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; + macro method foo cannot override an abstract method + def foo(x: Int) = macro Impls.impl + ^ +one error found diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..cb0b152852 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(x: c.Expr[Int]) = x +} + +trait Foo { + def foo(x: Int): Int +} + +object Macros extends Foo { + def foo(x: Int) = macro Impls.impl +} diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala new file mode 100644 index 0000000000..7e3357ec28 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val designator: Macros.type = Macros + designator.foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.check b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check new file mode 100644 index 0000000000..4d95dfc45c --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check @@ -0,0 +1,5 @@ +Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; + macro method foo cannot override an abstract method + def foo(x: Int) = macro Impls.impl + ^ +one error found diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..cb0b152852 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(x: c.Expr[Int]) = x +} + +trait Foo { + def foo(x: Int): Int +} + +object Macros extends Foo { + def foo(x: Int) = macro Impls.impl +} diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala new file mode 100644 index 0000000000..08fff30baf --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val designator: Foo = Macros + designator.foo(42) +} \ No newline at end of file diff --git a/test/files/neg/macro-override-method-overrides-macro.check b/test/files/neg/macro-override-method-overrides-macro.check new file mode 100644 index 0000000000..42edb0ff23 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro.check @@ -0,0 +1,5 @@ +Macros_Test_2.scala:8: error: overriding macro method foo in class B of type (x: String)Unit; + method foo cannot override a macro + override def foo(x: String) = println("fooDString") + ^ +one error found diff --git a/test/files/neg/macro-override-method-overrides-macro.flags b/test/files/neg/macro-override-method-overrides-macro.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala b/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala new file mode 100644 index 0000000000..0b127f5a59 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(tag: String, x: c.Expr[_]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree)) + Expr[Unit](body) + } + + def fooBString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBString", x) + def fooBInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBInt", x) + def fooDInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooDInt", x) + def fooZString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooZString", x) +} diff --git a/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala new file mode 100644 index 0000000000..36821b05d8 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala @@ -0,0 +1,15 @@ +class B { + def foo(x: String) = macro Impls.fooBString + def foo(x: Int) = macro Impls.fooBInt + def foo(x: Boolean) = println("fooBBoolean") +} + +class D extends B { + override def foo(x: String) = println("fooDString") + override def foo(x: Int) = macro Impls.fooDInt +} + +class Z extends D { + override def foo(x: String) = macro Impls.fooZString + override def foo(x: Boolean) = println("fooZBoolean") +} diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check new file mode 100644 index 0000000000..d9c390ba25 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for C[T] + println(implicitly[GroundTypeTag[C[T]]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[C[T]] + println(implicitly[GroundTypeTag[List[C[T]]]]) + ^ +two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala new file mode 100644 index 0000000000..d5ee61b91d --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTagHK[C[_], T] = { + println(implicitly[GroundTypeTag[C[T]]]) + println(implicitly[GroundTypeTag[List[C[T]]]]) + } + fooNoTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check new file mode 100644 index 0000000000..c678a2a313 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for T + println(implicitly[GroundTypeTag[T]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[T] + println(implicitly[GroundTypeTag[List[T]]]) + ^ +two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala new file mode 100644 index 0000000000..98bdf6d67f --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTag[T] = { + println(implicitly[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[List[T]]]) + } + fooNoTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag.check b/test/files/neg/macro-reify-groundtypetag-usetypetag.check new file mode 100644 index 0000000000..c678a2a313 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for T + println(implicitly[GroundTypeTag[T]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[T] + println(implicitly[GroundTypeTag[List[T]]]) + ^ +two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala new file mode 100644 index 0000000000..507d03a390 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: TypeTag] = { + println(implicitly[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a.check b/test/files/neg/macro-without-xmacros-a.check new file mode 100644 index 0000000000..a3ca081f04 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a.check @@ -0,0 +1,10 @@ +Macros_2.scala:5: error: not found: value macro + def foo(x: Int): Int = macro foo_impl + ^ +Macros_2.scala:7: error: not found: value macro + def bar(x: Int): Int = macro bar_impl + ^ +Macros_2.scala:11: error: not found: value macro + def quux(x: Int): Int = macro quux_impl + ^ +three errors found diff --git a/test/files/neg/macro-without-xmacros-a/Impls_1.scala b/test/files/neg/macro-without-xmacros-a/Impls_1.scala new file mode 100644 index 0000000000..2493c81c95 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/files/neg/macro-without-xmacros-a/Macros_2.scala b/test/files/neg/macro-without-xmacros-a/Macros_2.scala new file mode 100644 index 0000000000..62f9dcf505 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Macros_2.scala @@ -0,0 +1,12 @@ +import Impls._ + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro foo_impl + } + def bar(x: Int): Int = macro bar_impl +} + +class Macros { + def quux(x: Int): Int = macro quux_impl +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-a/Test_3.scala b/test/files/neg/macro-without-xmacros-a/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b.check b/test/files/neg/macro-without-xmacros-b.check new file mode 100644 index 0000000000..dce4a084c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b.check @@ -0,0 +1,10 @@ +Macros_2.scala:3: error: ';' expected but '.' found. + def foo(x: Int): Int = macro Impls.foo_impl + ^ +Macros_2.scala:5: error: ';' expected but '.' found. + def bar(x: Int): Int = macro Impls.bar_impl + ^ +Macros_2.scala:9: error: ';' expected but '.' found. + def quux(x: Int): Int = macro Impls.quux_impl + ^ +three errors found diff --git a/test/files/neg/macro-without-xmacros-b/Impls_1.scala b/test/files/neg/macro-without-xmacros-b/Impls_1.scala new file mode 100644 index 0000000000..2493c81c95 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Impls_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + } +} diff --git a/test/files/neg/macro-without-xmacros-b/Macros_2.scala b/test/files/neg/macro-without-xmacros-b/Macros_2.scala new file mode 100644 index 0000000000..de7080c7e8 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Macros_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo_impl + } + def bar(x: Int): Int = macro Impls.bar_impl +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux_impl +} \ No newline at end of file diff --git a/test/files/neg/macro-without-xmacros-b/Test_3.scala b/test/files/neg/macro-without-xmacros-b/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/neg/reify_ann2a.check b/test/files/neg/reify_ann2a.check deleted file mode 100644 index 2afe37e1d8..0000000000 --- a/test/files/neg/reify_ann2a.check +++ /dev/null @@ -1,4 +0,0 @@ -reify_ann2a.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(immutable.this.List.apply[String]("1a")) which involves a symbol declared inside the block being reified - val tree = scala.reflect.Code.lift{ - ^ -one error found diff --git a/test/files/neg/reify_ann2a.scala b/test/files/neg/reify_ann2a.scala deleted file mode 100644 index 8de0984074..0000000000 --- a/test/files/neg/reify_ann2a.scala +++ /dev/null @@ -1,30 +0,0 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - // test 1: reify - val tree = scala.reflect.Code.lift{ - class ann(bar: List[String]) extends StaticAnnotation - - @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { - @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { - @ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b")) - val s = 4: Int @ann(bar=List("9a")) @ann(bar=List("9b")) - r + s - } - } - }.tree - println(tree.toString) - - // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - val ttree = toolbox.typeCheck(tree) - println(ttree.toString) - - // test 3: import and compile - toolbox.runExpr(tree) -} \ No newline at end of file diff --git a/test/files/neg/reify_ann2b.check b/test/files/neg/reify_ann2b.check index ceb70689f1..b9dd84c1ee 100644 --- a/test/files/neg/reify_ann2b.check +++ b/test/files/neg/reify_ann2b.check @@ -1,7 +1,4 @@ -reify_ann2b.scala:10: error: inner classes cannot be classfile annotations - class ann(bar: String) extends ClassfileAnnotation - ^ -reify_ann2b.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(bar = "1a") which involves a symbol declared inside the block being reified - val tree = scala.reflect.Code.lift{ - ^ -two errors found +reify_ann2b.scala:6: error: inner classes cannot be classfile annotations + class ann(bar: String) extends ClassfileAnnotation + ^ +one error found diff --git a/test/files/neg/reify_ann2b.scala b/test/files/neg/reify_ann2b.scala index b43567c2a7..6b6da8f790 100644 --- a/test/files/neg/reify_ann2b.scala +++ b/test/files/neg/reify_ann2b.scala @@ -1,12 +1,8 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ class ann(bar: String) extends ClassfileAnnotation @ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) { @@ -20,8 +16,7 @@ object Test extends App { println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/neg/t2386.check b/test/files/neg/t2386.check index 1a01696a9a..f70f12535f 100644 --- a/test/files/neg/t2386.check +++ b/test/files/neg/t2386.check @@ -1,4 +1,4 @@ -t2386.scala:2: error: could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[Array[_ >: String with Int]] - val a = Array(Array(1, 2), Array("a","b")) - ^ -one error found +t2386.scala:2: error: No ClassTag available for Array[_ >: String with Int] + val a = Array(Array(1, 2), Array("a","b")) + ^ +one error found diff --git a/test/files/neg/t2775.check b/test/files/neg/t2775.check index a30d35fdd9..f357221cd9 100644 --- a/test/files/neg/t2775.check +++ b/test/files/neg/t2775.check @@ -1,4 +1,4 @@ -t2775.scala:1: error: cannot find class manifest for element type B.this.T -trait B[S] { type T = S; val c = new Array[T](1) } - ^ -one error found +t2775.scala:1: error: cannot find class tag for element type B.this.T +trait B[S] { type T = S; val c = new Array[T](1) } + ^ +one error found diff --git a/test/files/neg/t3507.check b/test/files/neg/t3507.check index 8e538e4a8b..6b6df6ba76 100644 --- a/test/files/neg/t3507.check +++ b/test/files/neg/t3507.check @@ -1,4 +1,4 @@ -t3507.scala:13: error: No Manifest available for _1.b.c.type. - mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier - ^ -one error found +t3507.scala:13: error: No GroundTypeTag available for _1.b.c.type + mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier + ^ +one error found diff --git a/test/files/neg/t3692.check b/test/files/neg/t3692.check index 96ddd2a461..ec67e76bb4 100644 --- a/test/files/neg/t3692.check +++ b/test/files/neg/t3692.check @@ -1,4 +1,11 @@ -t3692.scala:15: error: unreachable code - case m2: Map[T, Int] => new java.util.HashMap[T, Integer] - ^ -one error found +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead + private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { + ^ +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead + private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { + ^ +t3692.scala:15: error: unreachable code + case m2: Map[T, Int] => new java.util.HashMap[T, Integer] + ^ +two warnings found +one error found diff --git a/test/files/neg/t5334_1.check b/test/files/neg/t5334_1.check new file mode 100644 index 0000000000..1d5a7cbc01 --- /dev/null +++ b/test/files/neg/t5334_1.check @@ -0,0 +1,4 @@ +t5334_1.scala:4: error: implementation restriction: cannot reify block of type C that involves a type declared inside the block being reified. consider casting the return value to a suitable type + reify { + ^ +one error found diff --git a/test/files/neg/t5334_1.scala b/test/files/neg/t5334_1.scala new file mode 100644 index 0000000000..a7de5a0915 --- /dev/null +++ b/test/files/neg/t5334_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + class C { override def toString = "C" } + new C + }.eval +} diff --git a/test/files/neg/t5334_2.check b/test/files/neg/t5334_2.check new file mode 100644 index 0000000000..a62bfff7a5 --- /dev/null +++ b/test/files/neg/t5334_2.check @@ -0,0 +1,4 @@ +t5334_2.scala:4: error: implementation restriction: cannot reify block of type List[(C, C)] that involves a type declared inside the block being reified. consider casting the return value to a suitable type + reify { + ^ +one error found diff --git a/test/files/neg/t5334_2.scala b/test/files/neg/t5334_2.scala new file mode 100644 index 0000000000..fc6dfcd0c1 --- /dev/null +++ b/test/files/neg/t5334_2.scala @@ -0,0 +1,8 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + class C { override def toString() = "C" } + List((new C, new C)) + }.eval +} diff --git a/test/files/pos/implicits.scala b/test/files/pos/implicits.scala deleted file mode 100644 index 2c01dd0ba8..0000000000 --- a/test/files/pos/implicits.scala +++ /dev/null @@ -1,89 +0,0 @@ -// #1435 -object t1435 { - implicit def a(s:String):String = error("") - implicit def a(i:Int):String = error("") - implicit def b(i:Int):String = error("") -} - -class C1435 { - val v:String = { - import t1435.a - 2 - } -} - -// #1492 -class C1492 { - - class X - - def foo(x: X => X) {} - - foo ( implicit x => implicitly[X] ) - foo { implicit x => implicitly[X] } -} - -// #1579 -object Test1579 { - class Column - class Query[E](val value: E) - class Invoker(q: Any) { val foo = null } - - implicit def unwrap[C](q: Query[C]) = q.value - implicit def invoker(q: Query[Column]) = new Invoker(q) - - val q = new Query(new Column) - q.foo -} -// #1625 -object Test1625 { - - class Wrapped(x:Any) { - def unwrap() = x - } - - implicit def byName[A](x: =>A) = new Wrapped(x) - - implicit def byVal[A](x: A) = x - - def main(args: Array[String]) = { - -// val res:Wrapped = 7 // works - - val res = 7.unwrap() // doesn't work - - println("=> result: " + res) - } -} - -object Test2188 { - implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) - - val x: java.util.List[String] = List("foo") -} - -object TestNumericWidening { - val y = 1 - val x: java.lang.Long = y -} - -// #2709 -package foo2709 { - class A - class B - - package object bar { - implicit def a2b(a: A): B = new B - } - - package bar { - object test { - new A: B - } - } -} - -// Problem with specs -object specsProblem { - println(implicitly[Manifest[Class[_]]]) -} diff --git a/test/files/pos/implicits.scala.temporarily.disabled b/test/files/pos/implicits.scala.temporarily.disabled new file mode 100644 index 0000000000..2c01dd0ba8 --- /dev/null +++ b/test/files/pos/implicits.scala.temporarily.disabled @@ -0,0 +1,89 @@ +// #1435 +object t1435 { + implicit def a(s:String):String = error("") + implicit def a(i:Int):String = error("") + implicit def b(i:Int):String = error("") +} + +class C1435 { + val v:String = { + import t1435.a + 2 + } +} + +// #1492 +class C1492 { + + class X + + def foo(x: X => X) {} + + foo ( implicit x => implicitly[X] ) + foo { implicit x => implicitly[X] } +} + +// #1579 +object Test1579 { + class Column + class Query[E](val value: E) + class Invoker(q: Any) { val foo = null } + + implicit def unwrap[C](q: Query[C]) = q.value + implicit def invoker(q: Query[Column]) = new Invoker(q) + + val q = new Query(new Column) + q.foo +} +// #1625 +object Test1625 { + + class Wrapped(x:Any) { + def unwrap() = x + } + + implicit def byName[A](x: =>A) = new Wrapped(x) + + implicit def byVal[A](x: A) = x + + def main(args: Array[String]) = { + +// val res:Wrapped = 7 // works + + val res = 7.unwrap() // doesn't work + + println("=> result: " + res) + } +} + +object Test2188 { + implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) + + val x: java.util.List[String] = List("foo") +} + +object TestNumericWidening { + val y = 1 + val x: java.lang.Long = y +} + +// #2709 +package foo2709 { + class A + class B + + package object bar { + implicit def a2b(a: A): B = new B + } + + package bar { + object test { + new A: B + } + } +} + +// Problem with specs +object specsProblem { + println(implicitly[Manifest[Class[_]]]) +} diff --git a/test/files/pos/liftcode_polymorphic.scala b/test/files/pos/liftcode_polymorphic.scala index 3d4b159c83..9c59b34bee 100644 --- a/test/files/pos/liftcode_polymorphic.scala +++ b/test/files/pos/liftcode_polymorphic.scala @@ -1,3 +1,5 @@ +import scala.reflect.mirror._ + object Append extends Application { def append[A](l1: List[A], l2: List[A]):List[A] = @@ -6,6 +8,6 @@ object Append extends Application { case x::xs => x :: append(xs, l2) } - println(scala.reflect.Code.lift(append _).tree) + println(reify(append _).tree) } diff --git a/test/files/pos/macros.flags b/test/files/pos/macros.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/pos/macros.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/pos/macros.scala b/test/files/pos/macros.scala deleted file mode 100644 index 303610d464..0000000000 --- a/test/files/pos/macros.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test { - - class C { - def macro foo[T](xs: List[T]): T = (T, xs) match { - case (t1: Type, t2: Tree) => t2 - } - } -} diff --git a/test/files/pos/manifest1.scala b/test/files/pos/manifest1.scala deleted file mode 100644 index 8901aa7437..0000000000 --- a/test/files/pos/manifest1.scala +++ /dev/null @@ -1,21 +0,0 @@ -import scala.reflect.Manifest - -object Test { - def foo[T](x: T)(implicit m: Manifest[T]) { - foo(List(x)) - } - foo(1) - foo("abc") - foo(List(1, 2, 3)) - val x: List[Int] with Ordered[List[Int]] = null - foo(x) - foo[x.type](x) - abstract class C { type T = String; val x: T } - val c = new C { val x = "abc" } - foo(c.x) - abstract class D { type T; implicit val m: Manifest[T]; val x: T } - val stringm = implicitly[Manifest[String]] - val d: D = new D { type T = String; val m = stringm; val x = "x" } - import d.m - foo(d.x) -} diff --git a/test/files/pos/manifest1.scala.temporarily.disabled b/test/files/pos/manifest1.scala.temporarily.disabled new file mode 100644 index 0000000000..8901aa7437 --- /dev/null +++ b/test/files/pos/manifest1.scala.temporarily.disabled @@ -0,0 +1,21 @@ +import scala.reflect.Manifest + +object Test { + def foo[T](x: T)(implicit m: Manifest[T]) { + foo(List(x)) + } + foo(1) + foo("abc") + foo(List(1, 2, 3)) + val x: List[Int] with Ordered[List[Int]] = null + foo(x) + foo[x.type](x) + abstract class C { type T = String; val x: T } + val c = new C { val x = "abc" } + foo(c.x) + abstract class D { type T; implicit val m: Manifest[T]; val x: T } + val stringm = implicitly[Manifest[String]] + val d: D = new D { type T = String; val m = stringm; val x = "x" } + import d.m + foo(d.x) +} diff --git a/test/files/pos/t5223.scala b/test/files/pos/t5223.scala index 51682e9254..398630dc61 100644 --- a/test/files/pos/t5223.scala +++ b/test/files/pos/t5223.scala @@ -1,6 +1,6 @@ -import scala.reflect._ +import scala.reflect.mirror._ object Foo extends App { - Code.lift{def printf(format: String, args: Any*): String = null } - Code.lift{def printf(format: String, args: Any*): String = ("abc": @cloneable)} + reify{def printf(format: String, args: Any*): String = null } + reify{def printf(format: String, args: Any*): String = ("abc": @cloneable)} } diff --git a/test/files/pos/t531.scala b/test/files/pos/t531.scala index 856926de4f..5176912ef0 100644 --- a/test/files/pos/t531.scala +++ b/test/files/pos/t531.scala @@ -1,8 +1,9 @@ +import scala.reflect.mirror._ + object Test extends App { - import scala.reflect._; def titi = { var truc = 0 - val tata = Code.lift{() => { + val tata = reify{() => { truc = 6 }} () diff --git a/test/files/pos/t532.scala b/test/files/pos/t532.scala index f864bbf45e..a319fdfa27 100644 --- a/test/files/pos/t532.scala +++ b/test/files/pos/t532.scala @@ -1,8 +1,9 @@ +import scala.reflect.mirror._ + object Test extends App { - import scala.reflect._; def titi: Unit = { var truc = 0 - val tata = Code.lift{() => { + val tata = reify{() => { truc = truc + 6 }} () diff --git a/test/files/run/classtags_contextbound.check b/test/files/run/classtags_contextbound.check new file mode 100644 index 0000000000..4104d544ba --- /dev/null +++ b/test/files/run/classtags_contextbound.check @@ -0,0 +1 @@ +class [I diff --git a/test/files/run/classtags_contextbound.scala b/test/files/run/classtags_contextbound.scala new file mode 100644 index 0000000000..5bb0ae8d80 --- /dev/null +++ b/test/files/run/classtags_contextbound.scala @@ -0,0 +1,5 @@ +object Test extends App { + def mkArray[T: ClassTag] = Array[T]() + def foo[T: ClassTag] = mkArray[T] + println(foo[Int].getClass) +} \ No newline at end of file diff --git a/test/files/run/classtags_core.check b/test/files/run/classtags_core.check new file mode 100644 index 0000000000..ce5a893b08 --- /dev/null +++ b/test/files/run/classtags_core.check @@ -0,0 +1,30 @@ +true +ClassTag(byte) +true +ClassTag(short) +true +ClassTag(char) +true +ClassTag(int) +true +ClassTag(long) +true +ClassTag(float) +true +ClassTag(double) +true +ClassTag(boolean) +true +ClassTag(void) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) +true +ClassTag(class java.lang.Object) diff --git a/test/files/run/classtags_core.scala b/test/files/run/classtags_core.scala new file mode 100644 index 0000000000..45c54b1fe0 --- /dev/null +++ b/test/files/run/classtags_core.scala @@ -0,0 +1,32 @@ +object Test extends App { + println(implicitly[ClassTag[Byte]] eq ClassTag.Byte) + println(implicitly[ClassTag[Byte]]) + println(implicitly[ClassTag[Short]] eq ClassTag.Short) + println(implicitly[ClassTag[Short]]) + println(implicitly[ClassTag[Char]] eq ClassTag.Char) + println(implicitly[ClassTag[Char]]) + println(implicitly[ClassTag[Int]] eq ClassTag.Int) + println(implicitly[ClassTag[Int]]) + println(implicitly[ClassTag[Long]] eq ClassTag.Long) + println(implicitly[ClassTag[Long]]) + println(implicitly[ClassTag[Float]] eq ClassTag.Float) + println(implicitly[ClassTag[Float]]) + println(implicitly[ClassTag[Double]] eq ClassTag.Double) + println(implicitly[ClassTag[Double]]) + println(implicitly[ClassTag[Boolean]] eq ClassTag.Boolean) + println(implicitly[ClassTag[Boolean]]) + println(implicitly[ClassTag[Unit]] eq ClassTag.Unit) + println(implicitly[ClassTag[Unit]]) + println(implicitly[ClassTag[Any]] eq ClassTag.Any) + println(implicitly[ClassTag[Any]]) + println(implicitly[ClassTag[Object]] eq ClassTag.Object) + println(implicitly[ClassTag[Object]]) + println(implicitly[ClassTag[AnyVal]] eq ClassTag.AnyVal) + println(implicitly[ClassTag[AnyVal]]) + println(implicitly[ClassTag[AnyRef]] eq ClassTag.AnyRef) + println(implicitly[ClassTag[AnyRef]]) + println(implicitly[ClassTag[Null]] eq ClassTag.Null) + println(implicitly[ClassTag[Null]]) + println(implicitly[ClassTag[Nothing]] eq ClassTag.Nothing) + println(implicitly[ClassTag[Nothing]]) +} \ No newline at end of file diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check deleted file mode 100644 index 36a458dacc..0000000000 --- a/test/files/run/existentials3.check +++ /dev/null @@ -1,22 +0,0 @@ -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/existentials3.check.temporarily.disabled b/test/files/run/existentials3.check.temporarily.disabled new file mode 100644 index 0000000000..36a458dacc --- /dev/null +++ b/test/files/run/existentials3.check.temporarily.disabled @@ -0,0 +1,22 @@ +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/existentials3.scala b/test/files/run/existentials3.scala deleted file mode 100644 index bb80d366cc..0000000000 --- a/test/files/run/existentials3.scala +++ /dev/null @@ -1,73 +0,0 @@ -object Test { - trait ToS { final override def toString = getClass.getName } - - def f1 = { case class Bar() extends ToS; Bar } - def f2 = { case class Bar() extends ToS; Bar() } - def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - def f4 = { class Bar() extends ToS; new Bar() } - def f5 = { object Bar extends ToS; Bar } - def f6 = { () => { object Bar extends ToS ; Bar } } - def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - def f10 = { class A { type T1 } ; List[A#T1]() } - def f11 = { abstract class A extends Seq[Int] ; List[A]() } - def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - val g1 = { case class Bar() extends ToS; Bar } - val g2 = { case class Bar() extends ToS; Bar() } - val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - val g4 = { class Bar() extends ToS; new Bar() } - val g5 = { object Bar extends ToS; Bar } - val g6 = { () => { object Bar extends ToS ; Bar } } - val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - val g10 = { class A { type T1 } ; List[A#T1]() } - val g11 = { abstract class A extends Seq[Int] ; List[A]() } - val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - def m[T: Manifest](x: T) = println(manifest[T]) - - // manifests don't work for f10/g10 - def main(args: Array[String]): Unit = { - m(f1) - m(f2) - m(f3) - m(f4) - m(f5) - m(f6) - m(f7) - m(f8) - m(f9) - // m(f10) - m(f11) - m(f12) - m(g1) - m(g2) - m(g3) - m(g4) - m(g5) - m(g6) - m(g7) - m(g8) - m(g9) - // m(g10) - m(g11) - m(g12) - } -} - -object Misc { - trait Bippy { def bippy = "I'm Bippy!" } - object o1 { - def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } - def f2 = f1.head.bippy - } - def g1 = o1.f1 _ - def g2 = o1.f2 _ -} diff --git a/test/files/run/existentials3.scala.temporarily.disabled b/test/files/run/existentials3.scala.temporarily.disabled new file mode 100644 index 0000000000..bb80d366cc --- /dev/null +++ b/test/files/run/existentials3.scala.temporarily.disabled @@ -0,0 +1,73 @@ +object Test { + trait ToS { final override def toString = getClass.getName } + + def f1 = { case class Bar() extends ToS; Bar } + def f2 = { case class Bar() extends ToS; Bar() } + def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + def f4 = { class Bar() extends ToS; new Bar() } + def f5 = { object Bar extends ToS; Bar } + def f6 = { () => { object Bar extends ToS ; Bar } } + def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + def f10 = { class A { type T1 } ; List[A#T1]() } + def f11 = { abstract class A extends Seq[Int] ; List[A]() } + def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + val g1 = { case class Bar() extends ToS; Bar } + val g2 = { case class Bar() extends ToS; Bar() } + val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + val g4 = { class Bar() extends ToS; new Bar() } + val g5 = { object Bar extends ToS; Bar } + val g6 = { () => { object Bar extends ToS ; Bar } } + val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + val g10 = { class A { type T1 } ; List[A#T1]() } + val g11 = { abstract class A extends Seq[Int] ; List[A]() } + val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + def m[T: Manifest](x: T) = println(manifest[T]) + + // manifests don't work for f10/g10 + def main(args: Array[String]): Unit = { + m(f1) + m(f2) + m(f3) + m(f4) + m(f5) + m(f6) + m(f7) + m(f8) + m(f9) + // m(f10) + m(f11) + m(f12) + m(g1) + m(g2) + m(g3) + m(g4) + m(g5) + m(g6) + m(g7) + m(g8) + m(g9) + // m(g10) + m(g11) + m(g12) + } +} + +object Misc { + trait Bippy { def bippy = "I'm Bippy!" } + object o1 { + def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } + def f2 = f1.head.bippy + } + def g1 = o1.f1 _ + def g2 = o1.f2 _ +} diff --git a/test/files/run/groundtypetags_core.check b/test/files/run/groundtypetags_core.check new file mode 100644 index 0000000000..d1b71f0926 --- /dev/null +++ b/test/files/run/groundtypetags_core.check @@ -0,0 +1,30 @@ +true +GroundTypeTag[Byte] +true +GroundTypeTag[Short] +true +GroundTypeTag[Char] +true +GroundTypeTag[Int] +true +GroundTypeTag[Long] +true +GroundTypeTag[Float] +true +GroundTypeTag[Double] +true +GroundTypeTag[Boolean] +true +GroundTypeTag[Unit] +true +GroundTypeTag[Any] +true +GroundTypeTag[Object] +true +GroundTypeTag[AnyVal] +true +GroundTypeTag[AnyRef] +true +GroundTypeTag[Null] +true +GroundTypeTag[Nothing] diff --git a/test/files/run/groundtypetags_core.scala b/test/files/run/groundtypetags_core.scala new file mode 100644 index 0000000000..d779e3fc7e --- /dev/null +++ b/test/files/run/groundtypetags_core.scala @@ -0,0 +1,32 @@ +object Test extends App { + println(implicitly[GroundTypeTag[Byte]] eq GroundTypeTag.Byte) + println(implicitly[GroundTypeTag[Byte]]) + println(implicitly[GroundTypeTag[Short]] eq GroundTypeTag.Short) + println(implicitly[GroundTypeTag[Short]]) + println(implicitly[GroundTypeTag[Char]] eq GroundTypeTag.Char) + println(implicitly[GroundTypeTag[Char]]) + println(implicitly[GroundTypeTag[Int]] eq GroundTypeTag.Int) + println(implicitly[GroundTypeTag[Int]]) + println(implicitly[GroundTypeTag[Long]] eq GroundTypeTag.Long) + println(implicitly[GroundTypeTag[Long]]) + println(implicitly[GroundTypeTag[Float]] eq GroundTypeTag.Float) + println(implicitly[GroundTypeTag[Float]]) + println(implicitly[GroundTypeTag[Double]] eq GroundTypeTag.Double) + println(implicitly[GroundTypeTag[Double]]) + println(implicitly[GroundTypeTag[Boolean]] eq GroundTypeTag.Boolean) + println(implicitly[GroundTypeTag[Boolean]]) + println(implicitly[GroundTypeTag[Unit]] eq GroundTypeTag.Unit) + println(implicitly[GroundTypeTag[Unit]]) + println(implicitly[GroundTypeTag[Any]] eq GroundTypeTag.Any) + println(implicitly[GroundTypeTag[Any]]) + println(implicitly[GroundTypeTag[Object]] eq GroundTypeTag.Object) + println(implicitly[GroundTypeTag[Object]]) + println(implicitly[GroundTypeTag[AnyVal]] eq GroundTypeTag.AnyVal) + println(implicitly[GroundTypeTag[AnyVal]]) + println(implicitly[GroundTypeTag[AnyRef]] eq GroundTypeTag.AnyRef) + println(implicitly[GroundTypeTag[AnyRef]]) + println(implicitly[GroundTypeTag[Null]] eq GroundTypeTag.Null) + println(implicitly[GroundTypeTag[Null]]) + println(implicitly[GroundTypeTag[Nothing]] eq GroundTypeTag.Nothing) + println(implicitly[GroundTypeTag[Nothing]]) +} \ No newline at end of file diff --git a/test/files/run/macro-abort-fresh.check b/test/files/run/macro-abort-fresh.check new file mode 100644 index 0000000000..28057c2883 --- /dev/null +++ b/test/files/run/macro-abort-fresh.check @@ -0,0 +1,6 @@ +$1$ +qwe1 +qwe2 +reflective compilation has failed: + +blargh diff --git a/test/files/run/macro-abort-fresh.flags b/test/files/run/macro-abort-fresh.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-abort-fresh.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-abort-fresh/Macros_1.scala b/test/files/run/macro-abort-fresh/Macros_1.scala new file mode 100644 index 0000000000..4186c4c4a6 --- /dev/null +++ b/test/files/run/macro-abort-fresh/Macros_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.Context + +object Impls { + def impl(c: Context) = { + import c.mirror._ + println(c.fresh()) + println(c.fresh("qwe")) + println(c.fresh(newTypeName("qwe"))) + c.abort(NoPosition, "blargh") + } +} + +object Macros { + def foo = macro Impls.impl +} \ No newline at end of file diff --git a/test/files/run/macro-abort-fresh/Test_2.scala b/test/files/run/macro-abort-fresh/Test_2.scala new file mode 100644 index 0000000000..f389231ca6 --- /dev/null +++ b/test/files/run/macro-abort-fresh/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Select(Ident("Macros"), newTermName("foo")) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-md-mi.check b/test/files/run/macro-basic-ma-md-mi.check new file mode 100644 index 0000000000..b74e882ae3 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi.check @@ -0,0 +1 @@ +31 \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-md-mi.flags b/test/files/run/macro-basic-ma-md-mi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/run/macro-basic-ma-md-mi/Impls_1.scala b/test/files/run/macro-basic-ma-md-mi/Impls_1.scala new file mode 100644 index 0000000000..3f23e349d5 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi/Impls_1.scala @@ -0,0 +1,21 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-basic-ma-md-mi/Macros_2.scala b/test/files/run/macro-basic-ma-md-mi/Macros_2.scala new file mode 100644 index 0000000000..5279043746 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi/Macros_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-md-mi/Test_3.scala b/test/files/run/macro-basic-ma-md-mi/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-mdmi.check b/test/files/run/macro-basic-ma-mdmi.check new file mode 100644 index 0000000000..b74e882ae3 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi.check @@ -0,0 +1 @@ +31 \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-mdmi.flags b/test/files/run/macro-basic-ma-mdmi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala b/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala new file mode 100644 index 0000000000..44bfe861e3 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala @@ -0,0 +1,32 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} + +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} \ No newline at end of file diff --git a/test/files/run/macro-basic-ma-mdmi/Test_2.scala b/test/files/run/macro-basic-ma-mdmi/Test_2.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/run/macro-basic-mamd-mi.check b/test/files/run/macro-basic-mamd-mi.check new file mode 100644 index 0000000000..b74e882ae3 --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi.check @@ -0,0 +1 @@ +31 \ No newline at end of file diff --git a/test/files/run/macro-basic-mamd-mi.flags b/test/files/run/macro-basic-mamd-mi.flags new file mode 100644 index 0000000000..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi.flags @@ -0,0 +1 @@ +-Xmacros diff --git a/test/files/run/macro-basic-mamd-mi/Impls_1.scala b/test/files/run/macro-basic-mamd-mi/Impls_1.scala new file mode 100644 index 0000000000..eadb63fa8e --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi/Impls_1.scala @@ -0,0 +1,19 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala b/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala new file mode 100644 index 0000000000..d3746894f0 --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala @@ -0,0 +1,15 @@ +object Macros { + object Shmacros { + def foo(x: Int): Int = macro Impls.foo + } + def bar(x: Int): Int = macro Impls.bar +} + +class Macros { + def quux(x: Int): Int = macro Impls.quux +} + +object Test extends App { + import Macros.Shmacros._ + println(foo(2) + Macros.bar(2) * new Macros().quux(4)) +} \ No newline at end of file diff --git a/test/files/run/macro-basic.check b/test/files/run/macro-basic.check deleted file mode 100644 index d434014897..0000000000 --- a/test/files/run/macro-basic.check +++ /dev/null @@ -1 +0,0 @@ -10 diff --git a/test/files/run/macro-basic.flags b/test/files/run/macro-basic.flags deleted file mode 100644 index 06a7b31f11..0000000000 --- a/test/files/run/macro-basic.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros diff --git a/test/files/run/macro-basic/Macros_1.scala b/test/files/run/macro-basic/Macros_1.scala deleted file mode 100644 index c2ea183abe..0000000000 --- a/test/files/run/macro-basic/Macros_1.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Macros { - object Shmacros { - def macro foo(x: Int): Int = x - } - def macro bar(x: Int): Int = x -} - -class Macros { - def macro quux(x: Int): Int = x -} \ No newline at end of file diff --git a/test/files/run/macro-basic/Test_2.scala b/test/files/run/macro-basic/Test_2.scala deleted file mode 100644 index e9a10e20c9..0000000000 --- a/test/files/run/macro-basic/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros.Shmacros._ - println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -} \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl.check b/test/files/run/macro-bodyexpandstoimpl.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl.flags b/test/files/run/macro-bodyexpandstoimpl.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala new file mode 100644 index 0000000000..5c5ec2c999 --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x + + def refToFoo(dummy: Int) = macro refToFoo_impl + def refToFoo_impl(c: Ctx)(dummy: c.Expr[Int]) = { + import c.mirror._ + val body = Select(Ident(newTermName("Impls")), newTermName("foo")) + Expr[Int](body) + } +} \ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala new file mode 100644 index 0000000000..2934201a16 --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo(x: Int) = macro Impls.refToFoo(42) +} + +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation.check b/test/files/run/macro-declared-in-annotation.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-declared-in-annotation.flags b/test/files/run/macro-declared-in-annotation.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation/Impls_1.scala b/test/files/run/macro-declared-in-annotation/Impls_1.scala new file mode 100644 index 0000000000..a1234a7374 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Literal(Constant("this is deprecated"))) + Expr[String](body) + } +} diff --git a/test/files/run/macro-declared-in-annotation/Macros_2.scala b/test/files/run/macro-declared-in-annotation/Macros_2.scala new file mode 100644 index 0000000000..a565849aa9 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation/Macros_2.scala @@ -0,0 +1,8 @@ +class foo(val bar: String) extends StaticAnnotation + +object Api { + // foo in ann must have a different name + // otherwise, we get bitten by https://issues.scala-lang.org/browse/SI-5544 + @foo({def fooInAnn = macro Impls.foo; fooInAnn}) + def foo = println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation/Test_3.scala b/test/files/run/macro-declared-in-annotation/Test_3.scala new file mode 100644 index 0000000000..866487f028 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation/Test_3.scala @@ -0,0 +1,3 @@ +object Test extends App { + Api.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous.check b/test/files/run/macro-declared-in-anonymous.check new file mode 100644 index 0000000000..09b8d015a6 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.macros) +it works diff --git a/test/files/run/macro-declared-in-anonymous.flags b/test/files/run/macro-declared-in-anonymous.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-anonymous/Impls_1.scala b/test/files/run/macro-declared-in-anonymous/Impls_1.scala new file mode 100644 index 0000000000..c0827ace31 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala new file mode 100644 index 0000000000..8bd8c172c9 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val macros = new { def foo = macro Impls.foo } + macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-block.check b/test/files/run/macro-declared-in-block.check new file mode 100644 index 0000000000..a61fd13087 --- /dev/null +++ b/test/files/run/macro-declared-in-block.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-declared-in-block.flags b/test/files/run/macro-declared-in-block.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-block.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-block/Impls_1.scala b/test/files/run/macro-declared-in-block/Impls_1.scala new file mode 100644 index 0000000000..c0827ace31 --- /dev/null +++ b/test/files/run/macro-declared-in-block/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-block/Macros_Test_2.scala b/test/files/run/macro-declared-in-block/Macros_Test_2.scala new file mode 100644 index 0000000000..69088e24bc --- /dev/null +++ b/test/files/run/macro-declared-in-block/Macros_Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + { + def foo = macro Impls.foo + foo + } +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class.check b/test/files/run/macro-declared-in-class-class.check new file mode 100644 index 0000000000..480c2f906f --- /dev/null +++ b/test/files/run/macro-declared-in-class-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Test.this.outer.Macros()) +it works diff --git a/test/files/run/macro-declared-in-class-class.flags b/test/files/run/macro-declared-in-class-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-class/Impls_1.scala b/test/files/run/macro-declared-in-class-class/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-class-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala new file mode 100644 index 0000000000..871857a97f --- /dev/null +++ b/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class Macros { + class Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = new Macros() + new outer.Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object.check b/test/files/run/macro-declared-in-class-object.check new file mode 100644 index 0000000000..f7ba5a53cb --- /dev/null +++ b/test/files/run/macro-declared-in-class-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.outer.Macros) +it works diff --git a/test/files/run/macro-declared-in-class-object.flags b/test/files/run/macro-declared-in-class-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class-object/Impls_1.scala b/test/files/run/macro-declared-in-class-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-class-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala new file mode 100644 index 0000000000..994f9fe935 --- /dev/null +++ b/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class Macros { + object Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = new Macros() + outer.Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class.check b/test/files/run/macro-declared-in-class.check new file mode 100644 index 0000000000..946851e4bb --- /dev/null +++ b/test/files/run/macro-declared-in-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Macros()) +it works diff --git a/test/files/run/macro-declared-in-class.flags b/test/files/run/macro-declared-in-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-class/Impls_1.scala b/test/files/run/macro-declared-in-class/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class/Macros_Test_2.scala new file mode 100644 index 0000000000..1b9d13e775 --- /dev/null +++ b/test/files/run/macro-declared-in-class/Macros_Test_2.scala @@ -0,0 +1,7 @@ +class Macros { + def foo = macro Impls.foo +} + +object Test extends App { + new Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param.check b/test/files/run/macro-declared-in-default-param.check new file mode 100644 index 0000000000..00052ad018 --- /dev/null +++ b/test/files/run/macro-declared-in-default-param.check @@ -0,0 +1,5 @@ +prefix = Expr[Nothing]() +it works +it works +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-declared-in-default-param.flags b/test/files/run/macro-declared-in-default-param.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-default-param.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-default-param/Impls_1.scala b/test/files/run/macro-declared-in-default-param/Impls_1.scala new file mode 100644 index 0000000000..e45095812a --- /dev/null +++ b/test/files/run/macro-declared-in-default-param/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Literal(Constant("it works"))) + Expr[String](body) + } +} diff --git a/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala b/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala new file mode 100644 index 0000000000..356029e63e --- /dev/null +++ b/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Test extends App { + def foo(bar: String = { def foo = macro Impls.foo; foo }) = println(bar) + + foo() + foo("it works") + foo() +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class.check b/test/files/run/macro-declared-in-implicit-class.check new file mode 100644 index 0000000000..b3640ceaa7 --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros.foo("2")) +Some(2) diff --git a/test/files/run/macro-declared-in-implicit-class.flags b/test/files/run/macro-declared-in-implicit-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala new file mode 100644 index 0000000000..8605d4a8be --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala @@ -0,0 +1,19 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def toOptionOfInt(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, newTermName("x")), newTermName("toInt"))))) + Expr[Option[Int]](body) + } +} + +object Macros { + implicit def foo(x: String): Foo = new Foo(x) + + class Foo(val x: String) { + def toOptionOfInt = macro Impls.toOptionOfInt + } +} diff --git a/test/files/run/macro-declared-in-implicit-class/Test_2.scala b/test/files/run/macro-declared-in-implicit-class/Test_2.scala new file mode 100644 index 0000000000..d0bc9cc38c --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + println("2".toOptionOfInt) +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method.check b/test/files/run/macro-declared-in-method.check new file mode 100644 index 0000000000..a61fd13087 --- /dev/null +++ b/test/files/run/macro-declared-in-method.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing]() +it works diff --git a/test/files/run/macro-declared-in-method.flags b/test/files/run/macro-declared-in-method.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-method.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-method/Impls_1.scala b/test/files/run/macro-declared-in-method/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-method/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-method/Macros_Test_2.scala b/test/files/run/macro-declared-in-method/Macros_Test_2.scala new file mode 100644 index 0000000000..ed5c8b7c43 --- /dev/null +++ b/test/files/run/macro-declared-in-method/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Test extends App { + def bar() = { + def foo = macro Impls.foo + foo + } + + bar() +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class.check b/test/files/run/macro-declared-in-object-class.check new file mode 100644 index 0000000000..480c2f906f --- /dev/null +++ b/test/files/run/macro-declared-in-object-class.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](new Test.this.outer.Macros()) +it works diff --git a/test/files/run/macro-declared-in-object-class.flags b/test/files/run/macro-declared-in-object-class.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object-class.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-class/Impls_1.scala b/test/files/run/macro-declared-in-object-class/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-object-class/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala new file mode 100644 index 0000000000..204deed61c --- /dev/null +++ b/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + class Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = Macros + new outer.Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object.check b/test/files/run/macro-declared-in-object-object.check new file mode 100644 index 0000000000..f7ba5a53cb --- /dev/null +++ b/test/files/run/macro-declared-in-object-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.outer.Macros) +it works diff --git a/test/files/run/macro-declared-in-object-object.flags b/test/files/run/macro-declared-in-object-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object-object/Impls_1.scala b/test/files/run/macro-declared-in-object-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-object-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala new file mode 100644 index 0000000000..e261a50f3d --- /dev/null +++ b/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + object Macros { + def foo = macro Impls.foo + } +} + +object Test extends App { + val outer = Macros + outer.Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object.check b/test/files/run/macro-declared-in-object.check new file mode 100644 index 0000000000..05a8cc48ea --- /dev/null +++ b/test/files/run/macro-declared-in-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros) +it works diff --git a/test/files/run/macro-declared-in-object.flags b/test/files/run/macro-declared-in-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-object/Impls_1.scala b/test/files/run/macro-declared-in-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object/Macros_Test_2.scala new file mode 100644 index 0000000000..a5a4862ba0 --- /dev/null +++ b/test/files/run/macro-declared-in-object/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object.check b/test/files/run/macro-declared-in-package-object.check new file mode 100644 index 0000000000..6f797f3c68 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Macros.`package`) +it works diff --git a/test/files/run/macro-declared-in-package-object.flags b/test/files/run/macro-declared-in-package-object.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-package-object/Impls_1.scala b/test/files/run/macro-declared-in-package-object/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala new file mode 100644 index 0000000000..54a5962e80 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala @@ -0,0 +1,8 @@ +package object Macros { + def foo = macro Impls.foo +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement.check b/test/files/run/macro-declared-in-refinement.check new file mode 100644 index 0000000000..861cd43b01 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement.check @@ -0,0 +1,2 @@ +prefix = Expr[Nothing](Test.this.macros) +it works diff --git a/test/files/run/macro-declared-in-refinement.flags b/test/files/run/macro-declared-in-refinement.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-refinement/Impls_1.scala b/test/files/run/macro-declared-in-refinement/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala new file mode 100644 index 0000000000..f746c2da57 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala @@ -0,0 +1,6 @@ +class Base + +object Test extends App { + val macros = new Base { def foo = macro Impls.foo } + macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-declared-in-trait.check b/test/files/run/macro-declared-in-trait.check new file mode 100644 index 0000000000..d5d9e4e457 --- /dev/null +++ b/test/files/run/macro-declared-in-trait.check @@ -0,0 +1,15 @@ +prefix = Expr[Nothing]({ + final class $anon extends Object with Base { + def (): anonymous class $anon = { + $anon.super.(); + () + }; + + }; + new $anon() +}) +it works +prefix = Expr[Nothing](Macros) +it works +prefix = Expr[Nothing](new Macros()) +it works diff --git a/test/files/run/macro-declared-in-trait.flags b/test/files/run/macro-declared-in-trait.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-trait.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-declared-in-trait/Impls_1.scala b/test/files/run/macro-declared-in-trait/Impls_1.scala new file mode 100644 index 0000000000..c2e6933582 --- /dev/null +++ b/test/files/run/macro-declared-in-trait/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.mirror._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-declared-in-trait/Macros_Test_2.scala b/test/files/run/macro-declared-in-trait/Macros_Test_2.scala new file mode 100644 index 0000000000..f75906b636 --- /dev/null +++ b/test/files/run/macro-declared-in-trait/Macros_Test_2.scala @@ -0,0 +1,13 @@ +trait Base { + def foo = macro Impls.foo +} + +object Macros extends Base + +class Macros extends Base + +object Test extends App { + (new Base {}).foo + Macros.foo + new Macros().foo +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.check b/test/files/run/macro-def-infer-return-type-a.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.flags b/test/files/run/macro-def-infer-return-type-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a/Impls_1.scala b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala new file mode 100644 index 0000000000..2346a6106d --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} diff --git a/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala new file mode 100644 index 0000000000..60fe9dc1c2 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo(x: Int) = macro Impls.foo + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b.check b/test/files/run/macro-def-infer-return-type-b.check new file mode 100644 index 0000000000..f34d257c82 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b.check @@ -0,0 +1,6 @@ +reflective compilation has failed: + +exception during macro expansion: +java.lang.Error: an implementation is missing + at Impls$.foo(Impls_Macros_1.scala:5) + diff --git a/test/files/run/macro-def-infer-return-type-b.flags b/test/files/run/macro-def-infer-return-type-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..8640713846 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T](c: Ctx)(x: c.Expr[T]) = + throw new Error("an implementation is missing") +} + +object Macros { + def foo[T](x: T) = macro Impls.foo[T] +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Test_2.scala b/test/files/run/macro-def-infer-return-type-b/Test_2.scala new file mode 100644 index 0000000000..8ff4494750 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c.check b/test/files/run/macro-def-infer-return-type-c.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c.flags b/test/files/run/macro-def-infer-return-type-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c/Impls_1.scala b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala new file mode 100644 index 0000000000..f3e53bbea7 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T](c: Ctx)(x: c.Expr[T]): c.Expr[T] = x +} diff --git a/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala new file mode 100644 index 0000000000..967d16f6de --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[T](x: T) = macro Impls.foo[T] + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-a.check b/test/files/run/macro-def-path-dependent-a.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-a.flags b/test/files/run/macro-def-path-dependent-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..d7167e671c --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala @@ -0,0 +1,21 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + + type Expr[T] + + def reify[T](expr: T) = macro Impls.reify[T] +} + +trait Universe extends Exprs with Reifiers + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Reifiers })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-a/Test_2.scala b/test/files/run/macro-def-path-dependent-a/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b.check b/test/files/run/macro-def-path-dependent-b.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-b.flags b/test/files/run/macro-def-path-dependent-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..44af6949a7 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala @@ -0,0 +1,20 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + +} + +trait Universe extends Exprs with Reifiers { + def reify[T](expr: T) = macro Impls.reify[T] +} + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-b/Test_2.scala b/test/files/run/macro-def-path-dependent-b/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c.check b/test/files/run/macro-def-path-dependent-c.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-c.flags b/test/files/run/macro-def-path-dependent-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala new file mode 100644 index 0000000000..305146c48b --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala @@ -0,0 +1,20 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Exprs { + self: Universe => + + class Expr[T] +} + +trait Reifiers { + self: Universe => + +} + +trait Universe extends Exprs with Reifiers { + def reify[T](expr: T): Expr[T] = macro Impls.reify[T] +} + +object Impls { + def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-c/Test_2.scala b/test/files/run/macro-def-path-dependent-c/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d.check b/test/files/run/macro-def-path-dependent-d.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-def-path-dependent-d.flags b/test/files/run/macro-def-path-dependent-d.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala new file mode 100644 index 0000000000..32f03e778e --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.Context +import scala.reflect.api.Universe + +object Test { + def materializeTypeTag[T](u: Universe)(e: T) = macro materializeTypeTag_impl[T] + + def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ??? +} diff --git a/test/files/run/macro-def-path-dependent-d/Test_2.scala b/test/files/run/macro-def-path-dependent-d/Test_2.scala new file mode 100644 index 0000000000..7dffc5107d --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println("it works") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit.check b/test/files/run/macro-expand-implicit-macro-has-implicit.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit.flags b/test/files/run/macro-expand-implicit-macro-has-implicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala new file mode 100644 index 0000000000..39db275e1c --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(x.tree)) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala new file mode 100644 index 0000000000..ffb04dc80b --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + implicit val x = 42 + def foo(implicit x: Int) = macro Impls.foo + foo +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit.check b/test/files/run/macro-expand-implicit-macro-is-implicit.check new file mode 100644 index 0000000000..42abf4579b --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit.check @@ -0,0 +1,2 @@ +Some(2) +2 diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit.flags b/test/files/run/macro-expand-implicit-macro-is-implicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala new file mode 100644 index 0000000000..0262485994 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[String]): c.Expr[Option[Int]] = { + import c.mirror._ + val body = Apply(Ident(definitions.SomeModule), List(Select(x.tree, newTermName("toInt")))) + Expr[Option[Int]](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala new file mode 100644 index 0000000000..81ebd63c5f --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + implicit def foo(x: String): Option[Int] = macro Impls.foo +} + +object Test extends App { + import Macros._ + println("2": Option[Int]) + val s: Int = "2" getOrElse 0 + println(s) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-val.check b/test/files/run/macro-expand-implicit-macro-is-val.check new file mode 100644 index 0000000000..78c6baefdd --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val.check @@ -0,0 +1 @@ +2 diff --git a/test/files/run/macro-expand-implicit-macro-is-val.flags b/test/files/run/macro-expand-implicit-macro-is-val.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala new file mode 100644 index 0000000000..510d8502f6 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Literal(Constant(2)) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala new file mode 100644 index 0000000000..b91b1016c9 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + implicit def foo = macro Impls.foo + def bar(implicit x: Int) = println(x) + bar +} \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-view.check b/test/files/run/macro-expand-implicit-macro-is-view.check new file mode 100644 index 0000000000..78c6baefdd --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view.check @@ -0,0 +1 @@ +2 diff --git a/test/files/run/macro-expand-implicit-macro-is-view.flags b/test/files/run/macro-expand-implicit-macro-is-view.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala new file mode 100644 index 0000000000..0262485994 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[String]): c.Expr[Option[Int]] = { + import c.mirror._ + val body = Apply(Ident(definitions.SomeModule), List(Select(x.tree, newTermName("toInt")))) + Expr[Option[Int]](body) + } +} diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala new file mode 100644 index 0000000000..0ff1fb80ca --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala @@ -0,0 +1,9 @@ +object Macros { + implicit def foo(x: String): Option[Int] = macro Impls.foo +} + +object Test extends App { + import Macros._ + def bar[T <% Option[Int]](x: T) = println(x) + println("2") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists.check b/test/files/run/macro-expand-multiple-arglists.check new file mode 100644 index 0000000000..c24b6ae77d --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists.check @@ -0,0 +1 @@ +38 \ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists.flags b/test/files/run/macro-expand-multiple-arglists.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists/Impls_1.scala b/test/files/run/macro-expand-multiple-arglists/Impls_1.scala new file mode 100644 index 0000000000..ae1c50eace --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int])(y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala new file mode 100644 index 0000000000..fa4504b0ea --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo(x: Int)(y: Int) = macro Impls.foo + foo(40)(2) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic.check b/test/files/run/macro-expand-nullary-generic.check new file mode 100644 index 0000000000..34a453cd3a --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic.check @@ -0,0 +1,6 @@ +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +kkthxbai diff --git a/test/files/run/macro-expand-nullary-generic.flags b/test/files/run/macro-expand-nullary-generic.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic/Impls_1.scala b/test/files/run/macro-expand-nullary-generic/Impls_1.scala new file mode 100644 index 0000000000..10352594f5 --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic/Impls_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl[T: c.TypeTag](c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works " + implicitly[c.TypeTag[T]])))) + Expr[Unit](body) + } + + def fooNullary[T: c.TypeTag](c: Ctx) = impl[T](c) + def fooEmpty[T: c.TypeTag](c: Ctx)() = impl[T](c) + def barNullary[T: c.TypeTag](c: Ctx)(x: c.Expr[Int]) = impl[T](c) + def barEmpty[T: c.TypeTag](c: Ctx)(x: c.Expr[Int])() = impl[T](c) +} diff --git a/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala new file mode 100644 index 0000000000..2d5cf53c3c --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala @@ -0,0 +1,15 @@ +object Macros { + def foo1[T] = macro Impls.fooNullary[T] + def foo2[T]() = macro Impls.fooEmpty[T] + def bar1[T](x: Int) = macro Impls.barNullary[T] + def bar2[T](x: Int)() = macro Impls.barEmpty[T] +} + +object Test extends App { + Macros.foo1[Int] + Macros.foo2[Int] + Macros.foo2[Int]() + Macros.bar1[Int](42) + Macros.bar2[Int](42)() + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-nongeneric.check b/test/files/run/macro-expand-nullary-nongeneric.check new file mode 100644 index 0000000000..9ab5f3a2bc --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric.check @@ -0,0 +1,6 @@ +it works +it works +it works +it works +it works +kkthxbai diff --git a/test/files/run/macro-expand-nullary-nongeneric.flags b/test/files/run/macro-expand-nullary-nongeneric.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala new file mode 100644 index 0000000000..7dc58abba8 --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooNullary(c: Ctx) = impl(c) + def fooEmpty(c: Ctx)() = impl(c) + def barNullary(c: Ctx)(x: c.Expr[Int]) = impl(c) + def barEmpty(c: Ctx)(x: c.Expr[Int])() = impl(c) +} diff --git a/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala new file mode 100644 index 0000000000..1f6d717956 --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala @@ -0,0 +1,15 @@ +object Macros { + def foo1 = macro Impls.fooNullary + def foo2() = macro Impls.fooEmpty + def bar1(x: Int) = macro Impls.barNullary + def bar2(x: Int)() = macro Impls.barEmpty +} + +object Test extends App { + Macros.foo1 + Macros.foo2 + Macros.foo2() + Macros.bar1(42) + Macros.bar2(42)() + println("kkthxbai") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-overload.check b/test/files/run/macro-expand-overload.check new file mode 100644 index 0000000000..9d9989d85f --- /dev/null +++ b/test/files/run/macro-expand-overload.check @@ -0,0 +1,6 @@ +(fooObjectString,Expr[Nothing](Macros),42) +(fooObjectInt,Expr[Nothing](Macros),42) +fooObjectBoolean +(fooClassString,Expr[Nothing](new Macros()),42) +(fooClassInt,Expr[Nothing](new Macros()),42) +fooClassBoolean diff --git a/test/files/run/macro-expand-overload.flags b/test/files/run/macro-expand-overload.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-overload.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-overload/Impls_1.scala b/test/files/run/macro-expand-overload/Impls_1.scala new file mode 100644 index 0000000000..1dc4adc20e --- /dev/null +++ b/test/files/run/macro-expand-overload/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(tag: String, x: c.Expr[_]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree)) + Expr[Unit](body) + } + + def fooObjectString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooObjectString", x) + def fooObjectInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooObjectInt", x) + def fooClassString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooClassString", x) + def fooClassInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooClassInt", x) +} diff --git a/test/files/run/macro-expand-overload/Macros_Test_2.scala b/test/files/run/macro-expand-overload/Macros_Test_2.scala new file mode 100644 index 0000000000..7f61f85184 --- /dev/null +++ b/test/files/run/macro-expand-overload/Macros_Test_2.scala @@ -0,0 +1,20 @@ +object Macros { + def foo(x: String) = macro Impls.fooObjectString + def foo(x: Int) = macro Impls.fooObjectInt + def foo(x: Boolean) = println("fooObjectBoolean") +} + +class Macros { + def foo(x: String) = macro Impls.fooClassString + def foo(x: Int) = macro Impls.fooClassInt + def foo(x: Boolean) = println("fooClassBoolean") +} + +object Test extends App { + Macros.foo("42") + Macros.foo(42) + Macros.foo(true) + new Macros().foo("42") + new Macros().foo(42) + new Macros().foo(true) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-override.check b/test/files/run/macro-expand-override.check new file mode 100644 index 0000000000..486bec7098 --- /dev/null +++ b/test/files/run/macro-expand-override.check @@ -0,0 +1,15 @@ +(fooBString,Expr[Nothing](Test.this.dd),42) +(fooDInt,Expr[Nothing](Test.this.dd),42) +fooBBoolean +(fooBString,Expr[Nothing](Test.this.db),42) +(fooBInt,Expr[Nothing](Test.this.db),42) +fooBBoolean +(fooZString,Expr[Nothing](Test.this.zz),42) +(fooDInt,Expr[Nothing](Test.this.zz),42) +fooZBoolean +(fooBString,Expr[Nothing](Test.this.zd),42) +(fooDInt,Expr[Nothing](Test.this.zd),42) +fooZBoolean +(fooBString,Expr[Nothing](Test.this.zb),42) +(fooBInt,Expr[Nothing](Test.this.zb),42) +fooZBoolean diff --git a/test/files/run/macro-expand-override.flags b/test/files/run/macro-expand-override.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-override.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-override/Impls_1.scala b/test/files/run/macro-expand-override/Impls_1.scala new file mode 100644 index 0000000000..0b127f5a59 --- /dev/null +++ b/test/files/run/macro-expand-override/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def impl(c: Ctx)(tag: String, x: c.Expr[_]) = { + import c.{prefix => prefix} + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree)) + Expr[Unit](body) + } + + def fooBString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBString", x) + def fooBInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBInt", x) + def fooDInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooDInt", x) + def fooZString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooZString", x) +} diff --git a/test/files/run/macro-expand-override/Macros_Test_2.scala b/test/files/run/macro-expand-override/Macros_Test_2.scala new file mode 100644 index 0000000000..f162773c95 --- /dev/null +++ b/test/files/run/macro-expand-override/Macros_Test_2.scala @@ -0,0 +1,43 @@ +class B { + def foo(x: String) = macro Impls.fooBString + def foo(x: Int) = macro Impls.fooBInt + def foo(x: Boolean) = println("fooBBoolean") +} + +class D extends B { + //override def foo(x: String) = println("fooDString") => method cannot override a macro + override def foo(x: Int) = macro Impls.fooDInt +} + +class Z extends D { + override def foo(x: String) = macro Impls.fooZString + override def foo(x: Boolean) = println("fooZBoolean") +} + +object Test extends App { + + val dd: D = new D() + dd.foo("42") + dd.foo(42) + dd.foo(true) + + val db: B = new D() + db.foo("42") + db.foo(42) + db.foo(true) + + val zz: Z = new Z() + zz.foo("42") + zz.foo(42) + zz.foo(true) + + val zd: D = new Z() + zd.foo("42") + zd.foo(42) + zd.foo(true) + + val zb: B = new Z() + zb.foo("42") + zb.foo(42) + zb.foo(true) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-recursive.check b/test/files/run/macro-expand-recursive.check new file mode 100644 index 0000000000..1ea14b4e20 --- /dev/null +++ b/test/files/run/macro-expand-recursive.check @@ -0,0 +1 @@ +it works diff --git a/test/files/run/macro-expand-recursive.flags b/test/files/run/macro-expand-recursive.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-recursive.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-recursive/Impls_1.scala b/test/files/run/macro-expand-recursive/Impls_1.scala new file mode 100644 index 0000000000..6eff805989 --- /dev/null +++ b/test/files/run/macro-expand-recursive/Impls_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))) + Expr[Unit](body) + } + + def fooFoo(c: Ctx) = { + import c.mirror._ + val body = Select(Ident(newTermName("Macros")), newTermName("foo")) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-recursive/Macros_Test_2.scala b/test/files/run/macro-expand-recursive/Macros_Test_2.scala new file mode 100644 index 0000000000..6ff691bdb1 --- /dev/null +++ b/test/files/run/macro-expand-recursive/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo + def fooFoo = macro Impls.fooFoo +} + +object Test extends App { + Macros.fooFoo +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a.check b/test/files/run/macro-expand-tparams-bounds-a.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-expand-tparams-bounds-a.flags b/test/files/run/macro-expand-tparams-bounds-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala new file mode 100644 index 0000000000..4cd98c5838 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx): c.Expr[Unit] = { + import c.mirror._ + Literal(Constant(())) + } +} diff --git a/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala new file mode 100644 index 0000000000..b498e6f65b --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo[U <: String] = macro Impls.foo[U] +} + +object Test extends App { + import Macros._ + foo[String] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b.check b/test/files/run/macro-expand-tparams-bounds-b.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-expand-tparams-bounds-b.flags b/test/files/run/macro-expand-tparams-bounds-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala new file mode 100644 index 0000000000..9103ddb08a --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +class C + +object Impls { + def foo[U <: C](c: Ctx): c.Expr[Unit] = { + import c.mirror._ + Literal(Constant(())) + } +} diff --git a/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala new file mode 100644 index 0000000000..1a261e9f73 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala @@ -0,0 +1,10 @@ +class D extends C + +object Macros { + def foo[T <: D] = macro Impls.foo[T] +} + +object Test extends App { + import Macros._ + foo[D] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-explicit.check b/test/files/run/macro-expand-tparams-explicit.check new file mode 100644 index 0000000000..54da026aa8 --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit.check @@ -0,0 +1 @@ +GroundTypeTag[Int] diff --git a/test/files/run/macro-expand-tparams-explicit.flags b/test/files/run/macro-expand-tparams-explicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-explicit/Impls_1.scala b/test/files/run/macro-expand-tparams-explicit/Impls_1.scala new file mode 100644 index 0000000000..957d8331fc --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx) = { + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala new file mode 100644 index 0000000000..e72c27881a --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[U] = macro Impls.foo[U] + foo[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-implicit.check b/test/files/run/macro-expand-tparams-implicit.check new file mode 100644 index 0000000000..60c021a35b --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-implicit.flags b/test/files/run/macro-expand-tparams-implicit.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-implicit/Impls_1.scala b/test/files/run/macro-expand-tparams-implicit/Impls_1.scala new file mode 100644 index 0000000000..c25d12be60 --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = { + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala new file mode 100644 index 0000000000..f8c573f509 --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + def foo[U](x: U) = macro Impls.foo[U] + foo(42) + foo("42") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-only-in-impl.flags b/test/files/run/macro-expand-tparams-only-in-impl.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-only-in-impl.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala new file mode 100644 index 0000000000..4cd98c5838 --- /dev/null +++ b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U <: String](c: Ctx): c.Expr[Unit] = { + import c.mirror._ + Literal(Constant(())) + } +} diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala new file mode 100644 index 0000000000..218c7aec7f --- /dev/null +++ b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo = macro Impls.foo[String] +} + +object Test extends App { + import Macros._ + foo +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional.check b/test/files/run/macro-expand-tparams-optional.check new file mode 100644 index 0000000000..3bacd7a4e0 --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional.check @@ -0,0 +1 @@ +don't know U diff --git a/test/files/run/macro-expand-tparams-optional.flags b/test/files/run/macro-expand-tparams-optional.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional/Impls_1.scala b/test/files/run/macro-expand-tparams-optional/Impls_1.scala new file mode 100644 index 0000000000..37efb009c4 --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U](c: Ctx) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("don't know U")))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala new file mode 100644 index 0000000000..e72c27881a --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[U] = macro Impls.foo[U] + foo[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check new file mode 100644 index 0000000000..1447c2478f --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a.check @@ -0,0 +1,4 @@ +GroundTypeTag[Int] +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-a.flags b/test/files/run/macro-expand-tparams-prefix-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala new file mode 100644 index 0000000000..c25d12be60 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = { + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala new file mode 100644 index 0000000000..81ccb7ff42 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Test extends App { + class C[T] { + def foo[U](x: U) = macro Impls.foo[U] + } + + new C[Int]().foo(42) + new C[Boolean]().foo(42) + new C[Int]().foo("42") + new C[String]().foo(true) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check new file mode 100644 index 0000000000..c7ec594b92 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b.check @@ -0,0 +1,2 @@ +GroundTypeTag[Boolean] GroundTypeTag[Int] +GroundTypeTag[Boolean] GroundTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-b.flags b/test/files/run/macro-expand-tparams-prefix-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala new file mode 100644 index 0000000000..8af3ecc9ae --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T: c.TypeTag, U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = { + import c.mirror._ + val T = implicitly[c.TypeTag[T]] + val U = implicitly[c.TypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString + " " + U.toString)))) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala new file mode 100644 index 0000000000..a4a0acfe8b --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Test extends App { + class C[T] { + def foo[U](x: U) = macro Impls.foo[T, U] + } + + object D extends C[Boolean] + + D.foo(42) + D.foo("42") +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check new file mode 100644 index 0000000000..fac58e9516 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1.check @@ -0,0 +1,3 @@ +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c1.flags b/test/files/run/macro-expand-tparams-prefix-c1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala new file mode 100644 index 0000000000..4fa0c8cb33 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala @@ -0,0 +1,11 @@ +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[T, U, V] + } +} + +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check new file mode 100644 index 0000000000..fac58e9516 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2.check @@ -0,0 +1,3 @@ +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c2.flags b/test/files/run/macro-expand-tparams-prefix-c2.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala new file mode 100644 index 0000000000..c83e401afb --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} + +class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[T, U, V] + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala new file mode 100644 index 0000000000..e729d4a536 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo[Boolean] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1.check b/test/files/run/macro-expand-tparams-prefix-d1.check new file mode 100644 index 0000000000..f78ddea4f3 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1.check @@ -0,0 +1,3 @@ +TypeTag[T] +TypeTag[U] +GroundTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-d1.flags b/test/files/run/macro-expand-tparams-prefix-d1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala new file mode 100644 index 0000000000..8222a6d1e8 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala @@ -0,0 +1,11 @@ +object Test extends App { + class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[T, U, V] + foo[Boolean] + } + } + + val outer1 = new D[Int] + new outer1.C[String] +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check new file mode 100644 index 0000000000..fd1d654cf8 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check @@ -0,0 +1,4 @@ +reflective compilation has failed: + +no `: _*' annotation allowed here +(such annotations are only allowed in arguments to *-parameters) diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala new file mode 100644 index 0000000000..d97f0af786 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala new file mode 100644 index 0000000000..523c6b0645 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Typed(Apply(Ident(definitions.ListModule), List(Literal(Constant(1)), Literal(Constant(2)))), Ident(tpnme.WILDCARD_STAR)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check new file mode 100644 index 0000000000..835137b4a2 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check @@ -0,0 +1 @@ +List(1, 2, 3, 4, 5) diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala new file mode 100644 index 0000000000..f9667d78b8 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val stripped_xs = xs map (_.tree) toList match { + case List(Typed(stripped, Ident(wildstar))) if wildstar == tpnme.WILDCARD_STAR => List(stripped) + case _ => ??? + } + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), stripped_xs) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala new file mode 100644 index 0000000000..f127ebcde7 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + val numbers = List(1, 2, 3, 4, 5) + Macros.foo(numbers: _*) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs.check b/test/files/run/macro-expand-varargs-explicit-over-varargs.check new file mode 100644 index 0000000000..835137b4a2 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.check @@ -0,0 +1 @@ +List(1, 2, 3, 4, 5) diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs.flags b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala new file mode 100644 index 0000000000..8c609daa0e --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def myprintln(xs: Int*) = { + println(xs) + } + + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(newTermName("Impls")), newTermName("myprintln")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala new file mode 100644 index 0000000000..f127ebcde7 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + val numbers = List(1, 2, 3, 4, 5) + Macros.foo(numbers: _*) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check new file mode 100644 index 0000000000..0a6596858c --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check @@ -0,0 +1 @@ +(1,2,3,4,5) diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala new file mode 100644 index 0000000000..d97f0af786 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala new file mode 100644 index 0000000000..2311ca0b95 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + Macros.foo(1, 2, 3, 4, 5) +} \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs.check b/test/files/run/macro-expand-varargs-implicit-over-varargs.check new file mode 100644 index 0000000000..f25fa141d3 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.check @@ -0,0 +1 @@ +WrappedArray(1, 2, 3, 4, 5) diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs.flags b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala b/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala new file mode 100644 index 0000000000..8c609daa0e --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def myprintln(xs: Int*) = { + println(xs) + } + + def foo(c: Ctx)(xs: c.Expr[Int]*) = { + import c.mirror._ + val body = Apply(Select(Ident(newTermName("Impls")), newTermName("myprintln")), xs.map(_.tree).toList) + Expr[Unit](body) + } +} diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala new file mode 100644 index 0000000000..2311ca0b95 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala @@ -0,0 +1,7 @@ +object Macros { + def foo(xs: Int*) = macro Impls.foo +} + +object Test extends App { + Macros.foo(1, 2, 3, 4, 5) +} \ No newline at end of file diff --git a/test/files/run/macro-impl-default-params.check b/test/files/run/macro-impl-default-params.check new file mode 100644 index 0000000000..eaf94458e6 --- /dev/null +++ b/test/files/run/macro-impl-default-params.check @@ -0,0 +1,5 @@ +foo_targs: +invoking foo_targs... +type of prefix is: Nothing +type of prefix tree is: Macros[Int] +U is: String diff --git a/test/files/run/macro-impl-default-params.flags b/test/files/run/macro-impl-default-params.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-impl-default-params.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-impl-default-params/Impls_Macros_1.scala b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala new file mode 100644 index 0000000000..cece1c09e4 --- /dev/null +++ b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala @@ -0,0 +1,20 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo_targs[T, U: c.TypeTag](c: Ctx = null)(x: c.Expr[Int] = null) = { + import c.{prefix => prefix} + import c.mirror._ + val U = implicitly[c.TypeTag[U]] + val body = Block( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.tpe)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix tree is: " + prefix.tree.tpe)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + U.tpe)))), + Literal(Constant(()))) + Expr[Unit](body) + } +} + +class Macros[T] { + def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U] +} diff --git a/test/files/run/macro-impl-default-params/Test_2.scala b/test/files/run/macro-impl-default-params/Test_2.scala new file mode 100644 index 0000000000..90e850df21 --- /dev/null +++ b/test/files/run/macro-impl-default-params/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println("foo_targs:") + new Macros[Int]().foo_targs[String](42) +} \ No newline at end of file diff --git a/test/files/run/macro-impl-rename-context.check b/test/files/run/macro-impl-rename-context.check new file mode 100644 index 0000000000..753edcd970 --- /dev/null +++ b/test/files/run/macro-impl-rename-context.check @@ -0,0 +1,2 @@ +foo +invoking foo... diff --git a/test/files/run/macro-impl-rename-context.flags b/test/files/run/macro-impl-rename-context.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-impl-rename-context.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala new file mode 100644 index 0000000000..000e351f4d --- /dev/null +++ b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(unconventionalName: Ctx)(x: unconventionalName.Expr[Int]) = { + import unconventionalName.mirror._ + val body = Block( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo...")))), + Literal(Constant(()))) + Expr[Unit](body) + } +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-impl-rename-context/Test_2.scala b/test/files/run/macro-impl-rename-context/Test_2.scala new file mode 100644 index 0000000000..bd9c493544 --- /dev/null +++ b/test/files/run/macro-impl-rename-context/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println("foo") + Macros.foo(42) +} \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check new file mode 100644 index 0000000000..e21e05157a --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check @@ -0,0 +1,5 @@ +reflective compilation has failed: + +type mismatch; + found : String("42") + required: Int diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala new file mode 100644 index 0000000000..882867fcab --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx): c.Expr[Int] = { + import c.mirror._ + Literal(Constant("42")) + } +} + +object Macros { + def foo: Int = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala new file mode 100644 index 0000000000..f389231ca6 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Select(Ident("Macros"), newTermName("foo")) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-nontypeable.check b/test/files/run/macro-invalidret-nontypeable.check new file mode 100644 index 0000000000..eee08528e2 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +not found: value IDoNotExist diff --git a/test/files/run/macro-invalidret-nontypeable.flags b/test/files/run/macro-invalidret-nontypeable.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala new file mode 100644 index 0000000000..f3a0476a35 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.mirror._ + val body = Ident("IDoNotExist") + Expr[Int](body) + } +} + +object Macros { + def foo = macro Impls.foo +} diff --git a/test/files/run/macro-invalidret-nontypeable/Test_2.scala b/test/files/run/macro-invalidret-nontypeable/Test_2.scala new file mode 100644 index 0000000000..f389231ca6 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Select(Ident("Macros"), newTermName("foo")) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-badret.check b/test/files/run/macro-invalidusage-badret.check new file mode 100644 index 0000000000..5bdc484644 --- /dev/null +++ b/test/files/run/macro-invalidusage-badret.check @@ -0,0 +1,5 @@ +reflective compilation has failed: + +type mismatch; + found : Int(42) + required: String diff --git a/test/files/run/macro-invalidusage-badret.flags b/test/files/run/macro-invalidusage-badret.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidusage-badret.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala b/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala new file mode 100644 index 0000000000..c63ad01677 --- /dev/null +++ b/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = x +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-invalidusage-badret/Test_2.scala b/test/files/run/macro-invalidusage-badret/Test_2.scala new file mode 100644 index 0000000000..e171c9d05a --- /dev/null +++ b/test/files/run/macro-invalidusage-badret/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Typed(Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))), Ident(newTypeName("String"))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication.check b/test/files/run/macro-invalidusage-partialapplication.check new file mode 100644 index 0000000000..73f57b0b81 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +macros cannot be partially applied diff --git a/test/files/run/macro-invalidusage-partialapplication.flags b/test/files/run/macro-invalidusage-partialapplication.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala b/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala new file mode 100644 index 0000000000..449b91d074 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int])(y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$plus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} + +object Macros { + def foo(x: Int)(y: Int) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala new file mode 100644 index 0000000000..63371a4a82 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(40)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} diff --git a/test/files/run/macro-openmacros.check b/test/files/run/macro-openmacros.check new file mode 100644 index 0000000000..a4b06a1e1a --- /dev/null +++ b/test/files/run/macro-openmacros.check @@ -0,0 +1,3 @@ +List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0)) +List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +1), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0)) +List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +2), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +1), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0)) diff --git a/test/files/run/macro-openmacros.flags b/test/files/run/macro-openmacros.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-openmacros.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-openmacros/Impls_Macros_1.scala b/test/files/run/macro-openmacros/Impls_Macros_1.scala new file mode 100644 index 0000000000..9fd658656e --- /dev/null +++ b/test/files/run/macro-openmacros/Impls_Macros_1.scala @@ -0,0 +1,26 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context): c.Expr[Unit] = { + // we're macros, so we can reflect against our source path + // so we don't need any partests to clean up after us! + val c.CompilationUnit(file, _, _) = c.enclosingUnit + val dir = file.getParentFile + def normalizePaths(s: String) = { + val base = (dir.getCanonicalPath + java.io.File.separator).replace('\\', '/') + var regex = """\Q%s\E""" format base + val isWin = System.getProperty("os.name", "") startsWith "Windows" + if (isWin) regex = "(?i)" + regex + s.replace('\\', '/').replaceAll(regex, "") + } + + import c.mirror._ + val next = if (c.enclosingMacros.length < 3) Expr[Unit](Select(Ident(staticModule("Macros")), newTermName("foo"))) else c.literalUnit + c.reify { + println(c.literal(normalizePaths(c.enclosingMacros.toString)).eval) + next.eval + } + } + + def foo = macro impl +} \ No newline at end of file diff --git a/test/files/run/macro-openmacros/Test_2.scala b/test/files/run/macro-openmacros/Test_2.scala new file mode 100644 index 0000000000..5d19639cdd --- /dev/null +++ b/test/files/run/macro-openmacros/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +} diff --git a/test/files/run/macro-quasiinvalidbody-c.check b/test/files/run/macro-quasiinvalidbody-c.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/files/run/macro-quasiinvalidbody-c.flags b/test/files/run/macro-quasiinvalidbody-c.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala b/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala new file mode 100644 index 0000000000..7cb810c86b --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = x + } + + def foo(x: Any) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-quasiinvalidbody-c/Test_2.scala b/test/files/run/macro-quasiinvalidbody-c/Test_2.scala new file mode 100644 index 0000000000..dec29aa857 --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/files/run/macro-range/Common_1.scala b/test/files/run/macro-range/Common_1.scala new file mode 100644 index 0000000000..bd46e1f529 --- /dev/null +++ b/test/files/run/macro-range/Common_1.scala @@ -0,0 +1,48 @@ +import reflect.api.Modifier +import reflect.makro.Context + +abstract class RangeDefault { + val from, to: Int + def foreach(f: Int => Unit) = { + var i = from + while (i < to) { f(i); i += 1 } + } +} + +/** This class should go into reflect.macro once it is a bit more stable. */ +abstract class Utils { + val context: Context + import context.mirror._ + + class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { + override def transform(tree: Tree): Tree = tree match { + case Ident(_) => + def subst(from: List[Symbol], to: List[Tree]): Tree = + if (from.isEmpty) tree + else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? + else subst(from.tail, to.tail); + subst(from, to) + case _ => + val tree1 = super.transform(tree) + if (tree1 ne tree) tree1.tpe = null + tree1 + } + } + def makeApply(fn: Tree, args: List[Tree]): Tree = fn match { + case Function(vparams, body) => + new TreeSubstituter(vparams map (_.symbol), args) transform body + case Block(stats, expr) => + Block(stats, makeApply(expr, args)) + case _ => + // todo. read the compiler config and print if -Ydebug is set + //println("no beta on "+fn+" "+fn.getClass) + Apply(fn, args) + } + def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { + val continu = Apply(Ident(lname), Nil) + val rhs = If(cond, Block(List(body), continu), Literal(Constant())) + LabelDef(lname, Nil, rhs) + } + def makeBinop(left: Tree, op: String, right: Tree): Tree = + Apply(Select(left, newTermName(op)), List(right)) +} diff --git a/test/files/run/macro-range/Expansion_Impossible_2.scala b/test/files/run/macro-range/Expansion_Impossible_2.scala new file mode 100644 index 0000000000..7a093b74ee --- /dev/null +++ b/test/files/run/macro-range/Expansion_Impossible_2.scala @@ -0,0 +1,53 @@ +import reflect.api.Modifier +import reflect.makro.Context + +object Impls { + def foreach(c: Context)(f: c.Expr[Int => Unit]): c.Expr[Unit] = { + // todo. read the compiler config and print if -Ydebug is set + //println("macro-expand, _this = "+ _this) + object utils extends Utils { val context: c.type = c } + import utils._ + import c.mirror._ + + val initName = newTermName("") + // Either: + // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } } + // or: + // scala"($_this: RangeDefault).foreach($f)" + c.prefix.tree match { + case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" => + val iname = newTermName("$i") + val hname = newTermName("$h") + def iref = Ident(iname) + def href = Ident(hname) + val labelname = newTermName("$while") + val cond = makeBinop(iref, "$less", href) + val body = Block( + List(makeApply(f, List(iref))), + Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1))))) + val generated = + Block( + List( + ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo), + ValDef(Modifiers(), hname, TypeTree(), hi)), + makeWhile(labelname, cond, body)) + // todo. read the compiler config and print if -Ydebug is set + //tools.nsc.util.trace("generated: ")(generated) + generated + case _ => + Apply( + Select( + Typed(c.prefix, Ident(newTypeName("RangeDefault"))), + newTermName("foreach")), + List(f)) + } + } +} + +class Range(val from: Int, val to: Int) extends RangeDefault { + override def foreach(f: Int => Unit): Unit = macro Impls.foreach +} + +object Test extends App { + new Range(1, 10) foreach println +} \ No newline at end of file diff --git a/test/files/run/macro-range/Expansion_Possible_3.scala b/test/files/run/macro-range/Expansion_Possible_3.scala new file mode 100644 index 0000000000..e7ecbcc362 --- /dev/null +++ b/test/files/run/macro-range/Expansion_Possible_3.scala @@ -0,0 +1,7 @@ +class Range(val from: Int, val to: Int) extends RangeDefault { + override def foreach(f: Int => Unit): Unit = macro Impls.foreach +} + +object Test extends App { + new Range(1, 10) foreach println +} \ No newline at end of file diff --git a/test/files/run/macro-range/macro_range_1.scala b/test/files/run/macro-range/macro_range_1.scala deleted file mode 100644 index fdfe7169ad..0000000000 --- a/test/files/run/macro-range/macro_range_1.scala +++ /dev/null @@ -1,99 +0,0 @@ -import reflect.api.Modifier -import reflect.macro.Context - -abstract class RangeDefault { - val from, to: Int - def foreach(f: Int => Unit) = { - var i = from - while (i < to) { f(i); i += 1 } - } -} - -/** This class should go into reflect.macro once it is a bit more stable. */ -abstract class Utils { - val context: Context - import context._ - - class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { - override def transform(tree: Tree): Tree = tree match { - case Ident(_) => - def subst(from: List[Symbol], to: List[Tree]): Tree = - if (from.isEmpty) tree - else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? - else subst(from.tail, to.tail); - subst(from, to) - case _ => - val tree1 = super.transform(tree) - if (tree1 ne tree) tree1.tpe = null - tree1 - } - } - def makeApply(fn: Tree, args: List[Tree]): Tree = fn match { - case Function(vparams, body) => - new TreeSubstituter(vparams map (_.symbol), args) transform body - case Block(stats, expr) => - Block(stats, makeApply(expr, args)) - case _ => - // todo. read the compiler config and print if -Ydebug is set - //println("no beta on "+fn+" "+fn.getClass) - Apply(fn, args) - } - def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { - val continu = Apply(Ident(lname), Nil) - val rhs = If(cond, Block(List(body), continu), Literal(Constant())) - LabelDef(lname, Nil, rhs) - } - def makeBinop(left: Tree, op: String, right: Tree): Tree = - Apply(Select(left, newTermName(op)), List(right)) -} - -class Range(val from: Int, val to: Int) extends RangeDefault { - override def macro foreach(f: Int => Unit): Unit = { - // todo. read the compiler config and print if -Ydebug is set - //println("macro-expand, _this = "+ _this) - import _context._ - object utils extends Utils { - val context: _context.type = _context - } - import utils._ - - val initName = newTermName("") - // Either: - // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } } - // or: - // scala"($_this: RangeDefault).foreach($f)" - _this match { - case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" => - val iname = newTermName("$i") - val hname = newTermName("$h") - def iref = Ident(iname) - def href = Ident(hname) - val labelname = newTermName("$while") - val cond = makeBinop(iref, "$less", href) - val body = Block( - List(makeApply(f, List(iref))), - Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1))))) - val generated = - Block( - List( - ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo), - ValDef(Modifiers(), hname, TypeTree(), hi)), - makeWhile(labelname, cond, body)) - // todo. read the compiler config and print if -Ydebug is set - //tools.nsc.util.trace("generated: ")(generated) - generated - case _ => - Apply( - Select( - Typed(_this, Ident(newTypeName("RangeDefault"))), - newTermName("foreach")), - List(f)) - } - } -} - -object Test extends App { - - new Range(1, 10) foreach println - -} diff --git a/test/files/run/macro-range/macro_range_2.scala b/test/files/run/macro-range/macro_range_2.scala deleted file mode 100644 index fdfe7169ad..0000000000 --- a/test/files/run/macro-range/macro_range_2.scala +++ /dev/null @@ -1,99 +0,0 @@ -import reflect.api.Modifier -import reflect.macro.Context - -abstract class RangeDefault { - val from, to: Int - def foreach(f: Int => Unit) = { - var i = from - while (i < to) { f(i); i += 1 } - } -} - -/** This class should go into reflect.macro once it is a bit more stable. */ -abstract class Utils { - val context: Context - import context._ - - class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { - override def transform(tree: Tree): Tree = tree match { - case Ident(_) => - def subst(from: List[Symbol], to: List[Tree]): Tree = - if (from.isEmpty) tree - else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? - else subst(from.tail, to.tail); - subst(from, to) - case _ => - val tree1 = super.transform(tree) - if (tree1 ne tree) tree1.tpe = null - tree1 - } - } - def makeApply(fn: Tree, args: List[Tree]): Tree = fn match { - case Function(vparams, body) => - new TreeSubstituter(vparams map (_.symbol), args) transform body - case Block(stats, expr) => - Block(stats, makeApply(expr, args)) - case _ => - // todo. read the compiler config and print if -Ydebug is set - //println("no beta on "+fn+" "+fn.getClass) - Apply(fn, args) - } - def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { - val continu = Apply(Ident(lname), Nil) - val rhs = If(cond, Block(List(body), continu), Literal(Constant())) - LabelDef(lname, Nil, rhs) - } - def makeBinop(left: Tree, op: String, right: Tree): Tree = - Apply(Select(left, newTermName(op)), List(right)) -} - -class Range(val from: Int, val to: Int) extends RangeDefault { - override def macro foreach(f: Int => Unit): Unit = { - // todo. read the compiler config and print if -Ydebug is set - //println("macro-expand, _this = "+ _this) - import _context._ - object utils extends Utils { - val context: _context.type = _context - } - import utils._ - - val initName = newTermName("") - // Either: - // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } } - // or: - // scala"($_this: RangeDefault).foreach($f)" - _this match { - case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" => - val iname = newTermName("$i") - val hname = newTermName("$h") - def iref = Ident(iname) - def href = Ident(hname) - val labelname = newTermName("$while") - val cond = makeBinop(iref, "$less", href) - val body = Block( - List(makeApply(f, List(iref))), - Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1))))) - val generated = - Block( - List( - ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo), - ValDef(Modifiers(), hname, TypeTree(), hi)), - makeWhile(labelname, cond, body)) - // todo. read the compiler config and print if -Ydebug is set - //tools.nsc.util.trace("generated: ")(generated) - generated - case _ => - Apply( - Select( - Typed(_this, Ident(newTypeName("RangeDefault"))), - newTermName("foreach")), - List(f)) - } - } -} - -object Test extends App { - - new Range(1, 10) foreach println - -} diff --git a/test/files/run/macro-reflective-ma-normal-mdmi.check b/test/files/run/macro-reflective-ma-normal-mdmi.check new file mode 100644 index 0000000000..ac4213d6e9 --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi.check @@ -0,0 +1 @@ +43 \ No newline at end of file diff --git a/test/files/run/macro-reflective-ma-normal-mdmi.flags b/test/files/run/macro-reflective-ma-normal-mdmi.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala new file mode 100644 index 0000000000..f6caf89dca --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} \ No newline at end of file diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala new file mode 100644 index 0000000000..3c594aed75 --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + println(tree.eval) +} diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check new file mode 100644 index 0000000000..ac4213d6e9 --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi.check @@ -0,0 +1 @@ +43 \ No newline at end of file diff --git a/test/files/run/macro-reflective-mamd-normal-mi.flags b/test/files/run/macro-reflective-mamd-normal-mi.flags new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala new file mode 100644 index 0000000000..dc7d42d23e --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } +} diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala new file mode 100644 index 0000000000..7cbe425fc8 --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala @@ -0,0 +1,16 @@ +//object Macros { +// def foo(x: Int) = macro Impls.foo +//} + +object Test extends App { + import scala.reflect.mirror._ + + val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo")) + val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.asType), EmptyTree) + val macrodef = DefDef(Modifiers(Set(scala.reflect.api.Modifier.`macro`)), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody) + val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(EmptyTypeName), EmptyTypeName), nme.CONSTRUCTOR), List()))) + val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef))) + val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + val tree = Block(macrodef, module, macroapp) + println(tree.eval) +} diff --git a/test/files/run/macro-reify-basic.check b/test/files/run/macro-reify-basic.check new file mode 100644 index 0000000000..f35d3e67b4 --- /dev/null +++ b/test/files/run/macro-reify-basic.check @@ -0,0 +1 @@ +hello world diff --git a/test/files/run/macro-reify-basic.flags b/test/files/run/macro-reify-basic.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-basic.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-basic/Macros_1.scala b/test/files/run/macro-reify-basic/Macros_1.scala new file mode 100644 index 0000000000..b2243d131c --- /dev/null +++ b/test/files/run/macro-reify-basic/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo(s: String) = macro Impls.foo + + object Impls { + def foo(c: Ctx)(s: c.Expr[String]) = c.reify { + println("hello " + s.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-basic/Test_2.scala b/test/files/run/macro-reify-basic/Test_2.scala new file mode 100644 index 0000000000..0a762f7ad7 --- /dev/null +++ b/test/files/run/macro-reify-basic/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo("world") +} \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-eval.check b/test/files/run/macro-reify-eval-eval.check new file mode 100644 index 0000000000..f35d3e67b4 --- /dev/null +++ b/test/files/run/macro-reify-eval-eval.check @@ -0,0 +1 @@ +hello world diff --git a/test/files/run/macro-reify-eval-eval.flags b/test/files/run/macro-reify-eval-eval.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-eval-eval.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-eval/Macros_1.scala b/test/files/run/macro-reify-eval-eval/Macros_1.scala new file mode 100644 index 0000000000..6b8ac94f0e --- /dev/null +++ b/test/files/run/macro-reify-eval-eval/Macros_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} +import scala.reflect.{mirror => mr} + +object Macros { + def foo = macro Impls.foo + + object Impls { + def foo(c: Ctx) = c.reify { + { c.reify(c.reify("hello world")) }.eval.eval + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-eval/Test_2.scala b/test/files/run/macro-reify-eval-eval/Test_2.scala new file mode 100644 index 0000000000..f697da6020 --- /dev/null +++ b/test/files/run/macro-reify-eval-eval/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println(Macros.foo) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-outside-reify.check b/test/files/run/macro-reify-eval-outside-reify.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-reify-eval-outside-reify.flags b/test/files/run/macro-reify-eval-outside-reify.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala new file mode 100644 index 0000000000..13b603d610 --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = c.literal(x.eval) +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-reify-eval-outside-reify/Test_2.scala b/test/files/run/macro-reify-eval-outside-reify/Test_2.scala new file mode 100644 index 0000000000..3c594aed75 --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + println(tree.eval) +} diff --git a/test/files/run/macro-reify-freevars.check b/test/files/run/macro-reify-freevars.check new file mode 100644 index 0000000000..02a6a7436b --- /dev/null +++ b/test/files/run/macro-reify-freevars.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +macro expansion contains free term variable code defined by map in Macros_1.scala:8:9. have you forgot to use eval when splicing this variable into a reifee? if you have troubles tracking free term variables, consider using -Xlog-free-terms diff --git a/test/files/run/macro-reify-freevars.flags b/test/files/run/macro-reify-freevars.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-freevars.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-freevars/Macros_1.scala b/test/files/run/macro-reify-freevars/Macros_1.scala new file mode 100644 index 0000000000..3cc559a0af --- /dev/null +++ b/test/files/run/macro-reify-freevars/Macros_1.scala @@ -0,0 +1,19 @@ +package scala.collection.slick +object QueryableMacros{ + def map[T:c.TypeTag, S:c.TypeTag] + (c: scala.reflect.makro.Context) + (projection: c.mirror.Expr[T => S]) + : c.mirror.Expr[scala.collection.slick.Queryable[S]] = { + import c.mirror._ + val code = EmptyTree + c.reify{ + Queryable.factory[S]( code.asInstanceOf[reflect.mirror.Tree] ) + } + } +} +class Queryable[T]{ + def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S] +} +object Queryable{ + def factory[S]( projection:scala.reflect.mirror.Tree ) : Queryable[S] = null +} \ No newline at end of file diff --git a/test/files/run/macro-reify-freevars/Test_2.scala b/test/files/run/macro-reify-freevars/Test_2.scala new file mode 100644 index 0000000000..55c677155a --- /dev/null +++ b/test/files/run/macro-reify-freevars/Test_2.scala @@ -0,0 +1,9 @@ +object Test extends App { + import scala.reflect.mirror._ + val q = New(AppliedTypeTree(Select(Select(Select(Ident("scala"), newTermName("collection")), newTermName("slick")), newTypeName("Queryable")), List(Ident("Int")))) + val x = ValDef(NoMods, newTermName("x"), Ident("Int"), EmptyTree) + val fn = Function(List(x), Apply(Select(Ident(newTermName("x")), newTermName("$plus")), List(Literal(Constant("5"))))) + val tree = Apply(Select(q, newTermName("map")), List(fn)) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams.check b/test/files/run/macro-reify-groundtypetag-notypeparams.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-notypeparams.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala new file mode 100644 index 0000000000..3aa40251ec --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala @@ -0,0 +1,6 @@ +import scala.reflect.mirror._ + +object Test extends App { + println(implicitly[GroundTypeTag[Int]]) + println(implicitly[GroundTypeTag[List[Int]]]) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags.check b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala new file mode 100644 index 0000000000..21735c10d5 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: GroundTypeTag] = { + println(implicitly[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-a.check b/test/files/run/macro-reify-nested-a.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-reify-nested-a.flags b/test/files/run/macro-reify-nested-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-nested-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..1ce8f44671 --- /dev/null +++ b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala @@ -0,0 +1,43 @@ +import scala.reflect.makro.Context + +case class Utils[C <: Context]( c:C ) { + import c.mirror._ + import c.{Tree=>_} + object removeDoubleReify extends c.mirror.Transformer { + def apply( tree:Tree ) = transform(tree) + override def transform(tree: Tree): Tree = { + super.transform { + tree match { + case Apply(TypeApply(Select(_this, termname), _), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case Apply(Select(_this, termname), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case _ => tree + } + } + } + } +} +object QueryableMacros{ + def _helper[C <: Context,S:c.TypeTag]( c:C )( name:String, projection:c.mirror.Expr[_] ) = { + import c.mirror._ + val element_type = implicitly[c.TypeTag[S]].tpe + val foo = Expr[reflect.mirror.Expr[Queryable[S]]]( + c.reifyTree( c.reflectMirrorPrefix, c.typeCheck( + Utils[c.type](c).removeDoubleReify( + Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree )) + ).asInstanceOf[Tree] + ))) + c.reify{ Queryable.factory[S]( foo.eval )} + } + def map[T:c.TypeTag, S:c.TypeTag] + (c: scala.reflect.makro.Context) + (projection: c.mirror.Expr[T => S]): c.mirror.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection ) +} +class Queryable[T]{ + def _map[S]( projection: T => S ) : Queryable[S] = ??? + def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S] +} +object Queryable{ + def factory[S]( projection:scala.reflect.mirror.Expr[Queryable[S]] ) : Queryable[S] = null +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-a/Test_2.scala b/test/files/run/macro-reify-nested-a/Test_2.scala new file mode 100644 index 0000000000..fa0eb378af --- /dev/null +++ b/test/files/run/macro-reify-nested-a/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App{ + val q : Queryable[Any] = new Queryable[Any] + q.map(e1 => q.map(e2=>e1)) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-b.check b/test/files/run/macro-reify-nested-b.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/macro-reify-nested-b.flags b/test/files/run/macro-reify-nested-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-nested-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..1ce8f44671 --- /dev/null +++ b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala @@ -0,0 +1,43 @@ +import scala.reflect.makro.Context + +case class Utils[C <: Context]( c:C ) { + import c.mirror._ + import c.{Tree=>_} + object removeDoubleReify extends c.mirror.Transformer { + def apply( tree:Tree ) = transform(tree) + override def transform(tree: Tree): Tree = { + super.transform { + tree match { + case Apply(TypeApply(Select(_this, termname), _), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case Apply(Select(_this, termname), reified::Nil ) + if termname.toString == "factory" => c.unreifyTree(reified) + case _ => tree + } + } + } + } +} +object QueryableMacros{ + def _helper[C <: Context,S:c.TypeTag]( c:C )( name:String, projection:c.mirror.Expr[_] ) = { + import c.mirror._ + val element_type = implicitly[c.TypeTag[S]].tpe + val foo = Expr[reflect.mirror.Expr[Queryable[S]]]( + c.reifyTree( c.reflectMirrorPrefix, c.typeCheck( + Utils[c.type](c).removeDoubleReify( + Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree )) + ).asInstanceOf[Tree] + ))) + c.reify{ Queryable.factory[S]( foo.eval )} + } + def map[T:c.TypeTag, S:c.TypeTag] + (c: scala.reflect.makro.Context) + (projection: c.mirror.Expr[T => S]): c.mirror.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection ) +} +class Queryable[T]{ + def _map[S]( projection: T => S ) : Queryable[S] = ??? + def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S] +} +object Queryable{ + def factory[S]( projection:scala.reflect.mirror.Expr[Queryable[S]] ) : Queryable[S] = null +} \ No newline at end of file diff --git a/test/files/run/macro-reify-nested-b/Test_2.scala b/test/files/run/macro-reify-nested-b/Test_2.scala new file mode 100644 index 0000000000..fa13f57ffb --- /dev/null +++ b/test/files/run/macro-reify-nested-b/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App{ + val q : Queryable[Any] = new Queryable[Any] + q.map(e1 => q.map(e2=>e1).map(e2=>e1)) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-ref-to-packageless.check b/test/files/run/macro-reify-ref-to-packageless.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-reify-ref-to-packageless.flags b/test/files/run/macro-reify-ref-to-packageless.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala b/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala new file mode 100644 index 0000000000..2f2d05678d --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala @@ -0,0 +1,6 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + val `Answer to the Ultimate Question of Life, the Universe, and Everything` = 42 + def foo(c: Ctx) = c.reify { `Answer to the Ultimate Question of Life, the Universe, and Everything` } +} diff --git a/test/files/run/macro-reify-ref-to-packageless/Test_2.scala b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala new file mode 100644 index 0000000000..9d475f756d --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo = macro Impls.foo + println(foo) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagful-a.check b/test/files/run/macro-reify-tagful-a.check new file mode 100644 index 0000000000..8a701df6a5 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a.check @@ -0,0 +1 @@ +List(hello world) diff --git a/test/files/run/macro-reify-tagful-a.flags b/test/files/run/macro-reify-tagful-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-tagful-a/Macros_1.scala b/test/files/run/macro-reify-tagful-a/Macros_1.scala new file mode 100644 index 0000000000..2ff12091a1 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[T] + + object Impls { + def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify { + List(s.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagful-a/Test_2.scala b/test/files/run/macro-reify-tagful-a/Test_2.scala new file mode 100644 index 0000000000..4d27166341 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val list: List[String] = Macros.foo("hello world") + println(list) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagless-a.check b/test/files/run/macro-reify-tagless-a.check new file mode 100644 index 0000000000..b58cff19bc --- /dev/null +++ b/test/files/run/macro-reify-tagless-a.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +macro expansion contains free type variable T defined by foo in Impls_Macros_1.scala:7:13. have you forgot to use c.TypeTag annotation for this type parameter? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/macro-reify-tagless-a.flags b/test/files/run/macro-reify-tagless-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-tagless-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala b/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala new file mode 100644 index 0000000000..45e39d7d1c --- /dev/null +++ b/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[T] + + object Impls { + def foo[T](c: Ctx)(s: c.Expr[T]) = c.reify { + List[T](s.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-tagless-a/Test_2.scala b/test/files/run/macro-reify-tagless-a/Test_2.scala new file mode 100644 index 0000000000..d996da1570 --- /dev/null +++ b/test/files/run/macro-reify-tagless-a/Test_2.scala @@ -0,0 +1,12 @@ +object Test extends App { + //val list: List[String] = Macros.foo("hello world") + //println(list) + + import scala.reflect.mirror._ + val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass))) + val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world")))) + val list = ValDef(NoMods, newTermName("list"), tpt, rhs) + val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name)))) + try tree.eval + catch { case ex: Throwable => println(ex.getMessage) } +} diff --git a/test/files/run/macro-reify-typetag-notypeparams.check b/test/files/run/macro-reify-typetag-notypeparams.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-notypeparams.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-notypeparams/Test.scala b/test/files/run/macro-reify-typetag-notypeparams/Test.scala new file mode 100644 index 0000000000..041a44273d --- /dev/null +++ b/test/files/run/macro-reify-typetag-notypeparams/Test.scala @@ -0,0 +1,6 @@ +import scala.reflect.mirror._ + +object Test extends App { + println(implicitly[TypeTag[Int]]) + println(implicitly[TypeTag[List[Int]]]) +} \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-typeparams-notags.check b/test/files/run/macro-reify-typetag-typeparams-notags.check new file mode 100644 index 0000000000..3da30c71ba --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-notags.check @@ -0,0 +1,2 @@ +GroundTypeTag[T] +GroundTypeTag[List[T]] diff --git a/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala b/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala new file mode 100644 index 0000000000..a89499e7fe --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTag[T] = { + println(implicitly[TypeTag[T]]) + println(implicitly[TypeTag[List[T]]]) + } + fooNoTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-typeparams-tags.check b/test/files/run/macro-reify-typetag-typeparams-tags.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-tags.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala new file mode 100644 index 0000000000..b32680a4b8 --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: TypeTag] = { + println(implicitly[TypeTag[T]]) + println(implicitly[TypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag.check b/test/files/run/macro-reify-typetag-usegroundtypetag.check new file mode 100644 index 0000000000..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala new file mode 100644 index 0000000000..c9b210f35a --- /dev/null +++ b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTag[T: GroundTypeTag] = { + println(implicitly[TypeTag[T]]) + println(implicitly[TypeTag[List[T]]]) + } + fooTypeTag[Int] +} \ No newline at end of file diff --git a/test/files/run/macro-reify-unreify.check b/test/files/run/macro-reify-unreify.check new file mode 100644 index 0000000000..a5334cc355 --- /dev/null +++ b/test/files/run/macro-reify-unreify.check @@ -0,0 +1 @@ +hello world = Expr[String("hello world")]("hello world") diff --git a/test/files/run/macro-reify-unreify.flags b/test/files/run/macro-reify-unreify.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-unreify.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-unreify/Macros_1.scala b/test/files/run/macro-reify-unreify/Macros_1.scala new file mode 100644 index 0000000000..1b0b9c6421 --- /dev/null +++ b/test/files/run/macro-reify-unreify/Macros_1.scala @@ -0,0 +1,19 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo(s: String) = macro Impls.foo + + object Impls { + def foo(c: Ctx)(s: c.Expr[String]) = { + import c.mirror._ + + val world = c.reifyTree(c.reflectMirrorPrefix, s.tree) + val greeting = c.reifyTree(c.reflectMirrorPrefix, c.typeCheck(Apply(Select(Literal(Constant("hello ")), newTermName("$plus")), List(c.unreifyTree(world))))) + val typedGreeting = Expr[String](greeting) + + c.reify { + println("hello " + s.eval + " = " + typedGreeting.eval) + } + } + } +} \ No newline at end of file diff --git a/test/files/run/macro-reify-unreify/Test_2.scala b/test/files/run/macro-reify-unreify/Test_2.scala new file mode 100644 index 0000000000..0a762f7ad7 --- /dev/null +++ b/test/files/run/macro-reify-unreify/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo("world") +} \ No newline at end of file diff --git a/test/files/run/macro-reify-value-outside-reify.check b/test/files/run/macro-reify-value-outside-reify.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-reify-value-outside-reify.flags b/test/files/run/macro-reify-value-outside-reify.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala new file mode 100644 index 0000000000..28ec1ace67 --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala @@ -0,0 +1,9 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = c.literal(x.value) +} + +object Macros { + def foo(x: Int) = macro Impls.foo +} diff --git a/test/files/run/macro-reify-value-outside-reify/Test_2.scala b/test/files/run/macro-reify-value-outside-reify/Test_2.scala new file mode 100644 index 0000000000..8225eb0b39 --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + import scala.reflect.mirror._ + val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))) + try println(tree.eval) + catch { case ex: Throwable => println(ex.getMessage) } +} diff --git a/test/files/run/macro-repl-basic.check b/test/files/run/macro-repl-basic.check index f8f0d3ad29..3bc899f49b 100644 --- a/test/files/run/macro-repl-basic.check +++ b/test/files/run/macro-repl-basic.check @@ -3,13 +3,39 @@ Type :help for more information. scala> +scala> import scala.reflect.makro.{Context => Ctx} +import scala.reflect.makro.{Context=>Ctx} + +scala> + +scala> object Impls { + def foo(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + Expr[Int](body) + } + + def bar(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + Expr[Int](body) + } + + def quux(c: Ctx)(x: c.Expr[Int]) = { + import c.mirror._ + val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + Expr[Int](body) + } +} +defined module Impls + scala> object Macros { object Shmacros { - def macro foo(x: Int): Int = x + def foo(x: Int): Int = macro Impls.foo } - def macro bar(x: Int): Int = x + def bar(x: Int): Int = macro Impls.bar }; class Macros { - def macro quux(x: Int): Int = x + def quux(x: Int): Int = macro Impls.quux } defined module Macros defined class Macros @@ -20,6 +46,6 @@ scala> import Macros.Shmacros._ import Macros.Shmacros._ scala> println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -10 +31 scala> diff --git a/test/files/run/macro-repl-basic.scala b/test/files/run/macro-repl-basic.scala index 9b1a53343b..a21eb7815f 100644 --- a/test/files/run/macro-repl-basic.scala +++ b/test/files/run/macro-repl-basic.scala @@ -3,13 +3,34 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { override def extraSettings = "-Xmacros" def code = """ + |import scala.reflect.makro.{Context => Ctx} + | + |object Impls { + | def foo(c: Ctx)(x: c.Expr[Int]) = { + | import c.mirror._ + | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + | Expr[Int](body) + | } + | + | def bar(c: Ctx)(x: c.Expr[Int]) = { + | import c.mirror._ + | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + | Expr[Int](body) + | } + | + | def quux(c: Ctx)(x: c.Expr[Int]) = { + | import c.mirror._ + | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))) + | Expr[Int](body) + | } + |} |object Macros { | object Shmacros { - | def macro foo(x: Int): Int = x + | def foo(x: Int): Int = macro Impls.foo | } - | def macro bar(x: Int): Int = x + | def bar(x: Int): Int = macro Impls.bar |}; class Macros { - | def macro quux(x: Int): Int = x + | def quux(x: Int): Int = macro Impls.quux |} | |import Macros.Shmacros._ diff --git a/test/files/run/macro-repl-dontexpand.check b/test/files/run/macro-repl-dontexpand.check index d2bb89b6f7..35845f0cff 100644 --- a/test/files/run/macro-repl-dontexpand.check +++ b/test/files/run/macro-repl-dontexpand.check @@ -3,7 +3,10 @@ Type :help for more information. scala> -scala> def macro foo = ??? +scala> def bar(c: scala.reflect.makro.Context) = ??? +bar: (c: scala.reflect.makro.Context)Nothing + +scala> def foo = macro bar foo: Any scala> diff --git a/test/files/run/macro-repl-dontexpand.scala b/test/files/run/macro-repl-dontexpand.scala index 254bce894c..9889a8ffdf 100644 --- a/test/files/run/macro-repl-dontexpand.scala +++ b/test/files/run/macro-repl-dontexpand.scala @@ -3,6 +3,7 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { override def extraSettings = "-Xmacros" def code = """ - |def macro foo = ??? + |def bar(c: scala.reflect.makro.Context) = ??? + |def foo = macro bar |""".stripMargin } \ No newline at end of file diff --git a/test/files/run/macro-rettype-mismatch/Macros_1.scala b/test/files/run/macro-rettype-mismatch/Macros_1.scala deleted file mode 100644 index 64e5b93468..0000000000 --- a/test/files/run/macro-rettype-mismatch/Macros_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Macros { - def macro foo(x: Int): String = x -} \ No newline at end of file diff --git a/test/files/run/macro-rettype-mismatch/Test_2.scala b/test/files/run/macro-rettype-mismatch/Test_2.scala deleted file mode 100644 index 39a7c7ad1a..0000000000 --- a/test/files/run/macro-rettype-mismatch/Test_2.scala +++ /dev/null @@ -1,16 +0,0 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - import scala.reflect.mirror._ - val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(2)))) - - val stderr = new java.io.ByteArrayOutputStream() - Console.setErr(new java.io.PrintStream(stderr)) - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - try { toolbox.runExpr(tree) } - catch { case ex: Throwable => println(stderr); println(ex) } -} diff --git a/test/files/run/macro-settings.check b/test/files/run/macro-settings.check new file mode 100644 index 0000000000..33784d1c15 --- /dev/null +++ b/test/files/run/macro-settings.check @@ -0,0 +1 @@ +List(hello=1) diff --git a/test/files/run/macro-settings.flags b/test/files/run/macro-settings.flags new file mode 100644 index 0000000000..cdc7512197 --- /dev/null +++ b/test/files/run/macro-settings.flags @@ -0,0 +1 @@ +-Xmacros -Xmacro-settings:hello=1 \ No newline at end of file diff --git a/test/files/run/macro-settings/Impls_Macros_1.scala b/test/files/run/macro-settings/Impls_Macros_1.scala new file mode 100644 index 0000000000..8c7254c79a --- /dev/null +++ b/test/files/run/macro-settings/Impls_Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.Context + +object Impls { + def impl(c: Context) = c.reify { + println(c.literal(c.settings.toString).eval) + } +} + +object Macros { + def foo = macro Impls.impl +} \ No newline at end of file diff --git a/test/files/run/macro-settings/Test_2.scala b/test/files/run/macro-settings/Test_2.scala new file mode 100644 index 0000000000..acfddae942 --- /dev/null +++ b/test/files/run/macro-settings/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +} \ No newline at end of file diff --git a/test/files/run/macro-sip19-revised.check b/test/files/run/macro-sip19-revised.check new file mode 100644 index 0000000000..aa2fbd11d3 --- /dev/null +++ b/test/files/run/macro-sip19-revised.check @@ -0,0 +1,5 @@ +hey, i've been called from SourceLocation1(null,Test_2.scala,11,251) +hey, i've been called from SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222) +hey, i've been called from SourceLocation1(SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222),Test_2.scala,8,222) +hey, i've been called from SourceLocation1(SourceLocation1(SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222),Test_2.scala,8,222),Test_2.scala,6,180) +2 diff --git a/test/files/run/macro-sip19-revised.flags b/test/files/run/macro-sip19-revised.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-sip19-revised.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-sip19-revised/Impls_Macros_1.scala b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala new file mode 100644 index 0000000000..e8f6e1df85 --- /dev/null +++ b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala @@ -0,0 +1,34 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context) = { + import c.mirror._ + + val inscope = c.inferImplicitValue(staticClass("SourceLocation").asType) + val outer = Expr[SourceLocation](if (!inscope.isEmpty) inscope else Literal(Constant(null))) + + val Apply(fun, args) = c.enclosingImplicits(0)._2 + val fileName = fun.pos.fileInfo.getName + val line = fun.pos.line + val charOffset = fun.pos.point + c.reify { SourceLocation1(outer.eval, c.literal(fileName).eval, c.literal(line).eval, c.literal(charOffset).eval) } + } + + implicit def sourceLocation: SourceLocation1 = macro impl +} + +trait SourceLocation { + /** Source location of the outermost call */ + val outer: SourceLocation + + /** The name of the source file */ + val fileName: String + + /** The line number */ + val line: Int + + /** The character offset */ + val charOffset: Int +} + +case class SourceLocation1(val outer: SourceLocation, val fileName: String, val line: Int, val charOffset: Int) extends SourceLocation diff --git a/test/files/run/macro-sip19-revised/Test_2.scala b/test/files/run/macro-sip19-revised/Test_2.scala new file mode 100644 index 0000000000..d9a4d7d4fc --- /dev/null +++ b/test/files/run/macro-sip19-revised/Test_2.scala @@ -0,0 +1,12 @@ +import Macros._ + +object Test extends App { + def foo(x: Int, y: Int)(implicit loc: SourceLocation): Int = { + println("hey, i've been called from %s".format(loc)) + if (x < y) foo(y, x) + else if (y == 0) x + else foo(x - y, y) + } + + println(foo(4, 2)) +} diff --git a/test/files/run/macro-sip19.check b/test/files/run/macro-sip19.check new file mode 100644 index 0000000000..6b317ccb47 --- /dev/null +++ b/test/files/run/macro-sip19.check @@ -0,0 +1,5 @@ +hey, i've been called from SourceLocation(Test_2.scala,15,366) +hey, i've been called from SourceLocation(Test_2.scala,11,331) +hey, i've been called from SourceLocation(Test_2.scala,11,331) +hey, i've been called from SourceLocation(Test_2.scala,9,285) +2 diff --git a/test/files/run/macro-sip19.flags b/test/files/run/macro-sip19.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-sip19.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-sip19/Impls_Macros_1.scala b/test/files/run/macro-sip19/Impls_Macros_1.scala new file mode 100644 index 0000000000..39b29ad64c --- /dev/null +++ b/test/files/run/macro-sip19/Impls_Macros_1.scala @@ -0,0 +1,25 @@ +import scala.reflect.makro.Context + +object Macros { + def impl(c: Context) = { + import c.mirror._ + val Apply(fun, args) = c.enclosingImplicits(0)._2 + val fileName = fun.pos.fileInfo.getName + val line = fun.pos.line + val charOffset = fun.pos.point + c.reify { SourceLocation(c.literal(fileName).eval, c.literal(line).eval, c.literal(charOffset).eval) } + } + + implicit def sourceLocation: SourceLocation = macro impl +} + +case class SourceLocation( + /** The name of the source file */ + val fileName: String, + + /** The line number */ + val line: Int, + + /** The character offset */ + val charOffset: Int +) diff --git a/test/files/run/macro-sip19/Test_2.scala b/test/files/run/macro-sip19/Test_2.scala new file mode 100644 index 0000000000..32326e6352 --- /dev/null +++ b/test/files/run/macro-sip19/Test_2.scala @@ -0,0 +1,16 @@ +import Macros._ + +object Test extends App { + def foo(x: Int, y: Int)(implicit loc0: SourceLocation): Int = { + var loc = loc0; + { + var loc0 = 0 // shadow loc0 to disambiguate with the implicit macro + println("hey, i've been called from %s".format(loc)) + if (x < y) foo(y, x) + else if (y == 0) x + else foo(x - y, y) + } + } + + println(foo(4, 2)) +} diff --git a/test/files/run/macro-typecheck-implicitsdisabled.check b/test/files/run/macro-typecheck-implicitsdisabled.check new file mode 100644 index 0000000000..aa6c8e1f07 --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled.check @@ -0,0 +1,2 @@ +scala.this.Predef.any2ArrowAssoc[Int](1).->[Int](2) +scala.reflect.internal.Types$TypeError: value -> is not a member of Int diff --git a/test/files/run/macro-typecheck-implicitsdisabled.flags b/test/files/run/macro-typecheck-implicitsdisabled.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala new file mode 100644 index 0000000000..4f0f76aed6 --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala @@ -0,0 +1,28 @@ +import scala.reflect.makro.Context + +object Macros { + def impl_with_implicits_enabled(c: Context) = { + import c.mirror._ + + val tree1 = Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + val ttree1 = c.typeCheck(tree1, withImplicitViewsDisabled = false) + c.literal(ttree1.toString) + } + + def foo_with_implicits_enabled = macro impl_with_implicits_enabled + + def impl_with_implicits_disabled(c: Context) = { + import c.mirror._ + + try { + val tree2 = Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + val ttree2 = c.typeCheck(tree2, withImplicitViewsDisabled = true) + c.literal(ttree2.toString) + } catch { + case ex: Throwable => + c.literal(ex.toString) + } + } + + def foo_with_implicits_disabled = macro impl_with_implicits_disabled +} \ No newline at end of file diff --git a/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala b/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala new file mode 100644 index 0000000000..127e955f0e --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println(Macros.foo_with_implicits_enabled) + println(Macros.foo_with_implicits_disabled) +} \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check new file mode 100644 index 0000000000..9760c117a7 --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled.check @@ -0,0 +1,5 @@ +{ + val $mr: reflect.mirror.type = scala.reflect.`package`.mirror; + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) +} +mr.reify[Int](2) diff --git a/test/files/run/macro-typecheck-macrosdisabled.flags b/test/files/run/macro-typecheck-macrosdisabled.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala new file mode 100644 index 0000000000..c253f0b1fb --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala @@ -0,0 +1,36 @@ +import scala.reflect.makro.Context + +object Macros { + def impl_with_macros_enabled(c: Context) = { + import c.mirror._ + + // todo. doesn't work. why? + //val mrPkg = staticModule("scala.reflect.package") + //val mrSym = selectTerm(mrPkg, "mirror") + //val NullaryMethodType(mrTpe) = mrSym.typeSignature + //val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + //val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + + val mr = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("package")), newTermName("mirror")) + val tree1 = Apply(Select(mr, newTermName("reify")), List(Literal(Constant(2)))) + val ttree1 = c.typeCheck(tree1, withMacrosDisabled = false) + c.literal(ttree1.toString) + } + + def foo_with_macros_enabled = macro impl_with_macros_enabled + + def impl_with_macros_disabled(c: Context) = { + import c.mirror._ + + val mrPkg = staticModule("scala.reflect.package") + val mrSym = selectTerm(mrPkg, "mirror") + val NullaryMethodType(mrTpe) = mrSym.typeSignature + val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + + val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true) + c.literal(ttree2.toString) + } + + def foo_with_macros_disabled = macro impl_with_macros_disabled +} \ No newline at end of file diff --git a/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala b/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala new file mode 100644 index 0000000000..bdba39195b --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + println(Macros.foo_with_macros_enabled) + println(Macros.foo_with_macros_disabled) +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-consfromsls.check b/test/files/run/macro-undetparams-consfromsls.check new file mode 100644 index 0000000000..6bf9bcca5a --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls.check @@ -0,0 +1,5 @@ +A = GroundTypeTag[Int] +B = GroundTypeTag[Nothing] +List(1) +A = GroundTypeTag[Any] +List(abc, 1) diff --git a/test/files/run/macro-undetparams-consfromsls.flags b/test/files/run/macro-undetparams-consfromsls.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala b/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala new file mode 100644 index 0000000000..c22ff96028 --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala @@ -0,0 +1,17 @@ +import scala.reflect.makro.Context + +object Macros { + def cons_impl[A: c.TypeTag](c: Context)(x: c.Expr[A], xs: c.Expr[List[A]]): c.Expr[List[A]] = c.reify { + println("A = " + c.literal(implicitly[c.TypeTag[A]].toString).eval) + x.eval :: xs.eval + } + + def nil_impl[B: c.TypeTag](c: Context): c.Expr[List[B]] = c.reify { + println("B = " + c.literal(implicitly[c.TypeTag[B]].toString).eval) + Nil + } + + def cons[A](x: A, xs: List[A]): List[A] = macro cons_impl[A] + + def nil[B]: List[B] = macro nil_impl[B] +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-consfromsls/Test_2.scala b/test/files/run/macro-undetparams-consfromsls/Test_2.scala new file mode 100644 index 0000000000..f2c2ce0051 --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls/Test_2.scala @@ -0,0 +1,7 @@ +object Test extends App { + import Macros._ + val xs = cons(1, nil) + println(xs) + val ys = cons("abc", xs) + println(ys) +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-implicitval.check b/test/files/run/macro-undetparams-implicitval.check new file mode 100644 index 0000000000..352a2e6480 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval.check @@ -0,0 +1 @@ +GroundTypeTag[Nothing] diff --git a/test/files/run/macro-undetparams-implicitval.flags b/test/files/run/macro-undetparams-implicitval.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-implicitval/Test.scala b/test/files/run/macro-undetparams-implicitval/Test.scala new file mode 100644 index 0000000000..5278295451 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval/Test.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[T: TypeTag] = println(implicitly[TypeTag[T]]) + foo +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-macroitself.check b/test/files/run/macro-undetparams-macroitself.check new file mode 100644 index 0000000000..60c021a35b --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[String] diff --git a/test/files/run/macro-undetparams-macroitself.flags b/test/files/run/macro-undetparams-macroitself.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala b/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala new file mode 100644 index 0000000000..9d65e8b0da --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.makro.Context + +object Macros { + def impl[T: c.TypeTag](c: Context)(foo: c.Expr[T]): c.Expr[Unit] = c.reify { println(c.literal(implicitly[c.TypeTag[T]].toString).eval) } + + def foo[T](foo: T) = macro impl[T] +} \ No newline at end of file diff --git a/test/files/run/macro-undetparams-macroitself/Test_2.scala b/test/files/run/macro-undetparams-macroitself/Test_2.scala new file mode 100644 index 0000000000..1a93ff1304 --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo(42) + Macros.foo("42") +} \ No newline at end of file diff --git a/test/files/run/manifests.scala b/test/files/run/manifests.scala index 6b6ea80b34..2d64bf18a9 100644 --- a/test/files/run/manifests.scala +++ b/test/files/run/manifests.scala @@ -4,29 +4,29 @@ object Test val CO, IN, CONTRA = Value } import Variances.{ CO, IN, CONTRA } - + object SubtypeRelationship extends Enumeration { val NONE, SAME, SUB, SUPER = Value } import SubtypeRelationship.{ NONE, SAME, SUB, SUPER } - + class VarianceTester[T, U, CC[_]](expected: Variances.Value)( implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) { - - def elements = List(ev1 <:< ev2, ev2 <:< ev1) - def containers = List(ev3 <:< ev4, ev4 <:< ev3) + + def elements = List(ev1.tpe <:< ev2.tpe, ev2.tpe <:< ev1.tpe) + def containers = List(ev3.tpe <:< ev4.tpe, ev4.tpe <:< ev3.tpe) def isUnrelated = typeCompare[T, U] == NONE def isSame = typeCompare[T, U] == SAME def isSub = typeCompare[T, U] == SUB def isSuper = typeCompare[T, U] == SUPER - + def showsCovariance = (elements == containers) def showsContravariance = (elements == containers.reverse) def showsInvariance = containers forall (_ == isSame) def allContainerVariances = List(showsCovariance, showsInvariance, showsContravariance) - + def showsExpectedVariance = if (isUnrelated) allContainerVariances forall (_ == false) else if (isSame) allContainerVariances forall (_ == true) @@ -36,64 +36,57 @@ object Test case CONTRA => showsContravariance && !showsCovariance && !showsInvariance } } - + def showsCovariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) = new VarianceTester[T, U, CC](CO) showsExpectedVariance def showsInvariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) = new VarianceTester[T, U, CC](IN) showsExpectedVariance - + def showsContravariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) = new VarianceTester[T, U, CC](CONTRA) showsExpectedVariance - - def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = { - // checking types as well - if ((ev1 <:< ev2) != (ev1.tpe <:< ev2.tpe)) - println("Failed! " + ((ev1, ev2))) - - if ((ev2 <:< ev1) != (ev2.tpe <:< ev1.tpe)) - println("Failed! " + ((ev2, ev1))) - (ev1 <:< ev2, ev2 <:< ev1) match { + def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = { + (ev1.tpe <:< ev2.tpe, ev2.tpe <:< ev1.tpe) match { case (true, true) => SAME case (true, false) => SUB case (false, true) => SUPER case (false, false) => NONE } } - + def assertAnyRef[T: Manifest] = List( - manifest[T] <:< manifest[Any], - manifest[T] <:< manifest[AnyRef], - !(manifest[T] <:< manifest[AnyVal]) + manifest[T].tpe <:< manifest[Any].tpe, + manifest[T].tpe <:< manifest[AnyRef].tpe, + !(manifest[T].tpe <:< manifest[AnyVal].tpe) ) foreach (assert(_, "assertAnyRef")) - + def assertAnyVal[T: Manifest] = List( - manifest[T] <:< manifest[Any], - !(manifest[T] <:< manifest[AnyRef]), - manifest[T] <:< manifest[AnyVal] + manifest[T].tpe <:< manifest[Any].tpe, + !(manifest[T].tpe <:< manifest[AnyRef].tpe), + manifest[T].tpe <:< manifest[AnyVal].tpe ) foreach (assert(_, "assertAnyVal")) - + def assertSameType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SAME, "assertSameType") def assertSuperType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SUPER, "assertSuperType") def assertSubType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SUB, "assertSubType") def assertNoRelationship[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == NONE, "assertNoRelationship") - + def testVariancesVia[T: Manifest, U: Manifest] = assert( - typeCompare[T, U] == SUB && + typeCompare[T, U] == SUB && showsCovariance[T, U, List] && showsInvariance[T, U, Set], "testVariancesVia" ) - + def runAllTests = { assertAnyVal[AnyVal] assertAnyVal[Unit] - assertAnyVal[Int] - assertAnyVal[Double] + assertAnyVal[Int] + assertAnyVal[Double] assertAnyVal[Boolean] assertAnyVal[Char] - + assertAnyRef[AnyRef] assertAnyRef[java.lang.Object] assertAnyRef[java.lang.Integer] @@ -103,7 +96,7 @@ object Test assertAnyRef[String] assertAnyRef[scala.List[String]] assertAnyRef[scala.List[_]] - + // variance doesn't work yet // testVariancesVia[String, Any] // testVariancesVia[String, AnyRef] @@ -111,11 +104,11 @@ object Test assertSubType[List[String], List[Any]] assertSubType[List[String], List[AnyRef]] assertNoRelationship[List[String], List[AnyVal]] - + assertSubType[List[Int], List[Any]] assertSubType[List[Int], List[AnyVal]] assertNoRelationship[List[Int], List[AnyRef]] - + // Nothing assertSubType[Nothing, Any] assertSubType[Nothing, AnyVal] @@ -124,7 +117,7 @@ object Test assertSubType[Nothing, List[String]] assertSubType[Nothing, Null] assertSameType[Nothing, Nothing] - + // Null assertSubType[Null, Any] assertNoRelationship[Null, AnyVal] @@ -133,7 +126,7 @@ object Test assertSubType[Null, List[String]] assertSameType[Null, Null] assertSuperType[Null, Nothing] - + // Any assertSameType[Any, Any] assertSuperType[Any, AnyVal] @@ -142,7 +135,7 @@ object Test assertSuperType[Any, List[String]] assertSuperType[Any, Null] assertSuperType[Any, Nothing] - + // Misc unrelated types assertNoRelationship[Unit, AnyRef] assertNoRelationship[Unit, Int] diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check index feb0619525..761aa1ca72 100644 --- a/test/files/run/primitive-sigs-2.check +++ b/test/files/run/primitive-sigs-2.check @@ -1,7 +1,7 @@ -T -List(A, char, class java.lang.Object) -a -public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest) -public float[] Arr.arr3(float[][]) -public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) -public scala.collection.immutable.List Arr.arr1(int[]) +T +List(A, char, class java.lang.Object) +a +public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.api.TypeTags.scala.reflect.api.TypeTags$GroundTypeTag) +public float[] Arr.arr3(float[][]) +public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) +public scala.collection.immutable.List Arr.arr1(int[]) diff --git a/test/files/run/reify_ann1a.check b/test/files/run/reify_ann1a.check index 66dce778a8..a3944ae1ee 100644 --- a/test/files/run/reify_ann1a.check +++ b/test/files/run/reify_ann1a.check @@ -1,30 +1,30 @@ -{ - @new ann(immutable.this.List.apply[String]("1a")) @new ann(immutable.this.List.apply[String]("1b")) class C[@new ann(immutable.this.List.apply[String]("2a")) @new ann(immutable.this.List.apply[String]("2b")) T] extends scala.AnyRef { - @new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b")) = _; - def (@new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b"))) = { - super.(); - () - }; - @new ann(immutable.this.List.apply[String]("5a")) @new ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { - @new ann(immutable.this.List.apply[String]("7a")) @new ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.$plus(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); - val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); - r.$plus(s) - } - }; - () -} -{ - @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends scala.AnyRef { - @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; - def (@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = { - C.super.(); - () - }; - @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { - @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); - val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); - r.+(s) - } - }; - () -} +{ + @new ann(immutable.this.List.apply("1a")) @new ann(immutable.this.List.apply("1b")) class C[@new ann(immutable.this.List.apply("2a")) @new ann(immutable.this.List.apply("2b")) T >: Nothing <: Any] extends Object { + @new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _; + def (@new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b"))) = { + super.(); + () + }; + @new ann(immutable.this.List.apply("5a")) @new ann(immutable.this.List.apply("5b")) def f(x: Int @ann(immutable.this.List.apply("6a")) @ann(immutable.this.List.apply("6b"))) = { + @new ann(immutable.this.List.apply("7a")) @new ann(immutable.this.List.apply("7b")) val r = x.$plus(3): @ann(immutable.this.List.apply("8a")): @ann(immutable.this.List.apply("8b")); + val s = (4: Int @ann(immutable.this.List.apply("9a")) @ann(immutable.this.List.apply("9b"))); + r.$plus(s) + } + }; + () +} +{ + @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends Object { + @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; + def (@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = { + C.super.(); + () + }; + @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { + @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); + val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); + r.+(s) + } + }; + () +} diff --git a/test/files/run/reify_ann1a.scala b/test/files/run/reify_ann1a.scala index 1ca170904b..1f5d1daccd 100644 --- a/test/files/run/reify_ann1a.scala +++ b/test/files/run/reify_ann1a.scala @@ -1,14 +1,10 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ class ann(bar: List[String]) extends StaticAnnotation object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { @ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b")) @@ -20,8 +16,7 @@ object Test extends App { println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/run/reify_ann1b.check b/test/files/run/reify_ann1b.check index 9bc65a422e..bae838f15f 100644 --- a/test/files/run/reify_ann1b.check +++ b/test/files/run/reify_ann1b.check @@ -1,30 +1,30 @@ -{ - @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T] extends scala.AnyRef { - @new ann(bar = "3a") @new ann(bar = "3b") private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _; - def (@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = { - super.(); - () - }; - @new ann(bar = "5a") @new ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = { - @new ann(bar = "7a") @new ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.$plus(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a")); - val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a")); - r.$plus(s) - } - }; - () -} -{ - @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T] extends scala.AnyRef { - @ann(bar = "3a") @ann(bar = "3b") private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _; - def (@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = { - C.super.(); - () - }; - @ann(bar = "5a") @ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = { - @ann(bar = "7a") @ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.+(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a")); - val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a")); - r.+(s) - } - }; - () -} +{ + @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T >: Nothing <: Any] extends Object { + @new ann(bar = "3a") @new ann(bar = "3b") private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _; + def (@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = { + super.(); + () + }; + @new ann(bar = "5a") @new ann(bar = "5b") def f(x: Int @ann(bar = "6a") @ann(bar = "6b")) = { + @new ann(bar = "7a") @new ann(bar = "7b") val r = x.$plus(3): @ann(bar = "8a"): @ann(bar = "8b"); + val s = (4: Int @ann(bar = "9a") @ann(bar = "9b")); + r.$plus(s) + } + }; + () +} +{ + @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T] extends Object { + @ann(bar = "3a") @ann(bar = "3b") private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _; + def (@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = { + C.super.(); + () + }; + @ann(bar = "5a") @ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = { + @ann(bar = "7a") @ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.+(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a")); + val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a")); + r.+(s) + } + }; + () +} diff --git a/test/files/run/reify_ann1b.scala b/test/files/run/reify_ann1b.scala index 9bdc712227..13d861a15c 100644 --- a/test/files/run/reify_ann1b.scala +++ b/test/files/run/reify_ann1b.scala @@ -1,14 +1,10 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ class ann(bar: String) extends ClassfileAnnotation object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ @ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) { @ann(bar="5a") @ann(bar="5b") def f(x: Int @ann(bar="6a") @ann(bar="6b")) = { @ann(bar="7a") @ann(bar="7b") val r = (x + 3): @ann(bar="8a") @ann(bar="8b") @@ -20,8 +16,7 @@ object Test extends App { println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/run/reify_ann2a.check b/test/files/run/reify_ann2a.check new file mode 100644 index 0000000000..5022c50ca8 --- /dev/null +++ b/test/files/run/reify_ann2a.check @@ -0,0 +1,44 @@ +{ + class ann extends StaticAnnotation { + private[this] val bar: List[String] = _; + def (bar: List[String]) = { + super.(); + () + } + }; + @new ann(immutable.this.List.apply("1a")) @new ann(immutable.this.List.apply("1b")) class C[@new ann(immutable.this.List.apply("2a")) @new ann(immutable.this.List.apply("2b")) T >: Nothing <: Any] extends Object { + @new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _; + def (@new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b"))) = { + super.(); + () + }; + @new ann(immutable.this.List.apply("5a")) @new ann(immutable.this.List.apply("5b")) def f(x: Int @ann(immutable.this.List.apply("6a")) @ann(immutable.this.List.apply("6b"))) = { + @new ann(immutable.this.List.apply("7a")) @new ann(immutable.this.List.apply("7b")) val r = x.$plus(3): @ann(immutable.this.List.apply("8a")): @ann(immutable.this.List.apply("8b")); + val s = (4: Int @ann(immutable.this.List.apply("9a")) @ann(immutable.this.List.apply("9b"))); + r.$plus(s) + } + }; + () +} +{ + class ann extends scala.annotation.Annotation with scala.annotation.StaticAnnotation { + private[this] val bar: List[String] = _; + def (bar: List[String]): ann = { + ann.super.(); + () + } + }; + @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends Object { + @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; + def (@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = { + C.super.(); + () + }; + @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = { + @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a"))); + val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a"))); + r.+(s) + } + }; + () +} diff --git a/test/files/run/reify_ann2a.scala b/test/files/run/reify_ann2a.scala new file mode 100644 index 0000000000..370abadba0 --- /dev/null +++ b/test/files/run/reify_ann2a.scala @@ -0,0 +1,25 @@ +import scala.reflect.mirror._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class ann(bar: List[String]) extends StaticAnnotation + + @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { + @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { + @ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b")) + val s = 4: Int @ann(bar=List("9a")) @ann(bar=List("9b")) + r + s + } + } + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} \ No newline at end of file diff --git a/test/files/run/reify_ann3.check b/test/files/run/reify_ann3.check new file mode 100644 index 0000000000..9452a9701e --- /dev/null +++ b/test/files/run/reify_ann3.check @@ -0,0 +1,21 @@ +{ + class Tree[A >: Nothing <: Any, B >: Nothing <: Any] extends Object { + @new inline @getter() final val key: A = _; + def (key: A) = { + super.(); + () + } + }; + () +} +{ + class Tree[A, B] extends Object { + final private[this] val key: A = _; + @inline @scala.annotation.meta.getter final def key: A = Tree.this.key; + def (key: A): Tree[A,B] = { + Tree.super.(); + () + } + }; + () +} diff --git a/test/files/run/reify_ann3.scala b/test/files/run/reify_ann3.scala new file mode 100644 index 0000000000..d65e641619 --- /dev/null +++ b/test/files/run/reify_ann3.scala @@ -0,0 +1,19 @@ +import scala.reflect.mirror._ +import scala.annotation._ +import scala.annotation.meta._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class Tree[A, +B](@(inline @getter) final val key: A) + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} diff --git a/test/files/run/reify_ann4.check b/test/files/run/reify_ann4.check new file mode 100644 index 0000000000..406ee7bc08 --- /dev/null +++ b/test/files/run/reify_ann4.check @@ -0,0 +1,32 @@ +{ + class D extends StaticAnnotation { + def () = { + super.(); + () + } + }; + class C extends Object { + def () = { + super.(); + () + } + }; + val c1 = new C @D(); + () +} +{ + class D extends scala.annotation.Annotation with scala.annotation.StaticAnnotation { + def (): D = { + D.super.(); + () + } + }; + class C extends Object { + def (): C = { + C.super.(); + () + } + }; + val c1: C = new C @D(); + () +} diff --git a/test/files/run/reify_ann4.scala b/test/files/run/reify_ann4.scala new file mode 100644 index 0000000000..5655812689 --- /dev/null +++ b/test/files/run/reify_ann4.scala @@ -0,0 +1,23 @@ +import scala.reflect.mirror._ +import scala.annotation._ +import scala.annotation.meta._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class D extends StaticAnnotation + class C + val c1 = new C @D + //val c2 = (new C) @D // illegal syntax + //val c3 = c1 @D // illegal syntax + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} diff --git a/test/files/run/reify_ann5.check b/test/files/run/reify_ann5.check new file mode 100644 index 0000000000..ecf08eebb2 --- /dev/null +++ b/test/files/run/reify_ann5.check @@ -0,0 +1,22 @@ +{ + class C extends Object { + @new inline @beanGetter() @new BeanProperty() val x: Int = _; + def (x: Int) = { + super.(); + () + } + }; + () +} +{ + class C extends Object { + @scala.beans.BeanProperty private[this] val x: Int = _; + def x: Int = C.this.x; + def (x: Int): C = { + C.super.(); + () + }; + @inline @scala.annotation.meta.beanGetter def getX(): Int = C.this.x + }; + () +} diff --git a/test/files/run/reify_ann5.scala b/test/files/run/reify_ann5.scala new file mode 100644 index 0000000000..aecc61de46 --- /dev/null +++ b/test/files/run/reify_ann5.scala @@ -0,0 +1,20 @@ +import scala.reflect.mirror._ +import scala.annotation._ +import scala.annotation.meta._ +import scala.beans._ + +object Test extends App { + // test 1: reify + val tree = reify{ + class C(@BeanProperty @(inline @beanGetter) val x: Int) + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} diff --git a/test/files/run/reify_anonymous.scala b/test/files/run/reify_anonymous.scala index af16f2f8fd..cd740f0190 100644 --- a/test/files/run/reify_anonymous.scala +++ b/test/files/run/reify_anonymous.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { println(new {def x = 2; def y = x * x}.y) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_classfileann_a.check b/test/files/run/reify_classfileann_a.check index 419d916907..685ecf5de6 100644 --- a/test/files/run/reify_classfileann_a.check +++ b/test/files/run/reify_classfileann_a.check @@ -1,18 +1,18 @@ -{ - @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends scala.AnyRef { - def () = { - super.(); - () - } - }; - () -} -{ - @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends scala.AnyRef { - def (): C = { - C.super.(); - () - } - }; - () -} +{ + @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends Object { + def () = { + super.(); + () + } + }; + () +} +{ + @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends Object { + def (): C = { + C.super.(); + () + } + }; + () +} diff --git a/test/files/run/reify_classfileann_a.scala b/test/files/run/reify_classfileann_a.scala index c77bd3b8a2..c3e7d8d2e9 100644 --- a/test/files/run/reify_classfileann_a.scala +++ b/test/files/run/reify_classfileann_a.scala @@ -1,21 +1,16 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation object Test extends App { // test 1: reify - val tree = scala.reflect.Code.lift{ + val tree = reify{ @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) class C }.tree println(tree.toString) // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(tree) println(ttree.toString) diff --git a/test/files/run/reify_classfileann_b.check b/test/files/run/reify_classfileann_b.check new file mode 100644 index 0000000000..0aac9aeb2a --- /dev/null +++ b/test/files/run/reify_classfileann_b.check @@ -0,0 +1,20 @@ +{ + class C extends Object { + def () = { + super.(); + () + }; + def x: Int = 2: @ann(bar = "1",quux = Array("2", "3"),baz = new ann(bar = "4")) + }; + () +} +{ + class C extends Object { + def (): C = { + C.super.(); + () + }; + def x: Int = (2: Int(2) @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4"))) + }; + () +} diff --git a/test/files/run/reify_classfileann_b.scala b/test/files/run/reify_classfileann_b.scala new file mode 100644 index 0000000000..4e50494af3 --- /dev/null +++ b/test/files/run/reify_classfileann_b.scala @@ -0,0 +1,23 @@ +import scala.reflect.mirror._ + +class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation + +object Test extends App { + // test 1: reify + val tree = reify{ + class C { + def x: Int = { + 2: @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) + } + } + }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(tree) +} \ No newline at end of file diff --git a/test/files/run/reify_closure1.scala b/test/files/run/reify_closure1.scala index 7cb3aff17d..3f5c8a8724 100644 --- a/test/files/run/reify_closure1.scala +++ b/test/files/run/reify_closure1.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo[T](ys: List[T]): Int => Int = { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure2a.scala b/test/files/run/reify_closure2a.scala index cf367aa63f..f5669a0e2c 100644 --- a/test/files/run/reify_closure2a.scala +++ b/test/files/run/reify_closure2a.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo(y: Int): Int => Int = { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x + y }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure3a.scala b/test/files/run/reify_closure3a.scala index d322b970b6..056a705d7d 100644 --- a/test/files/run/reify_closure3a.scala +++ b/test/files/run/reify_closure3a.scala @@ -1,17 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo(y: Int): Int => Int = { def y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x + y1 }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure4a.scala b/test/files/run/reify_closure4a.scala index bbedd7e092..a63d20e561 100644 --- a/test/files/run/reify_closure4a.scala +++ b/test/files/run/reify_closure4a.scala @@ -1,17 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { def foo(y: Int): Int => Int = { val y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { x + y1 }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/files/run/reify_closure5a.scala b/test/files/run/reify_closure5a.scala index 193e18103a..2e8b413f4c 100644 --- a/test/files/run/reify_closure5a.scala +++ b/test/files/run/reify_closure5a.scala @@ -1,19 +1,18 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - def foo[T](ys: List[T]): Int => Int = { - val fun = reflect.Code.lift{(x: Int) => { + def foo[T: TypeTag](ys: List[T]): Int => Int = { + val fun = reify{(x: Int) => { x + ys.length }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } - println(foo(List(1, 2, 3))(10)) - println(foo(List(1, 2, 3, 4))(10)) + var fun1 = foo(List(1, 2, 3)) + println(fun1(10)) + var fun2 = foo(List(1, 2, 3, 4)) + println(fun2(10)) } diff --git a/test/files/run/reify_closure6.scala b/test/files/run/reify_closure6.scala index 6aff83cb94..2cbd4ce819 100644 --- a/test/files/run/reify_closure6.scala +++ b/test/files/run/reify_closure6.scala @@ -1,13 +1,11 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { var q = 0 - def foo[T](ys: List[T]): Int => Int = { + def foo[T: TypeTag](ys: List[T]): Int => Int = { val z = 1 var y = 0 - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { y += 1 q += 1 println("q = " + q) @@ -15,13 +13,14 @@ object Test extends App { x + ys.length * z + q + y }} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) dyn.asInstanceOf[Int => Int] } - println("first invocation = " + foo(List(1, 2, 3))(10)) - println("second invocation = " + foo(List(1, 2, 3, 4))(10)) + val fun1 = foo(List(1, 2, 3)) + println("first invocation = " + fun1(10)) + val fun2 = foo(List(1, 2, 3, 4)) + println("second invocation = " + fun2(10)) println("q after second invocation = " + q) } \ No newline at end of file diff --git a/test/files/run/reify_closure7.scala b/test/files/run/reify_closure7.scala index 46002d8d6c..b9f87dbdeb 100644 --- a/test/files/run/reify_closure7.scala +++ b/test/files/run/reify_closure7.scala @@ -1,14 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { var q = 0 var clo: Int => Int = null - def foo[T](ys: List[T]): Int => Int = { + def foo[T: TypeTag](ys: List[T]): Int => Int = { val z = 1 var y = 0 - val fun = reflect.Code.lift{(x: Int) => { + val fun = reify{(x: Int) => { y += 1 q += 1 println("q = " + q) @@ -17,8 +15,7 @@ object Test extends App { }} if (clo == null) { - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun.tree) clo = dyn.asInstanceOf[Int => Int] } @@ -26,6 +23,8 @@ object Test extends App { clo } - println("first invocation = " + foo(List(1, 2, 3))(10)) - println("second invocation = " + foo(List(1, 2, 3, 4))(10)) + val fun1 = foo(List(1, 2, 3)) + println("first invocation = " + fun1(10)) + val fun2 = foo(List(1, 2, 3, 4)) + println("second invocation = " + fun2(10)) } diff --git a/test/files/run/reify_closure8a.scala b/test/files/run/reify_closure8a.scala index 805d8ff855..9de121b42f 100644 --- a/test/files/run/reify_closure8a.scala +++ b/test/files/run/reify_closure8a.scala @@ -1,15 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { class Foo(val y: Int) { - def fun = lift{y} + def fun = reify{y} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(10).fun.tree) val foo = dyn.asInstanceOf[Int] println(foo) diff --git a/test/files/run/reify_closure8b.check b/test/files/run/reify_closure8b.check new file mode 100644 index 0000000000..e0ec7d2c8f --- /dev/null +++ b/test/files/run/reify_closure8b.check @@ -0,0 +1,3 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective compilation has failed: + +value y is not a member of Test.Foo diff --git a/test/files/run/reify_closure8b.scala b/test/files/run/reify_closure8b.scala new file mode 100644 index 0000000000..431da3230e --- /dev/null +++ b/test/files/run/reify_closure8b.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + // will fail because y is a private field + // reification doesn't magically make unavailable stuff available + class Foo(y: Int) { + def fun = reify{y} + } + + try { + val dyn = mkToolBox().runExpr(new Foo(10).fun.tree) + val foo = dyn.asInstanceOf[Int] + println(foo) + } catch { + case ex: Throwable => + println(ex) + } +} diff --git a/test/files/run/reify_closures10.scala b/test/files/run/reify_closures10.scala index b6ec8e8911..0ccce77a94 100644 --- a/test/files/run/reify_closures10.scala +++ b/test/files/run/reify_closures10.scala @@ -1,14 +1,10 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { val x = 2 val y = 3 - val code = lift{println(x + y); x + y} + val code = reify{println(x + y); x + y} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(toolbox.runExpr(code.tree)) } diff --git a/test/files/run/reify_complex.scala b/test/files/run/reify_complex.scala index 0d9aeb28c5..ecc25ffca5 100644 --- a/test/files/run/reify_complex.scala +++ b/test/files/run/reify_complex.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class Complex(val re: Double, val im: Double) { def + (that: Complex) = new Complex(re + that.re, im + that.im) @@ -22,9 +20,5 @@ object Test extends App { } val x = new Complex(2, 1); val y = new Complex(1, 3) println(x + y) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_extendbuiltins.scala b/test/files/run/reify_extendbuiltins.scala index 0aaec7cdf2..f95e9ab6ec 100644 --- a/test/files/run/reify_extendbuiltins.scala +++ b/test/files/run/reify_extendbuiltins.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n class Factorizer(n: Int) { @@ -12,9 +10,5 @@ object Test extends App { implicit def int2fact(n: Int) = new Factorizer(n) println("10! = " + (10!)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_for1.scala b/test/files/run/reify_for1.scala index d1b60d878b..9d1e32f7e5 100644 --- a/test/files/run/reify_for1.scala +++ b/test/files/run/reify_for1.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val sumOfSquares1 = (for (i <- 1 to 100; if (i % 3 == 0)) yield Math.pow(i, 2)).sum val sumOfSquares2 = (1 to 100).filter(_ % 3 == 0).map(Math.pow(_, 2)).sum assert(sumOfSquares1 == sumOfSquares2) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_fors.scala b/test/files/run/reify_fors.scala index 27ee85d18b..635fce049e 100644 --- a/test/files/run/reify_fors.scala +++ b/test/files/run/reify_fors.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object Persons { /** A list of persons. To create a list, we use Predef.List * which takes a variable number of arguments and constructs @@ -98,9 +96,5 @@ object Test extends App { val ys = List(2.0, 1.0, 3.0) println("scalProd(" + xs + ", " + ys +") = " + scalProd(xs, ys)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_generic.scala b/test/files/run/reify_generic.scala index 6a4ff148c4..7033c4e237 100644 --- a/test/files/run/reify_generic.scala +++ b/test/files/run/reify_generic.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val product = List(1, 2, 3).head * List[Any](4, 2, 0).head.asInstanceOf[Int] println(product) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_generic2.scala b/test/files/run/reify_generic2.scala index 9413f41eb5..8f9def318e 100644 --- a/test/files/run/reify_generic2.scala +++ b/test/files/run/reify_generic2.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C val product = List(new C, new C).length * List[C](new C, new C).length println(product) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_getter.scala b/test/files/run/reify_getter.scala index 33f36888a7..8bae293e72 100644 --- a/test/files/run/reify_getter.scala +++ b/test/files/run/reify_getter.scala @@ -1,18 +1,15 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { val x = 2 } new C().x - }; + } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/reify_implicits.scala b/test/files/run/reify_implicits.scala index 953eabe6c2..60971c3cfb 100644 --- a/test/files/run/reify_implicits.scala +++ b/test/files/run/reify_implicits.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { implicit def arrayWrapper[A : ClassManifest](x: Array[A]) = new { def sort(p: (A, A) => Boolean) = { @@ -12,9 +10,5 @@ object Test extends App { } val x = Array(2, 3, 1, 4) println("x = "+ x.sort((x: Int, y: Int) => x < y).toList) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inheritance.scala b/test/files/run/reify_inheritance.scala index 78a64c264e..dd86c355a3 100644 --- a/test/files/run/reify_inheritance.scala +++ b/test/files/run/reify_inheritance.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { def x = 2 def y = x * x @@ -14,9 +12,5 @@ object Test extends App { } println(new D().y * new C().x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner1.scala b/test/files/run/reify_inner1.scala index 546fe36d16..ea77ece6df 100644 --- a/test/files/run/reify_inner1.scala +++ b/test/files/run/reify_inner1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { class D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = new C() val inner = new outer.D() println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner2.scala b/test/files/run/reify_inner2.scala index 613614b989..67c403f7e5 100644 --- a/test/files/run/reify_inner2.scala +++ b/test/files/run/reify_inner2.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { object D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = new C() val inner = outer.D println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner3.scala b/test/files/run/reify_inner3.scala index e9fb636dce..ad401d81da 100644 --- a/test/files/run/reify_inner3.scala +++ b/test/files/run/reify_inner3.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C { class D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = C val inner = new outer.D println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_inner4.scala b/test/files/run/reify_inner4.scala index 33870b0983..140c8e9ed4 100644 --- a/test/files/run/reify_inner4.scala +++ b/test/files/run/reify_inner4.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C { object D { val x = 2 @@ -13,9 +11,5 @@ object Test extends App { val outer = C val inner = outer.D println(inner.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_maps.scala b/test/files/run/reify_maps.scala index d3d95ffa24..3fcc21892f 100644 --- a/test/files/run/reify_maps.scala +++ b/test/files/run/reify_maps.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val colors = Map("red" -> 0xFF0000, "turquoise" -> 0x00FFFF, "black" -> 0x000000, @@ -17,9 +15,5 @@ object Test extends App { "Unknown color: " + name } ) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_metalevel_breach_+0_refers_to_1.check b/test/files/run/reify_metalevel_breach_+0_refers_to_1.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_+0_refers_to_1.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala b/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala new file mode 100644 index 0000000000..fe23bc8438 --- /dev/null +++ b/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify{ + val x = 2 + val inner = reify{x} + inner.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala new file mode 100644 index 0000000000..5d98a38592 --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + val x = 2 + val outer = reify{reify{x}} + val code = reify{outer.eval.eval} + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala new file mode 100644 index 0000000000..ca31d83acd --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + val x = 2 + val code = reify{ + { + val inner = reify{reify{x}} + inner.eval + }.eval + } + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_1.check b/test/files/run/reify_metalevel_breach_-1_refers_to_1.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_1.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala new file mode 100644 index 0000000000..56d85c6ba1 --- /dev/null +++ b/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify{ + val x = 2 + val inner = reify{reify{x}} + inner.eval.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_inner_refers_to_global.check b/test/files/run/reify_nested_inner_refers_to_global.check new file mode 100644 index 0000000000..7ff4c83d37 --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_global.check @@ -0,0 +1 @@ +evaluated = 2 diff --git a/test/files/run/reify_nested_inner_refers_to_global.scala b/test/files/run/reify_nested_inner_refers_to_global.scala new file mode 100644 index 0000000000..14899bcf99 --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_global.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = { + val x = 2 + reify{ + reify{x}.eval + } + } + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_inner_refers_to_local.check b/test/files/run/reify_nested_inner_refers_to_local.check new file mode 100644 index 0000000000..5bfed17f8e --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_local.check @@ -0,0 +1 @@ +evaluated = 2 \ No newline at end of file diff --git a/test/files/run/reify_nested_inner_refers_to_local.scala b/test/files/run/reify_nested_inner_refers_to_local.scala new file mode 100644 index 0000000000..fd56585f72 --- /dev/null +++ b/test/files/run/reify_nested_inner_refers_to_local.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify{ + val x = 2 + reify{x}.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_outer_refers_to_global.check b/test/files/run/reify_nested_outer_refers_to_global.check new file mode 100644 index 0000000000..7ff4c83d37 --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_global.check @@ -0,0 +1 @@ +evaluated = 2 diff --git a/test/files/run/reify_nested_outer_refers_to_global.scala b/test/files/run/reify_nested_outer_refers_to_global.scala new file mode 100644 index 0000000000..f34e4fe04b --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_global.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = { + val x = 2 + val outer = reify{x} + reify{ + val x = 42 + outer.eval + }; + } + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_nested_outer_refers_to_local.check b/test/files/run/reify_nested_outer_refers_to_local.check new file mode 100644 index 0000000000..7ff4c83d37 --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_local.check @@ -0,0 +1 @@ +evaluated = 2 diff --git a/test/files/run/reify_nested_outer_refers_to_local.scala b/test/files/run/reify_nested_outer_refers_to_local.scala new file mode 100644 index 0000000000..e16c851d8d --- /dev/null +++ b/test/files/run/reify_nested_outer_refers_to_local.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + val outer = { + val x = 2 + reify{x} + } + val code = reify{ + val x = 42 + outer.eval + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_newimpl_01.check b/test/files/run/reify_newimpl_01.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_01.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_01.scala b/test/files/run/reify_newimpl_01.scala new file mode 100644 index 0000000000..f7539a15b0 --- /dev/null +++ b/test/files/run/reify_newimpl_01.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 2 + val code = reify { + x + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_02.check b/test/files/run/reify_newimpl_02.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_02.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_02.scala b/test/files/run/reify_newimpl_02.scala new file mode 100644 index 0000000000..2c085efa04 --- /dev/null +++ b/test/files/run/reify_newimpl_02.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var x = 2 + val code = reify { + x + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_03.check b/test/files/run/reify_newimpl_03.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_03.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_03.scala b/test/files/run/reify_newimpl_03.scala new file mode 100644 index 0000000000..361cfc50bb --- /dev/null +++ b/test/files/run/reify_newimpl_03.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val code = reify { + val x = 2 + reify{x}.eval + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_04.check b/test/files/run/reify_newimpl_04.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_04.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_04.scala b/test/files/run/reify_newimpl_04.scala new file mode 100644 index 0000000000..d80a7c9ffd --- /dev/null +++ b/test/files/run/reify_newimpl_04.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val code = reify { + var x = 2 + reify{x}.eval + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_05.check b/test/files/run/reify_newimpl_05.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_05.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_05.scala b/test/files/run/reify_newimpl_05.scala new file mode 100644 index 0000000000..85c1711bdb --- /dev/null +++ b/test/files/run/reify_newimpl_05.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val code = reify { + var x = 2 + def y = x // forcibly captures x + reify{x}.eval + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_06.check b/test/files/run/reify_newimpl_06.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_06.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_06.scala b/test/files/run/reify_newimpl_06.scala new file mode 100644 index 0000000000..257b54167a --- /dev/null +++ b/test/files/run/reify_newimpl_06.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C(val y: Int) { + val code = reify { + reify{y}.eval + } + } + + println(new C(2).code.eval) +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_09.check b/test/files/run/reify_newimpl_09.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_09.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_09.scala b/test/files/run/reify_newimpl_09.scala new file mode 100644 index 0000000000..2c81945a2a --- /dev/null +++ b/test/files/run/reify_newimpl_09.scala @@ -0,0 +1,11 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_10.check b/test/files/run/reify_newimpl_10.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_10.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_10.scala b/test/files/run/reify_newimpl_10.scala new file mode 100644 index 0000000000..6e70b4d216 --- /dev/null +++ b/test/files/run/reify_newimpl_10.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + type T = Int + implicit val tt = implicitly[TypeTag[String]].asInstanceOf[TypeTag[T]] // this "mistake" is made for a reason! + val code = reify { + List[T](2) + } + println(code.eval) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_11.check b/test/files/run/reify_newimpl_11.check new file mode 100644 index 0000000000..e2a8206132 --- /dev/null +++ b/test/files/run/reify_newimpl_11.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: T defined by C in reify_newimpl_11.scala:4:11). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_11.scala b/test/files/run/reify_newimpl_11.scala new file mode 100644 index 0000000000..4e91c7a457 --- /dev/null +++ b/test/files/run/reify_newimpl_11.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C[Int] + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_12.check b/test/files/run/reify_newimpl_12.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_12.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_12.scala b/test/files/run/reify_newimpl_12.scala new file mode 100644 index 0000000000..433168ce28 --- /dev/null +++ b/test/files/run/reify_newimpl_12.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T: TypeTag] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C[Int] +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_13.check b/test/files/run/reify_newimpl_13.check new file mode 100644 index 0000000000..7c47310cf2 --- /dev/null +++ b/test/files/run/reify_newimpl_13.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: T defined by C in reify_newimpl_13.scala:5:13). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_13.scala b/test/files/run/reify_newimpl_13.scala new file mode 100644 index 0000000000..dd1980b74f --- /dev/null +++ b/test/files/run/reify_newimpl_13.scala @@ -0,0 +1,19 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C[T] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C[Int] + } catch { + case ex: Throwable => + println(ex) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_14.check b/test/files/run/reify_newimpl_14.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_14.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_14.scala b/test/files/run/reify_newimpl_14.scala new file mode 100644 index 0000000000..3f52f19cfb --- /dev/null +++ b/test/files/run/reify_newimpl_14.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C[T: TypeTag] { + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C[Int] + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_15.check b/test/files/run/reify_newimpl_15.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_15.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_15.scala b/test/files/run/reify_newimpl_15.scala new file mode 100644 index 0000000000..b707b2583d --- /dev/null +++ b/test/files/run/reify_newimpl_15.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + new C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_16.check b/test/files/run/reify_newimpl_16.check new file mode 100644 index 0000000000..220bd6875a --- /dev/null +++ b/test/files/run/reify_newimpl_16.check @@ -0,0 +1 @@ +List(2) \ No newline at end of file diff --git a/test/files/run/reify_newimpl_16.scala b/test/files/run/reify_newimpl_16.scala new file mode 100644 index 0000000000..98fc15878c --- /dev/null +++ b/test/files/run/reify_newimpl_16.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + new C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_17.check b/test/files/run/reify_newimpl_17.check new file mode 100644 index 0000000000..0fb9ddfc2d --- /dev/null +++ b/test/files/run/reify_newimpl_17.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: U defined by C in reify_newimpl_17.scala:4:11). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_17.scala b/test/files/run/reify_newimpl_17.scala new file mode 100644 index 0000000000..331777fcfb --- /dev/null +++ b/test/files/run/reify_newimpl_17.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[U] { + type T = U + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C[Int] + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_18.check b/test/files/run/reify_newimpl_18.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_18.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_18.scala b/test/files/run/reify_newimpl_18.scala new file mode 100644 index 0000000000..704e54928a --- /dev/null +++ b/test/files/run/reify_newimpl_18.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[U: TypeTag] { + type T = U + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C[Int] +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_19.check b/test/files/run/reify_newimpl_19.check new file mode 100644 index 0000000000..32f9300f53 --- /dev/null +++ b/test/files/run/reify_newimpl_19.check @@ -0,0 +1,2 @@ +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed: +unresolved free type variables (namely: T defined by C in reify_newimpl_19.scala:5:10). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types diff --git a/test/files/run/reify_newimpl_19.scala b/test/files/run/reify_newimpl_19.scala new file mode 100644 index 0000000000..0ea8ae6992 --- /dev/null +++ b/test/files/run/reify_newimpl_19.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + try { + new C { val T = Int } + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_20.check b/test/files/run/reify_newimpl_20.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_20.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_20.scala b/test/files/run/reify_newimpl_20.scala new file mode 100644 index 0000000000..16895a449e --- /dev/null +++ b/test/files/run/reify_newimpl_20.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T + implicit val tt: TypeTag[T] = implicitly[TypeTag[Int]].asInstanceOf[TypeTag[T]] + val code = reify { + List[T](2.asInstanceOf[T]) + } + println(code.eval) + } + + new C { type T = String } // this "mistake" is made for a reason! +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_21.check b/test/files/run/reify_newimpl_21.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_21.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_21.scala b/test/files/run/reify_newimpl_21.scala new file mode 100644 index 0000000000..99f9ac9089 --- /dev/null +++ b/test/files/run/reify_newimpl_21.scala @@ -0,0 +1,18 @@ +import scala.reflect.mirror._ + +object Test extends App { + trait C { + type T + implicit val tt: TypeTag[T] + lazy val code = reify { + List[T](2.asInstanceOf[T]) + } + } + + class D extends C { + type T = String // this "mistake" is made for a reason! + override val tt: TypeTag[T] = implicitly[TypeTag[Int]].asInstanceOf[TypeTag[T]] + } + + println((new D).code.eval) +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_22.check b/test/files/run/reify_newimpl_22.check new file mode 100644 index 0000000000..51699cbc29 --- /dev/null +++ b/test/files/run/reify_newimpl_22.check @@ -0,0 +1,23 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> { + val x = 2 + val code = reify { + x + } + println(code.eval) +} +:13: free term: Ident(newTermName("x")) defined by res0 in :12:21 + val code = reify { + ^ +2 + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_22.scala b/test/files/run/reify_newimpl_22.scala new file mode 100644 index 0000000000..a211ad360c --- /dev/null +++ b/test/files/run/reify_newimpl_22.scala @@ -0,0 +1,15 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-terms" + def code = """ +import scala.reflect.mirror._ +{ + val x = 2 + val code = reify { + x + } + println(code.eval) +} + """ +} diff --git a/test/files/run/reify_newimpl_23.check b/test/files/run/reify_newimpl_23.check new file mode 100644 index 0000000000..33d15190fb --- /dev/null +++ b/test/files/run/reify_newimpl_23.check @@ -0,0 +1,22 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> def foo[T]{ + val code = reify { + List[T]() + } + println(code.eval) +} +:11: free type: Ident(newTypeName("T")) defined by foo in :10:16 + val code = reify { + ^ +foo: [T]=> Unit + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_23.scala b/test/files/run/reify_newimpl_23.scala new file mode 100644 index 0000000000..15da4e497e --- /dev/null +++ b/test/files/run/reify_newimpl_23.scala @@ -0,0 +1,14 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-types" + def code = """ +import scala.reflect.mirror._ +def foo[T]{ + val code = reify { + List[T]() + } + println(code.eval) +} + """ +} diff --git a/test/files/run/reify_newimpl_24.check b/test/files/run/reify_newimpl_24.check new file mode 100644 index 0000000000..66b18c790e --- /dev/null +++ b/test/files/run/reify_newimpl_24.check @@ -0,0 +1,24 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> { + val x = 2 + val code = reify { + val y = reify { x } + y.eval + } + println(code.eval) +} +:15: this splice cannot be resolved statically + y.eval + ^ +2 + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_24.scala b/test/files/run/reify_newimpl_24.scala new file mode 100644 index 0000000000..7b21eeeb10 --- /dev/null +++ b/test/files/run/reify_newimpl_24.scala @@ -0,0 +1,16 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-runtime-splices" + def code = """ +import scala.reflect.mirror._ +{ + val x = 2 + val code = reify { + val y = reify { x } + y.eval + } + println(code.eval) +} + """ +} diff --git a/test/files/run/reify_newimpl_25.check b/test/files/run/reify_newimpl_25.check new file mode 100644 index 0000000000..31ece627e1 --- /dev/null +++ b/test/files/run/reify_newimpl_25.check @@ -0,0 +1,21 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> { + val x = "2" + val tt = implicitly[TypeTag[x.type]] + println(tt) +} +:13: free term: Ident(newTermName("x")) defined by res0 in :12:21 + val tt = implicitly[TypeTag[x.type]] + ^ +GroundTypeTag[x.type] + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_25.scala b/test/files/run/reify_newimpl_25.scala new file mode 100644 index 0000000000..1f66f5e681 --- /dev/null +++ b/test/files/run/reify_newimpl_25.scala @@ -0,0 +1,13 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-terms" + def code = """ +import scala.reflect.mirror._ +{ + val x = "2" + val tt = implicitly[TypeTag[x.type]] + println(tt) +} + """ +} diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check new file mode 100644 index 0000000000..68b0ee8c99 --- /dev/null +++ b/test/files/run/reify_newimpl_26.check @@ -0,0 +1,23 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.mirror._ +import scala.reflect.mirror._ + +scala> def foo[T]{ + val tt = implicitly[TypeTag[List[T]]] + println(tt) +} +:11: free type: Ident(newTypeName("T")) defined by foo in :10:16 + val tt = implicitly[TypeTag[List[T]]] + ^ +foo: [T]=> Unit + +scala> foo[Int] +GroundTypeTag[List[T]] + +scala> + +scala> diff --git a/test/files/run/reify_newimpl_26.scala b/test/files/run/reify_newimpl_26.scala new file mode 100644 index 0000000000..f2dd1bfc4e --- /dev/null +++ b/test/files/run/reify_newimpl_26.scala @@ -0,0 +1,13 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-types" + def code = """ +import scala.reflect.mirror._ +def foo[T]{ + val tt = implicitly[TypeTag[List[T]]] + println(tt) +} +foo[Int] + """ +} diff --git a/test/files/run/reify_newimpl_27.check b/test/files/run/reify_newimpl_27.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_27.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_27.scala b/test/files/run/reify_newimpl_27.scala new file mode 100644 index 0000000000..b3d6d5c865 --- /dev/null +++ b/test/files/run/reify_newimpl_27.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + object C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_28.check b/test/files/run/reify_newimpl_28.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_28.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_28.scala b/test/files/run/reify_newimpl_28.scala new file mode 100644 index 0000000000..f7874b8548 --- /dev/null +++ b/test/files/run/reify_newimpl_28.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + object C { + type T = Int + val code = reify { + List[T](2) + } + println(code.eval) + } + + C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_29.check b/test/files/run/reify_newimpl_29.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_29.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_29.scala b/test/files/run/reify_newimpl_29.scala new file mode 100644 index 0000000000..e32762f335 --- /dev/null +++ b/test/files/run/reify_newimpl_29.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C { + type T = Int + val code = reify { + List[C#T](2) + } + println(code.eval) + } + + new C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_30.check b/test/files/run/reify_newimpl_30.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_30.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_30.scala b/test/files/run/reify_newimpl_30.scala new file mode 100644 index 0000000000..e4ba3221e1 --- /dev/null +++ b/test/files/run/reify_newimpl_30.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C { + type T = Int + val code = reify { + List[C#T](2) + } + println(code.eval) + } + + new C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_31.check b/test/files/run/reify_newimpl_31.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_31.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_31.scala b/test/files/run/reify_newimpl_31.scala new file mode 100644 index 0000000000..20a851e32e --- /dev/null +++ b/test/files/run/reify_newimpl_31.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + object C { + type T = Int + val code = reify { + List[C.T](2) + } + println(code.eval) + } + + C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_32.check b/test/files/run/reify_newimpl_32.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_32.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_32.scala b/test/files/run/reify_newimpl_32.scala new file mode 100644 index 0000000000..788486ec00 --- /dev/null +++ b/test/files/run/reify_newimpl_32.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + object C { + type T = Int + val code = reify { + List[C.T](2) + } + println(code.eval) + } + + C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_33.check b/test/files/run/reify_newimpl_33.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_33.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_33.scala b/test/files/run/reify_newimpl_33.scala new file mode 100644 index 0000000000..84a8258256 --- /dev/null +++ b/test/files/run/reify_newimpl_33.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + object C { + type T = Int + val c = C + val code = reify { + List[c.T](2) + } + println(code.eval) + } + + C +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_34.check b/test/files/run/reify_newimpl_34.check new file mode 100644 index 0000000000..a7029974a4 --- /dev/null +++ b/test/files/run/reify_newimpl_34.check @@ -0,0 +1 @@ +List(2) diff --git a/test/files/run/reify_newimpl_34.scala b/test/files/run/reify_newimpl_34.scala new file mode 100644 index 0000000000..5935ab385c --- /dev/null +++ b/test/files/run/reify_newimpl_34.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + object C { + type T = Int + lazy val c = C + val code = reify { + List[c.T](2) + } + println(code.eval) + } + + C + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_36.check b/test/files/run/reify_newimpl_36.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_36.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_36.scala b/test/files/run/reify_newimpl_36.scala new file mode 100644 index 0000000000..c76efce27a --- /dev/null +++ b/test/files/run/reify_newimpl_36.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify(reify(x)); + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + println(code2.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_37.check b/test/files/run/reify_newimpl_37.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_37.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_37.scala b/test/files/run/reify_newimpl_37.scala new file mode 100644 index 0000000000..e83d35dbe1 --- /dev/null +++ b/test/files/run/reify_newimpl_37.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify(reify(reify(x))); + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + val code3 = code2.eval + println(code3.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_38.check b/test/files/run/reify_newimpl_38.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_38.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_38.scala b/test/files/run/reify_newimpl_38.scala new file mode 100644 index 0000000000..70ef49ecf7 --- /dev/null +++ b/test/files/run/reify_newimpl_38.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify{ val y = x; reify(y) }; + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + println(code2.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_39.check b/test/files/run/reify_newimpl_39.check new file mode 100644 index 0000000000..2f562a182f --- /dev/null +++ b/test/files/run/reify_newimpl_39.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/reify_newimpl_39.scala b/test/files/run/reify_newimpl_39.scala new file mode 100644 index 0000000000..faa45d917d --- /dev/null +++ b/test/files/run/reify_newimpl_39.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify{ val y = x; reify{ val z = y; reify(z) } }; + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + val code3 = code2.eval + println(code3.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_40.check b/test/files/run/reify_newimpl_40.check new file mode 100644 index 0000000000..94c5a65fe0 --- /dev/null +++ b/test/files/run/reify_newimpl_40.check @@ -0,0 +1 @@ +74088 diff --git a/test/files/run/reify_newimpl_40.scala b/test/files/run/reify_newimpl_40.scala new file mode 100644 index 0000000000..a983a92324 --- /dev/null +++ b/test/files/run/reify_newimpl_40.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + val x = 42 + def foo() = reify{ val y = x; reify{ val z = y * x; reify(z * x) } }; + { + val x = 2 + val code1 = foo() + val code2 = code1.eval + val code3 = code2.eval + println(code3.eval) + } + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_41.check b/test/files/run/reify_newimpl_41.check new file mode 100644 index 0000000000..0b427f2ee6 --- /dev/null +++ b/test/files/run/reify_newimpl_41.check @@ -0,0 +1,3 @@ +42 +44 +43 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_41.scala b/test/files/run/reify_newimpl_41.scala new file mode 100644 index 0000000000..9aedccc98a --- /dev/null +++ b/test/files/run/reify_newimpl_41.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var _x = 42 + def x = { val x0 = _x; _x += 1; x0 } + var _y = 1 + def y = { val y0 = _y + _x; _y += y0; y0 } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_42.check b/test/files/run/reify_newimpl_42.check new file mode 100644 index 0000000000..0b427f2ee6 --- /dev/null +++ b/test/files/run/reify_newimpl_42.check @@ -0,0 +1,3 @@ +42 +44 +43 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_42.scala b/test/files/run/reify_newimpl_42.scala new file mode 100644 index 0000000000..1e21bd59bc --- /dev/null +++ b/test/files/run/reify_newimpl_42.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var _x = 42 + def x = { val x0 = _x; _x += 1; x0 } + var _y = 1 + def y = { val y0 = _y + _x; _y += y0; y0 } + val code = reify { + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_43.check b/test/files/run/reify_newimpl_43.check new file mode 100644 index 0000000000..7a754f414c --- /dev/null +++ b/test/files/run/reify_newimpl_43.check @@ -0,0 +1,2 @@ +1 +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_43.scala b/test/files/run/reify_newimpl_43.scala new file mode 100644 index 0000000000..962461db8b --- /dev/null +++ b/test/files/run/reify_newimpl_43.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_44.check b/test/files/run/reify_newimpl_44.check new file mode 100644 index 0000000000..7a754f414c --- /dev/null +++ b/test/files/run/reify_newimpl_44.check @@ -0,0 +1,2 @@ +1 +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_44.scala b/test/files/run/reify_newimpl_44.scala new file mode 100644 index 0000000000..962461db8b --- /dev/null +++ b/test/files/run/reify_newimpl_44.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_45.check b/test/files/run/reify_newimpl_45.check new file mode 100644 index 0000000000..6e14f71e26 --- /dev/null +++ b/test/files/run/reify_newimpl_45.check @@ -0,0 +1,2 @@ +List(free type T) +ima worx: 2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_45.scala b/test/files/run/reify_newimpl_45.scala new file mode 100644 index 0000000000..241b7d4bc3 --- /dev/null +++ b/test/files/run/reify_newimpl_45.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T >: Null] { + val code = reify{val x: T = "2".asInstanceOf[T]; println("ima worx: %s".format(x)); x} + println(freeTypes(code)) + val T = freeTypes(code)(0) + mkToolBox().runExpr(code, Map(T -> definitions.StringClass.asType)) + } + + new C[String] +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_47.check b/test/files/run/reify_newimpl_47.check new file mode 100644 index 0000000000..d8263ee986 --- /dev/null +++ b/test/files/run/reify_newimpl_47.check @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_47.scala b/test/files/run/reify_newimpl_47.scala new file mode 100644 index 0000000000..bd1bd1fe65 --- /dev/null +++ b/test/files/run/reify_newimpl_47.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + val outer = { + val x = 2 + reify{x} + } + + val code = reify{ + val x = 42 + outer.eval + } + + println(code.eval) +} diff --git a/test/files/run/reify_newimpl_48.check b/test/files/run/reify_newimpl_48.check new file mode 100644 index 0000000000..f11c82a4cb --- /dev/null +++ b/test/files/run/reify_newimpl_48.check @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_48.scala b/test/files/run/reify_newimpl_48.scala new file mode 100644 index 0000000000..1522509907 --- /dev/null +++ b/test/files/run/reify_newimpl_48.scala @@ -0,0 +1,20 @@ +import scala.reflect.mirror._ + +object Test extends App { + val outer1 = { + val x = 2 + reify{x} + } + + val outer2 = { + val x = 3 + reify{x} + } + + val code = reify{ + val x = 4 + x + outer1.eval + outer2.eval + } + + println(code.eval) +} diff --git a/test/files/run/reify_newimpl_49.check b/test/files/run/reify_newimpl_49.check new file mode 100644 index 0000000000..d8a621df00 --- /dev/null +++ b/test/files/run/reify_newimpl_49.check @@ -0,0 +1,3 @@ +3 +3 +5 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_49.scala b/test/files/run/reify_newimpl_49.scala new file mode 100644 index 0000000000..68d968e28b --- /dev/null +++ b/test/files/run/reify_newimpl_49.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var y = 1 + def x = { y += 2; y } + val code = reify { + def foo = y // ensures that y is the first freevar we find + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_50.check b/test/files/run/reify_newimpl_50.check new file mode 100644 index 0000000000..d8a621df00 --- /dev/null +++ b/test/files/run/reify_newimpl_50.check @@ -0,0 +1,3 @@ +3 +3 +5 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_50.scala b/test/files/run/reify_newimpl_50.scala new file mode 100644 index 0000000000..b81d72a4eb --- /dev/null +++ b/test/files/run/reify_newimpl_50.scala @@ -0,0 +1,14 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var y = 1 + def x = { y += 2; y } + val code = reify { + println(x) + println(y) + println(x) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_51.check b/test/files/run/reify_newimpl_51.check new file mode 100644 index 0000000000..9a4ddeacd3 --- /dev/null +++ b/test/files/run/reify_newimpl_51.check @@ -0,0 +1,3 @@ +2 +1 +2 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_51.scala b/test/files/run/reify_newimpl_51.scala new file mode 100644 index 0000000000..ccbae2e160 --- /dev/null +++ b/test/files/run/reify_newimpl_51.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + val bar = reify { println(x * y) } + bar.eval + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_newimpl_52.check b/test/files/run/reify_newimpl_52.check new file mode 100644 index 0000000000..9359a2b211 --- /dev/null +++ b/test/files/run/reify_newimpl_52.check @@ -0,0 +1,3 @@ +2 +2 +1 \ No newline at end of file diff --git a/test/files/run/reify_newimpl_52.scala b/test/files/run/reify_newimpl_52.scala new file mode 100644 index 0000000000..60b16d3618 --- /dev/null +++ b/test/files/run/reify_newimpl_52.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + var counter = 0 + lazy val x = { counter += 1; counter } + lazy val y = { counter += 1; counter } + val code = reify { + def foo = y // ensures that y is the first freevar we find + val bar = reify { println(y * x) } + bar.eval + println(x) + println(y) + } + code.eval + } +} \ No newline at end of file diff --git a/test/files/run/reify_printf.scala b/test/files/run/reify_printf.scala index cd6052bc5e..dc092c1a85 100644 --- a/test/files/run/reify_printf.scala +++ b/test/files/run/reify_printf.scala @@ -1,19 +1,15 @@ import java.io.{ ByteArrayOutputStream, PrintStream } -import scala.reflect.Code import scala.reflect.mirror._ import scala.reflect.api._ import scala.reflect.api.Trees import scala.reflect.internal.Types -import reflect.runtime.Mirror.ToolBox -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings import scala.util.matching.Regex object Test extends App { - val tree = tree_printf(Code.lift("hello %s").tree, Code.lift("world").tree) + val tree = tree_printf(reify("hello %s").tree, reify("world").tree) - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter, args mkString " ") + import scala.reflect.mirror._ + val toolbox = mkToolBox() val output = new ByteArrayOutputStream() Console.setOut(new PrintStream(output)) @@ -22,6 +18,7 @@ object Test extends App { assert(output.toString() == "hello world", output.toString() +" == hello world") /* + // upd. Oh, good old times, our very-very first experiments with macros :) macro def printf(format: String, params: Any*) : String = tree_printf(format: Tree, (params: Seq[Tree]): _*) */ diff --git a/test/files/run/reify_sort.scala b/test/files/run/reify_sort.scala index 5984a64967..0b373b358f 100644 --- a/test/files/run/reify_sort.scala +++ b/test/files/run/reify_sort.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /** Nested methods can use and even update everything * visible in their scope (including local variables or * arguments of enclosing methods). @@ -48,9 +46,5 @@ object Test extends App { println(ar) sort(ar) println(ar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_sort1.scala b/test/files/run/reify_sort1.scala index 6f365dea26..56125619e9 100644 --- a/test/files/run/reify_sort1.scala +++ b/test/files/run/reify_sort1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def sort(a: List[Int]): List[Int] = { if (a.length < 2) a @@ -18,9 +16,5 @@ object Test extends App { val xs = List(6, 2, 8, 5, 1) println(xs) println(sort(xs)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_this.scala b/test/files/run/reify_this.scala index ee1f116013..280d735ab6 100644 --- a/test/files/run/reify_this.scala +++ b/test/files/run/reify_this.scala @@ -1,30 +1,19 @@ -import scala.reflect._ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ trait Eval { - def eval(code: Code): Any = eval(code.tree) - - def eval(tree: Tree): Any = { - val settings = new Settings - val reporter = new ConsoleReporter(settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(tree) - } + def eval(tree: Expr[_]) = tree.eval } object Test extends App with Eval { // select a value from package - eval(lift{println("foo")}) - eval(lift{println((new Object).toString == (new Object).toString)}) + eval(reify{println("foo")}) + eval(reify{println((new Object).toString == (new Object).toString)}) // select a type from package - eval(lift{val x: Any = 2; println(x)}) - eval(lift{val x: Object = "bar"; println(x)}) + eval(reify{val x: Any = 2; println(x)}) + eval(reify{val x: Object = "bar"; println(x)}) // select a value from module val x = 2 - eval(lift{println(x)}) + eval(reify{println(x)}) } diff --git a/test/files/run/reify_timeofday.scala b/test/files/run/reify_timeofday.scala index 122d7a6d52..481ab04df5 100644 --- a/test/files/run/reify_timeofday.scala +++ b/test/files/run/reify_timeofday.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class DateError extends Exception /** Simulating properties in Scala @@ -39,9 +37,5 @@ object Test extends App { case de: DateError => println("DateError") case e: Exception => println("Exception") } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/reify_typerefs_1a.check b/test/files/run/reify_typerefs_1a.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_1a.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_1a.scala b/test/files/run/reify_typerefs_1a.scala new file mode 100644 index 0000000000..15d8d17835 --- /dev/null +++ b/test/files/run/reify_typerefs_1a.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +class Expression { + override def toString = "Expression" +} + +object Test extends App { + val code = reify { + List(new Expression, new Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_1b.check b/test/files/run/reify_typerefs_1b.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_1b.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_1b.scala b/test/files/run/reify_typerefs_1b.scala new file mode 100644 index 0000000000..06ce1e35ac --- /dev/null +++ b/test/files/run/reify_typerefs_1b.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Expression { + override def toString = "Expression" +} + +object Test extends App { + val code = reify { + List(Expression, Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_2a.check b/test/files/run/reify_typerefs_2a.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_2a.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_2a.scala b/test/files/run/reify_typerefs_2a.scala new file mode 100644 index 0000000000..d03efea222 --- /dev/null +++ b/test/files/run/reify_typerefs_2a.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +package foo { + class Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(new foo.Expression, new foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_2b.check b/test/files/run/reify_typerefs_2b.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_2b.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_2b.scala b/test/files/run/reify_typerefs_2b.scala new file mode 100644 index 0000000000..3d9f7d61b8 --- /dev/null +++ b/test/files/run/reify_typerefs_2b.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +package foo { + object Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(foo.Expression, foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_3a.check b/test/files/run/reify_typerefs_3a.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_3a.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_3a.scala b/test/files/run/reify_typerefs_3a.scala new file mode 100644 index 0000000000..4128073f60 --- /dev/null +++ b/test/files/run/reify_typerefs_3a.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object foo { + class Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(new foo.Expression, new foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_typerefs_3b.check b/test/files/run/reify_typerefs_3b.check new file mode 100644 index 0000000000..919c298ba3 --- /dev/null +++ b/test/files/run/reify_typerefs_3b.check @@ -0,0 +1 @@ +evaluated = List(Expression, Expression) \ No newline at end of file diff --git a/test/files/run/reify_typerefs_3b.scala b/test/files/run/reify_typerefs_3b.scala new file mode 100644 index 0000000000..a7ede00c9c --- /dev/null +++ b/test/files/run/reify_typerefs_3b.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object foo { + object Expression { + override def toString = "Expression" + } +} + +object Test extends App { + val code = reify { + List(foo.Expression, foo.Expression) + }; + + val toolbox = mkToolBox() + val evaluated = toolbox.runExpr(code.tree) + println("evaluated = " + evaluated) +} diff --git a/test/files/run/reify_varargs.scala b/test/files/run/reify_varargs.scala index 175cfb5db0..fe8f03b702 100644 --- a/test/files/run/reify_varargs.scala +++ b/test/files/run/reify_varargs.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val msg = java.text.MessageFormat.format( "On {1} there was {2} on planet {0}.", "Hoth", "the fifth of August", "a disturbance in the Force") println("Message="+msg) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index 1e7b6f0cd8..b811a4a8c5 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -1,32 +1,32 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> :power -** Power User mode enabled - BEEP WHIR GYVE ** -** :phase has been set to 'typer'. ** -** scala.tools.nsc._ has been imported ** -** global._, definitions._ also imported ** -** Try :help, :vals, power. ** - -scala> // guarding against "error: reference to global is ambiguous" - -scala> global.emptyValDef // "it is imported twice in the same scope by ..." -res0: $r.global.emptyValDef.type = private val _ = _ - -scala> val tp = ArrayClass[scala.util.Random] // magic with manifests -tp: $r.global.Type = Array[scala.util.Random] - -scala> tp.memberType(Array_apply) // evidence -res1: $r.global.Type = (i: Int)scala.util.Random - -scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl -m: $r.treedsl.global.Match = -10 match { - case 5 => false - case _ => true -} - -scala> typed(m).tpe // typed is in scope -res2: $r.treedsl.global.Type = Boolean - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> :power +** Power User mode enabled - BEEP WHIR GYVE ** +** :phase has been set to 'typer'. ** +** scala.tools.nsc._ has been imported ** +** global._, definitions._ also imported ** +** Try :help, :vals, power. ** + +scala> // guarding against "error: reference to global is ambiguous" + +scala> global.emptyValDef // "it is imported twice in the same scope by ..." +res0: $r.global.emptyValDef.type = private val _ = _ + +scala> val tp = ArrayClass[scala.util.Random] // magic with manifests +tp: $r.global.Type = Array[scala.util.Random] + +scala> tp.memberType(Array_apply) // evidence +res1: $r.global.Type = (i: Int)scala.util.Random + +scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl +m: $r.treedsl.global.Match = +10 match { + case 5 => false + case _ => true +} + +scala> typed(m).tpe // typed is in scope +res2: $r.treedsl.global.Type = Boolean + +scala> diff --git a/test/files/run/t1195.check b/test/files/run/t1195.check deleted file mode 100644 index d023bc91f7..0000000000 --- a/test/files/run/t1195.check +++ /dev/null @@ -1,6 +0,0 @@ -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable diff --git a/test/files/run/t1195.check.temporarily.disabled b/test/files/run/t1195.check.temporarily.disabled new file mode 100644 index 0000000000..d023bc91f7 --- /dev/null +++ b/test/files/run/t1195.check.temporarily.disabled @@ -0,0 +1,6 @@ +_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with scala.Product with scala.Serializable +Object with scala.Product with scala.Serializable +_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with scala.Product with scala.Serializable +Object with scala.Product with scala.Serializable diff --git a/test/files/run/t1195.scala b/test/files/run/t1195.scala deleted file mode 100644 index 81ef5bdb0e..0000000000 --- a/test/files/run/t1195.scala +++ /dev/null @@ -1,26 +0,0 @@ -object Test { - def f() = { case class Bar(x: Int); Bar } - def g() = { case class Bar(x: Int); Bar(5) } - def h() = { case object Bar ; Bar } - - val f1 = f() - val g1 = g() - val h1 = h() - - def m[T: Manifest](x: T) = println(manifest[T]) - - def main(args: Array[String]): Unit = { - m(f) - m(g) - m(h) - m(f1) - m(g1) - m(h1) - } -} - -class A1[T] { - class B1[U] { - def f = { case class D(x: Int) extends A1[String] ; new D(5) } - } -} diff --git a/test/files/run/t1195.scala.temporarily.disabled b/test/files/run/t1195.scala.temporarily.disabled new file mode 100644 index 0000000000..81ef5bdb0e --- /dev/null +++ b/test/files/run/t1195.scala.temporarily.disabled @@ -0,0 +1,26 @@ +object Test { + def f() = { case class Bar(x: Int); Bar } + def g() = { case class Bar(x: Int); Bar(5) } + def h() = { case object Bar ; Bar } + + val f1 = f() + val g1 = g() + val h1 = h() + + def m[T: Manifest](x: T) = println(manifest[T]) + + def main(args: Array[String]): Unit = { + m(f) + m(g) + m(h) + m(f1) + m(g1) + m(h1) + } +} + +class A1[T] { + class B1[U] { + def f = { case class D(x: Int) extends A1[String] ; new D(5) } + } +} diff --git a/test/files/run/t3758.check b/test/files/run/t3758.check new file mode 100644 index 0000000000..9c6ab655a3 --- /dev/null +++ b/test/files/run/t3758.check @@ -0,0 +1,6 @@ +List(String) +List(Int) +List(Float) +List(String) +List(Int) +List(Float) diff --git a/test/files/run/t3758.scala b/test/files/run/t3758.scala index 18750b0a9c..10bfb5724b 100644 --- a/test/files/run/t3758.scala +++ b/test/files/run/t3758.scala @@ -1,10 +1,10 @@ object Test { def main(args: Array[String]): Unit = { - assert(classManifest[Array[String]].typeArguments contains classManifest[String]) - assert(classManifest[Array[Int]].typeArguments contains classManifest[Int]) - assert(classManifest[Array[Float]].typeArguments contains classManifest[Float]) - assert(manifest[Array[String]].typeArguments contains manifest[String]) - assert(manifest[Array[Int]].typeArguments contains manifest[Int]) - assert(manifest[Array[Float]].typeArguments contains manifest[Float]) + println(classManifest[Array[String]].tpe.typeArguments) + println(classManifest[Array[Int]].tpe.typeArguments) + println(classManifest[Array[Float]].tpe.typeArguments) + println(manifest[Array[String]].tpe.typeArguments) + println(manifest[Array[Int]].tpe.typeArguments) + println(manifest[Array[Float]].tpe.typeArguments) } } diff --git a/test/files/run/t4110.check b/test/files/run/t4110.check deleted file mode 100644 index 8b005989de..0000000000 --- a/test/files/run/t4110.check +++ /dev/null @@ -1,2 +0,0 @@ -Object with Test$A with Test$B -Object with Test$A with Test$B diff --git a/test/files/run/t4110.check.temporarily.disabled b/test/files/run/t4110.check.temporarily.disabled new file mode 100644 index 0000000000..8b005989de --- /dev/null +++ b/test/files/run/t4110.check.temporarily.disabled @@ -0,0 +1,2 @@ +Object with Test$A with Test$B +Object with Test$A with Test$B diff --git a/test/files/run/t4110.scala b/test/files/run/t4110.scala deleted file mode 100644 index 4bd377b73e..0000000000 --- a/test/files/run/t4110.scala +++ /dev/null @@ -1,11 +0,0 @@ -object Test extends App { - def inferredType[T : Manifest](v : T) = println(manifest[T]) - - trait A - trait B - - inferredType(new A with B) - - val name = new A with B - inferredType(name) -} \ No newline at end of file diff --git a/test/files/run/t4110.scala.temporarily.disabled b/test/files/run/t4110.scala.temporarily.disabled new file mode 100644 index 0000000000..4bd377b73e --- /dev/null +++ b/test/files/run/t4110.scala.temporarily.disabled @@ -0,0 +1,11 @@ +object Test extends App { + def inferredType[T : Manifest](v : T) = println(manifest[T]) + + trait A + trait B + + inferredType(new A with B) + + val name = new A with B + inferredType(name) +} \ No newline at end of file diff --git a/test/files/run/t5224.check b/test/files/run/t5224.check index 28bc75d4fd..c754f23551 100644 --- a/test/files/run/t5224.check +++ b/test/files/run/t5224.check @@ -1,9 +1,9 @@ -{ - @new Foo(bar = "qwe") class C extends scala.AnyRef { - def () = { - super.(); - () - } - }; - () -} +{ + @new Foo(bar = "qwe") class C extends Object { + def () = { + super.(); + () + } + }; + () +} diff --git a/test/files/run/t5224.scala b/test/files/run/t5224.scala index 2226a69a05..93b244e03e 100644 --- a/test/files/run/t5224.scala +++ b/test/files/run/t5224.scala @@ -1,9 +1,8 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ class Foo(bar: String) extends ClassfileAnnotation object Test extends App { - val tree = scala.reflect.Code.lift{@Foo(bar = "qwe") class C}.tree + val tree = reify{@Foo(bar = "qwe") class C}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5225_1.check b/test/files/run/t5225_1.check index 719da572c7..40db2468b1 100644 --- a/test/files/run/t5225_1.check +++ b/test/files/run/t5225_1.check @@ -1,4 +1,4 @@ -{ - @new transient() @new volatile() var x: Int = 2; - () -} +{ + @new transient() @new volatile() var x = 2; + () +} diff --git a/test/files/run/t5225_1.scala b/test/files/run/t5225_1.scala index a655b7dd71..5e1d3b1f17 100644 --- a/test/files/run/t5225_1.scala +++ b/test/files/run/t5225_1.scala @@ -1,7 +1,6 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ object Test extends App { - val tree = scala.reflect.Code.lift{@transient @volatile var x = 2}.tree + val tree = reify{@transient @volatile var x = 2}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5225_2.check b/test/files/run/t5225_2.check index c4f6b4761e..8cd2ddc1a4 100644 --- a/test/files/run/t5225_2.check +++ b/test/files/run/t5225_2.check @@ -1,4 +1,4 @@ -{ - def foo(@new cloneable() x: Int): String = ""; - () -} +{ + def foo(@new cloneable() x: Int) = ""; + () +} diff --git a/test/files/run/t5225_2.scala b/test/files/run/t5225_2.scala index 65ea9b2f73..4cab640fe8 100644 --- a/test/files/run/t5225_2.scala +++ b/test/files/run/t5225_2.scala @@ -1,7 +1,6 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ object Test extends App { - val tree = scala.reflect.Code.lift{def foo(@cloneable x: Int) = ""}.tree + val tree = reify{def foo(@cloneable x: Int) = ""}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5229_1.scala b/test/files/run/t5229_1.scala index d5af569656..273079a89d 100644 --- a/test/files/run/t5229_1.scala +++ b/test/files/run/t5229_1.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5229_2.scala b/test/files/run/t5229_2.scala index 07f9ac6b84..85bf78ba31 100644 --- a/test/files/run/t5229_2.scala +++ b/test/files/run/t5229_2.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { object C { val x = 2 } @@ -11,8 +9,7 @@ object Test extends App { println(C.x) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/t5230.scala b/test/files/run/t5230.scala index d3106ca05c..e0632f591c 100644 --- a/test/files/run/t5230.scala +++ b/test/files/run/t5230.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { val x = 2 } @@ -11,8 +9,7 @@ object Test extends App { println(new C().x) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/t5258a.check b/test/files/run/t5258a.check deleted file mode 100644 index 4e0b2da04c..0000000000 --- a/test/files/run/t5258a.check +++ /dev/null @@ -1 +0,0 @@ -int \ No newline at end of file diff --git a/test/files/run/t5258a.scala b/test/files/run/t5258a.scala deleted file mode 100644 index 8cc4249e06..0000000000 --- a/test/files/run/t5258a.scala +++ /dev/null @@ -1,13 +0,0 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - val code = scala.reflect.Code.lift{ - println(classOf[Int]) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) -} \ No newline at end of file diff --git a/test/files/run/t5266_1.scala b/test/files/run/t5266_1.scala index 4262bc7a7b..ebb432be71 100644 --- a/test/files/run/t5266_1.scala +++ b/test/files/run/t5266_1.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { def x = 2 println(x) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } \ No newline at end of file diff --git a/test/files/run/t5266_2.scala b/test/files/run/t5266_2.scala index d0f718dbd7..27c91c35a8 100644 --- a/test/files/run/t5266_2.scala +++ b/test/files/run/t5266_2.scala @@ -1,16 +1,13 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { def x = 2 def y = x println(y) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val evaluated = toolbox.runExpr(code.tree) println("evaluated = " + evaluated) } diff --git a/test/files/run/t5269.scala b/test/files/run/t5269.scala index cab99f17e6..9026090b29 100644 --- a/test/files/run/t5269.scala +++ b/test/files/run/t5269.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { trait Z { val z = 2 } @@ -13,9 +11,5 @@ object Test extends App { } new X().println() - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5270.scala b/test/files/run/t5270.scala index 934cc13dea..476b610148 100644 --- a/test/files/run/t5270.scala +++ b/test/files/run/t5270.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class Y { def y = 100 } @@ -17,9 +15,5 @@ object Test extends App { } new X().println() - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5271_1.check b/test/files/run/t5271_1.check index 9b956da17a..7a728e5164 100644 --- a/test/files/run/t5271_1.check +++ b/test/files/run/t5271_1.check @@ -1,11 +1,11 @@ -{ - case class C extends Object with Product with Serializable { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - () -} +{ + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + () +} diff --git a/test/files/run/t5271_1.scala b/test/files/run/t5271_1.scala index fbc57aead7..5baa57c290 100644 --- a/test/files/run/t5271_1.scala +++ b/test/files/run/t5271_1.scala @@ -1,13 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { case class C(foo: Int, bar: Int) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(code.tree) } diff --git a/test/files/run/t5271_2.check b/test/files/run/t5271_2.check index 27297febb6..d8d6edeffc 100644 --- a/test/files/run/t5271_2.check +++ b/test/files/run/t5271_2.check @@ -1,12 +1,12 @@ -{ - case class C extends Object with Product with Serializable { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - val c = C.apply(2, 2); - scala.this.Predef.println(c.foo.$times(c.bar)) -} +{ + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + val c = C.apply(2, 2); + scala.this.Predef.println(c.foo.$times(c.bar)) +} diff --git a/test/files/run/t5271_2.scala b/test/files/run/t5271_2.scala index 4bfc574e00..9820ebe692 100644 --- a/test/files/run/t5271_2.scala +++ b/test/files/run/t5271_2.scala @@ -1,15 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(code.tree) } diff --git a/test/files/run/t5271_3.check b/test/files/run/t5271_3.check index 9331c78959..1d4f47c5df 100644 --- a/test/files/run/t5271_3.check +++ b/test/files/run/t5271_3.check @@ -1,19 +1,19 @@ -{ - object C extends scala.AnyRef with Serializable { - def () = { - super.(); - () - }; - def qwe: Int = 4 - }; - case class C extends Object with Product with Serializable { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - val c = C.apply(2, 2); - scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe)) -} +{ + object C extends Object { + def () = { + super.(); + () + }; + def qwe = 4 + }; + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + val c = C.apply(2, 2); + scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe)) +} diff --git a/test/files/run/t5271_3.scala b/test/files/run/t5271_3.scala index a085bdca4c..5fd94f4a2b 100644 --- a/test/files/run/t5271_3.scala +++ b/test/files/run/t5271_3.scala @@ -1,16 +1,13 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { object C { def qwe = 4 } case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar == C.qwe) }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(code.tree) } diff --git a/test/files/run/t5271_4.scala b/test/files/run/t5271_4.scala index c253b1adca..e13a331d9c 100644 --- a/test/files/run/t5271_4.scala +++ b/test/files/run/t5271_4.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case object C - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5272_1.scala b/test/files/run/t5272_1.scala index 882287f033..46472babf3 100644 --- a/test/files/run/t5272_1.scala +++ b/test/files/run/t5272_1.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { 2 match { case 2 => println("okay") case _ => println("not okay") } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5272_2.scala b/test/files/run/t5272_2.scala index 48b6a670bb..f5bab44205 100644 --- a/test/files/run/t5272_2.scala +++ b/test/files/run/t5272_2.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { 2 match { case x => println("okay" + x) } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5273_1.scala b/test/files/run/t5273_1.scala index 80460a4ae6..1b491923b2 100644 --- a/test/files/run/t5273_1.scala +++ b/test/files/run/t5273_1.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { List(1, 2, 3) match { case foo :: bar :: _ => println(foo * bar) case _ => println("this is getting out of hand!") } - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5273_2a.scala b/test/files/run/t5273_2a.scala index a7a336d8a7..062ff79d11 100644 --- a/test/files/run/t5273_2a.scala +++ b/test/files/run/t5273_2a.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val foo :: bar :: _ = List(1, 2, 3) println(foo * bar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5273_2b.scala b/test/files/run/t5273_2b.scala index 85c40f0607..82f1de89f7 100644 --- a/test/files/run/t5273_2b.scala +++ b/test/files/run/t5273_2b.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { val RegexParser = """(.*) \d+([A-Z]+) \| (.*) \|.*""".r val RegexParser(name, shortname, value) = "American Dollar 1USD | 2,8567 | sometext" println("name = %s, shortname = %s, value = %s".format(name, shortname, value)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5274_1.scala b/test/files/run/t5274_1.scala index 74a5b81bcb..7ef332aa05 100644 --- a/test/files/run/t5274_1.scala +++ b/test/files/run/t5274_1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def factorial(n: BigInt): BigInt = if (n == 0) 1 else n * factorial(n-1) @@ -11,9 +9,5 @@ object Test extends App { println("50! = " + f50) println("49! = " + f49) println("50!/49! = " + (f50 / f49)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5274_2.scala b/test/files/run/t5274_2.scala index 5984a64967..0b373b358f 100644 --- a/test/files/run/t5274_2.scala +++ b/test/files/run/t5274_2.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /** Nested methods can use and even update everything * visible in their scope (including local variables or * arguments of enclosing methods). @@ -48,9 +46,5 @@ object Test extends App { println(ar) sort(ar) println(ar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5275.scala b/test/files/run/t5275.scala index 285d8a18a4..534672be3c 100644 --- a/test/files/run/t5275.scala +++ b/test/files/run/t5275.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C(val foo: Int) println(new C(2).foo) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_1a.scala b/test/files/run/t5276_1a.scala index b717675824..a6e327c0e7 100644 --- a/test/files/run/t5276_1a.scala +++ b/test/files/run/t5276_1a.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { lazy val x = 2 println(x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_1b.scala b/test/files/run/t5276_1b.scala index 1ff25504ca..1bc3e246c9 100644 --- a/test/files/run/t5276_1b.scala +++ b/test/files/run/t5276_1b.scala @@ -1,14 +1,8 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { implicit lazy val x = 2 println(implicitly[Int]) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_2a.scala b/test/files/run/t5276_2a.scala index af5ff2a565..cdd87ddc9e 100644 --- a/test/files/run/t5276_2a.scala +++ b/test/files/run/t5276_2a.scala @@ -1,17 +1,11 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { lazy val x = 2 } println(new C().x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5276_2b.scala b/test/files/run/t5276_2b.scala index 63904b2898..2fac951731 100644 --- a/test/files/run/t5276_2b.scala +++ b/test/files/run/t5276_2b.scala @@ -1,18 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C { implicit lazy val x = 2 def y = implicitly[Int] } println(new C().y) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5277_1.scala b/test/files/run/t5277_1.scala index 0aaec7cdf2..f95e9ab6ec 100644 --- a/test/files/run/t5277_1.scala +++ b/test/files/run/t5277_1.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n class Factorizer(n: Int) { @@ -12,9 +10,5 @@ object Test extends App { implicit def int2fact(n: Int) = new Factorizer(n) println("10! = " + (10!)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5277_2.scala b/test/files/run/t5277_2.scala index 91ed55122a..5f1737f503 100644 --- a/test/files/run/t5277_2.scala +++ b/test/files/run/t5277_2.scala @@ -1,17 +1,11 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { def p(implicit i: Int) = print(i) implicit val v = 2 println(p) println(p(1)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5279.scala b/test/files/run/t5279.scala index cef58535d5..aab5588877 100644 --- a/test/files/run/t5279.scala +++ b/test/files/run/t5279.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { println(new Integer(10)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5334_1.scala b/test/files/run/t5334_1.scala index 9887bebf78..49dbea6b68 100644 --- a/test/files/run/t5334_1.scala +++ b/test/files/run/t5334_1.scala @@ -1,14 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { override def toString = "C" } - new C + val ret = new C + ret.asInstanceOf[Object] }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(toolbox.runExpr(code.tree)) } diff --git a/test/files/run/t5334_2.scala b/test/files/run/t5334_2.scala index 775a05aaf7..c6a77158dd 100644 --- a/test/files/run/t5334_2.scala +++ b/test/files/run/t5334_2.scala @@ -1,14 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + val code = reify { class C { override def toString() = "C" } - List((new C, new C)) + val ret = List((new C, new C)) + ret.asInstanceOf[List[Any]] }; - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() println(toolbox.runExpr(code.tree)) } diff --git a/test/files/run/t5335.scala b/test/files/run/t5335.scala index 8e2ed59db6..a0fe6c5822 100644 --- a/test/files/run/t5335.scala +++ b/test/files/run/t5335.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { println(new {def x = 2}.x) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/files/run/t5415.scala b/test/files/run/t5415.scala index 3db356da86..c6552f69b3 100644 --- a/test/files/run/t5415.scala +++ b/test/files/run/t5415.scala @@ -1,14 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import scala.reflect.runtime.Mirror.ToolBox - object Test extends App{ case class Queryable2[T]() { def filter(predicate: T => Boolean) = ??? } trait CoffeesTable{ def sales : Int } val q = Queryable2[CoffeesTable]() - val code = scala.reflect.Code.lift{q.filter(_.sales > 5)} + import scala.reflect.mirror._ + val code = reify{q.filter(_.sales > 5)} - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val ttree = toolbox.typeCheck(code.tree) } diff --git a/test/files/run/t5419.check b/test/files/run/t5419.check index 7e6d739354..50751b168e 100644 --- a/test/files/run/t5419.check +++ b/test/files/run/t5419.check @@ -1 +1 @@ -(5: Int(5) @Foo) +5: @Foo.asInstanceOf[Int] diff --git a/test/files/run/t5419.scala b/test/files/run/t5419.scala index 695786e5c4..d65d8f38c8 100644 --- a/test/files/run/t5419.scala +++ b/test/files/run/t5419.scala @@ -1,9 +1,8 @@ -import scala.reflect._ -import scala.reflect.api._ +import scala.reflect.mirror._ class Foo extends StaticAnnotation object Test extends App { - val tree = scala.reflect.Code.lift{5: @Foo}.tree + val tree = reify{(5: @Foo).asInstanceOf[Int]}.tree println(tree.toString) } \ No newline at end of file diff --git a/test/files/run/t5423.scala b/test/files/run/t5423.scala index fc507c417b..645c8c7c1d 100644 --- a/test/files/run/t5423.scala +++ b/test/files/run/t5423.scala @@ -1,7 +1,4 @@ -import java.lang.Class import scala.reflect.mirror._ -import scala.reflect.runtime.Mirror.ToolBox -import scala.reflect.Code final class table extends StaticAnnotation @table class A diff --git a/test/files/run/toolbox_console_reporter.check b/test/files/run/toolbox_console_reporter.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/run/toolbox_console_reporter.scala b/test/files/run/toolbox_console_reporter.scala new file mode 100644 index 0000000000..fd244b40ec --- /dev/null +++ b/test/files/run/toolbox_console_reporter.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + // todo. cannot test this unfortunately, because ConsoleReporter grabs Console.out too early + // todo. and isn't affected by Console.setOut employed by partest to intercept output + + //val toolbox = mkToolBox(reporter = mkConsoleReporter(), options = "-deprecation") + //toolbox.runExpr(reify{ + // object Utils { + // @deprecated("test", "2.10.0") + // def foo { println("hello") } + // } + // + // Utils.foo + //}) +} diff --git a/test/files/run/toolbox_default_reporter_is_silent.check b/test/files/run/toolbox_default_reporter_is_silent.check new file mode 100644 index 0000000000..ef0493b275 --- /dev/null +++ b/test/files/run/toolbox_default_reporter_is_silent.check @@ -0,0 +1 @@ +hello diff --git a/test/files/run/toolbox_default_reporter_is_silent.scala b/test/files/run/toolbox_default_reporter_is_silent.scala new file mode 100644 index 0000000000..78606e2abc --- /dev/null +++ b/test/files/run/toolbox_default_reporter_is_silent.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox() + toolbox.runExpr(reify{ + object Utils { + @deprecated("test", "2.10.0") + def foo { println("hello") } + } + + Utils.foo + }) +} diff --git a/test/files/run/toolbox_silent_reporter.check b/test/files/run/toolbox_silent_reporter.check new file mode 100644 index 0000000000..2d05b1e3f8 --- /dev/null +++ b/test/files/run/toolbox_silent_reporter.check @@ -0,0 +1,4 @@ +hello +============compiler messages============ +Info(NoPosition,method foo in object Utils is deprecated: test,WARNING) +========================================= diff --git a/test/files/run/toolbox_silent_reporter.scala b/test/files/run/toolbox_silent_reporter.scala new file mode 100644 index 0000000000..7e9259946b --- /dev/null +++ b/test/files/run/toolbox_silent_reporter.scala @@ -0,0 +1,16 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox(options = "-deprecation") + toolbox.runExpr(reify{ + object Utils { + @deprecated("test", "2.10.0") + def foo { println("hello") } + } + + Utils.foo + }) + println("============compiler messages============") + toolbox.reporter.infos.foreach(println(_)) + println("=========================================") +} \ No newline at end of file diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.check b/test/files/run/toolbox_typecheck_implicitsdisabled.check new file mode 100644 index 0000000000..4bc64530ab --- /dev/null +++ b/test/files/run/toolbox_typecheck_implicitsdisabled.check @@ -0,0 +1,5 @@ +{ + import scala.Predef._; + scala.Predef.any2ArrowAssoc[Int](1).->[Int](2) +} +scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective typecheck has failed: value -> is not a member of Int diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.scala b/test/files/run/toolbox_typecheck_implicitsdisabled.scala new file mode 100644 index 0000000000..9d52e91f73 --- /dev/null +++ b/test/files/run/toolbox_typecheck_implicitsdisabled.scala @@ -0,0 +1,24 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox() + + val tree1 = Block( + Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))), + Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + ) + val ttree1 = toolbox.typeCheck(tree1, withImplicitViewsDisabled = false) + println(ttree1) + + try { + val tree2 = Block( + Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))), + Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2)))) + ) + val ttree2 = toolbox.typeCheck(tree2, withImplicitViewsDisabled = true) + println(ttree2) + } catch { + case ex: Throwable => + println(ex) + } +} \ No newline at end of file diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check new file mode 100644 index 0000000000..fe2323ea06 --- /dev/null +++ b/test/files/run/toolbox_typecheck_macrosdisabled.check @@ -0,0 +1,5 @@ +{ + val $mr: mr.type = mr; + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) +} +mr.reify[Int](2) diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.scala b/test/files/run/toolbox_typecheck_macrosdisabled.scala new file mode 100644 index 0000000000..7d2707d5e1 --- /dev/null +++ b/test/files/run/toolbox_typecheck_macrosdisabled.scala @@ -0,0 +1,17 @@ +import scala.reflect.mirror._ + +object Test extends App { + val toolbox = mkToolBox() + val mrPkg = staticModule("scala.reflect.package") + val mrSym = selectTerm(mrPkg, "mirror") + val NullaryMethodType(mrTpe) = mrSym.typeSignature + val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null) + + val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false) + println(ttree1) + + val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2)))) + val ttree2 = toolbox.typeCheck(tree2, withMacrosDisabled = true) + println(ttree2) +} diff --git a/test/files/run/treePrint.check b/test/files/run/treePrint.check deleted file mode 100644 index 3360815ac1..0000000000 --- a/test/files/run/treePrint.check +++ /dev/null @@ -1,5 +0,0 @@ -def foo = { - var q: Boolean = false; - val x = 5; - ((x == 5) || (!q)) || (true) -} diff --git a/test/files/run/treePrint.check.temporarily.disabled b/test/files/run/treePrint.check.temporarily.disabled new file mode 100644 index 0000000000..3360815ac1 --- /dev/null +++ b/test/files/run/treePrint.check.temporarily.disabled @@ -0,0 +1,5 @@ +def foo = { + var q: Boolean = false; + val x = 5; + ((x == 5) || (!q)) || (true) +} diff --git a/test/files/run/treePrint.scala b/test/files/run/treePrint.scala deleted file mode 100644 index e0332a705f..0000000000 --- a/test/files/run/treePrint.scala +++ /dev/null @@ -1,42 +0,0 @@ -/** Testing compact tree printers. - */ -object Test { - import scala.tools.nsc._ - import interpreter._ - import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter} - - val code = """ - def foo = { - var q: Boolean = false - val x = if (true) { - if (true) { - if (true) { - 5 - } - else if (true) { - 5 - } else { - 10 - } - } - else 20 - } - else 30 - - (x == 5) || !q || true - } - """ - - class NullOutputStream extends OutputStream { def write(b: Int) { } } - - def main(args: Array[String]) { - val settings = new Settings - settings.classpath.value = System.getProperty("java.class.path") - settings.Ycompacttrees.value = true - - val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) - val power = new Power(intp, new ReplVals { }) - intp.interpret("""def initialize = "Have to interpret something or we get errors." """) - power trees code foreach println - } -} diff --git a/test/files/run/treePrint.scala.temporarily.disabled b/test/files/run/treePrint.scala.temporarily.disabled new file mode 100644 index 0000000000..e0332a705f --- /dev/null +++ b/test/files/run/treePrint.scala.temporarily.disabled @@ -0,0 +1,42 @@ +/** Testing compact tree printers. + */ +object Test { + import scala.tools.nsc._ + import interpreter._ + import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter} + + val code = """ + def foo = { + var q: Boolean = false + val x = if (true) { + if (true) { + if (true) { + 5 + } + else if (true) { + 5 + } else { + 10 + } + } + else 20 + } + else 30 + + (x == 5) || !q || true + } + """ + + class NullOutputStream extends OutputStream { def write(b: Int) { } } + + def main(args: Array[String]) { + val settings = new Settings + settings.classpath.value = System.getProperty("java.class.path") + settings.Ycompacttrees.value = true + + val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) + val power = new Power(intp, new ReplVals { }) + intp.interpret("""def initialize = "Have to interpret something or we get errors." """) + power trees code foreach println + } +} diff --git a/test/files/run/typetags_core.check b/test/files/run/typetags_core.check new file mode 100644 index 0000000000..d1b71f0926 --- /dev/null +++ b/test/files/run/typetags_core.check @@ -0,0 +1,30 @@ +true +GroundTypeTag[Byte] +true +GroundTypeTag[Short] +true +GroundTypeTag[Char] +true +GroundTypeTag[Int] +true +GroundTypeTag[Long] +true +GroundTypeTag[Float] +true +GroundTypeTag[Double] +true +GroundTypeTag[Boolean] +true +GroundTypeTag[Unit] +true +GroundTypeTag[Any] +true +GroundTypeTag[Object] +true +GroundTypeTag[AnyVal] +true +GroundTypeTag[AnyRef] +true +GroundTypeTag[Null] +true +GroundTypeTag[Nothing] diff --git a/test/files/run/typetags_core.scala b/test/files/run/typetags_core.scala new file mode 100644 index 0000000000..883c54b9a8 --- /dev/null +++ b/test/files/run/typetags_core.scala @@ -0,0 +1,32 @@ +object Test extends App { + println(implicitly[TypeTag[Byte]] eq TypeTag.Byte) + println(implicitly[TypeTag[Byte]]) + println(implicitly[TypeTag[Short]] eq TypeTag.Short) + println(implicitly[TypeTag[Short]]) + println(implicitly[TypeTag[Char]] eq TypeTag.Char) + println(implicitly[TypeTag[Char]]) + println(implicitly[TypeTag[Int]] eq TypeTag.Int) + println(implicitly[TypeTag[Int]]) + println(implicitly[TypeTag[Long]] eq TypeTag.Long) + println(implicitly[TypeTag[Long]]) + println(implicitly[TypeTag[Float]] eq TypeTag.Float) + println(implicitly[TypeTag[Float]]) + println(implicitly[TypeTag[Double]] eq TypeTag.Double) + println(implicitly[TypeTag[Double]]) + println(implicitly[TypeTag[Boolean]] eq TypeTag.Boolean) + println(implicitly[TypeTag[Boolean]]) + println(implicitly[TypeTag[Unit]] eq TypeTag.Unit) + println(implicitly[TypeTag[Unit]]) + println(implicitly[TypeTag[Any]] eq TypeTag.Any) + println(implicitly[TypeTag[Any]]) + println(implicitly[TypeTag[Object]] eq TypeTag.Object) + println(implicitly[TypeTag[Object]]) + println(implicitly[TypeTag[AnyVal]] eq TypeTag.AnyVal) + println(implicitly[TypeTag[AnyVal]]) + println(implicitly[TypeTag[AnyRef]] eq TypeTag.AnyRef) + println(implicitly[TypeTag[AnyRef]]) + println(implicitly[TypeTag[Null]] eq TypeTag.Null) + println(implicitly[TypeTag[Null]]) + println(implicitly[TypeTag[Nothing]] eq TypeTag.Nothing) + println(implicitly[TypeTag[Nothing]]) +} \ No newline at end of file diff --git a/test/pending/neg/reify_packed.check b/test/pending/neg/reify_packed.check new file mode 100644 index 0000000000..adba330d56 --- /dev/null +++ b/test/pending/neg/reify_packed.check @@ -0,0 +1,4 @@ +reify_packed.scala:6: error: implementation restriction: cannot reify block of type List[_$1] that involves a type declared inside the block being reified. consider casting the return value to a suitable type. + reify { + ^ +one error found diff --git a/test/pending/neg/reify_packed.scala b/test/pending/neg/reify_packed.scala new file mode 100644 index 0000000000..0240f2a4b5 --- /dev/null +++ b/test/pending/neg/reify_packed.scala @@ -0,0 +1,10 @@ +object Test extends App { + reify { + class C { override def toString() = "C" } + val ret = List((new C, new C)) + ret.asInstanceOf[List[_]] + }; + + val toolbox = mkToolBox() + println(toolbox.runExpr(code.tree)) +} diff --git a/test/pending/run/macro-expand-default.flags b/test/pending/run/macro-expand-default.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-default.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-default/Impls_1.scala b/test/pending/run/macro-expand-default/Impls_1.scala new file mode 100644 index 0000000000..fefe8fc4e2 --- /dev/null +++ b/test/pending/run/macro-expand-default/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} diff --git a/test/pending/run/macro-expand-default/Macros_Test_2.scala b/test/pending/run/macro-expand-default/Macros_Test_2.scala new file mode 100644 index 0000000000..92fe84d04a --- /dev/null +++ b/test/pending/run/macro-expand-default/Macros_Test_2.scala @@ -0,0 +1,8 @@ +object Test extends App { + def foo(x: Int = 2, y: Int = -40) = macro Impls.foo + foo(y = -40, x = 2) + foo(x = 2, y = -40) + foo(x = 100) + foo(y = 100) + foo() +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound.check b/test/pending/run/macro-expand-implicit-macro-has-context-bound.check new file mode 100644 index 0000000000..ac4213d6e9 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound.check @@ -0,0 +1 @@ +43 \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala new file mode 100644 index 0000000000..5c50576281 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[U](c: Ctx)(x: c.Expr[U])(evidence: c.Expr[Numeric[U]]) = { + import c.mirror._ + val plusOne = Apply(Select(evidence.tree, newTermName("plus")), List(x.tree, Literal(Constant(1)))) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(plusOne)) + Expr[Unit](body) + } +} diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala new file mode 100644 index 0000000000..7d16b773a6 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + def foo[U: Numeric](x: U) = macro Impls.foo[U] + foo(42) +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-named.flags b/test/pending/run/macro-expand-named.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-named.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-named/Impls_1.scala b/test/pending/run/macro-expand-named/Impls_1.scala new file mode 100644 index 0000000000..fefe8fc4e2 --- /dev/null +++ b/test/pending/run/macro-expand-named/Impls_1.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = { + import c.mirror._ + val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree)) + val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum)) + Expr[Unit](body) + } +} diff --git a/test/pending/run/macro-expand-named/Macros_Test_2.scala b/test/pending/run/macro-expand-named/Macros_Test_2.scala new file mode 100644 index 0000000000..abebcf8448 --- /dev/null +++ b/test/pending/run/macro-expand-named/Macros_Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + def foo(x: Int, y: Int) = macro Impls.foo + foo(y = -40, x = 2) + foo(x = 2, y = -40) +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-e1.check b/test/pending/run/macro-expand-tparams-prefix-e1.check new file mode 100644 index 0000000000..4fa05a7678 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1.check @@ -0,0 +1,3 @@ +TypeTag(List[Int]) +TypeTag(String) +TypeTag(Boolean) diff --git a/test/pending/run/macro-expand-tparams-prefix-e1.flags b/test/pending/run/macro-expand-tparams-prefix-e1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala b/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala b/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala new file mode 100644 index 0000000000..5c863804d0 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class D[T: TypeTag] { + class C[U: TypeTag] { + def foo[V] = macro Impls.foo[List[T], U, V] + foo[Boolean] + } + } + + val outer1 = new D[Int] + new outer1.C[String] +} \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-f1.check b/test/pending/run/macro-expand-tparams-prefix-f1.check new file mode 100644 index 0000000000..d15226143a --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1.check @@ -0,0 +1,3 @@ +TypeTag(List[T]) +TypeTag(U) +TypeTag(Boolean) diff --git a/test/pending/run/macro-expand-tparams-prefix-f1.flags b/test/pending/run/macro-expand-tparams-prefix-f1.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala b/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala new file mode 100644 index 0000000000..bc880fdf77 --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.makro.{Context => Ctx} + +object Impls { + def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = { + import c.mirror._ + Block(List( + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(()))) + } +} diff --git a/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala b/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala new file mode 100644 index 0000000000..bc8e7ac75c --- /dev/null +++ b/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + class D[T] { + class C[U] { + def foo[V] = macro Impls.foo[List[T], U, V] + foo[Boolean] + } + } + + val outer1 = new D[Int] + new outer1.C[String] +} \ No newline at end of file diff --git a/test/pending/run/macro-overload.check b/test/pending/run/macro-overload.check deleted file mode 100644 index 764f914e48..0000000000 --- a/test/pending/run/macro-overload.check +++ /dev/null @@ -1,4 +0,0 @@ -object-Int -object-String -class-Int -class-String \ No newline at end of file diff --git a/test/pending/run/macro-overload.flags b/test/pending/run/macro-overload.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/pending/run/macro-overload.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-overload/Macros_1.scala b/test/pending/run/macro-overload/Macros_1.scala deleted file mode 100644 index f24c69ea7b..0000000000 --- a/test/pending/run/macro-overload/Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - def macro bar(x: Int): Int = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("object-Int")))) - def macro bar(x: String): String = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("object-String")))) -} - -class Macros { - def macro bar(x: Int): Int = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("class-Int")))) - def macro bar(x: String): String = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("class-String")))) -} \ No newline at end of file diff --git a/test/pending/run/macro-overload/Test_2.scala b/test/pending/run/macro-overload/Test_2.scala deleted file mode 100644 index 75f6572e03..0000000000 --- a/test/pending/run/macro-overload/Test_2.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test extends App { - Macros.bar(2) - Macros.bar("2") - new Macros.bar(2) - new Macros.bar("2") -} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a.check b/test/pending/run/macro-quasiinvalidbody-a.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a.flags b/test/pending/run/macro-quasiinvalidbody-a.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala b/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala new file mode 100644 index 0000000000..0da37cd5c0 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.makro.{Context => Ctx} + +trait Impls { + def impl(c: Ctx)(x: c.Expr[Any]) = x +} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala b/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala new file mode 100644 index 0000000000..04a43080bd --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros extends Impls { + def foo(x: Any) = macro impl +} + +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b.check b/test/pending/run/macro-quasiinvalidbody-b.check new file mode 100644 index 0000000000..f70d7bba4a --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b.check @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b.flags b/test/pending/run/macro-quasiinvalidbody-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala b/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala new file mode 100644 index 0000000000..d84d04974f --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.makro.{Context => Ctx} + +trait ImplContainer { + object Impls { + def foo(c: Ctx)(x: c.Expr[Any]) = x + } +} \ No newline at end of file diff --git a/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala b/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala new file mode 100644 index 0000000000..82f88b62e4 --- /dev/null +++ b/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala @@ -0,0 +1,10 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros extends ImplContainer { + def foo(x: Any) = macro Impls.foo +} + +object Test extends App { + import Macros._ + println(foo(42)) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-array.flags b/test/pending/run/macro-reify-array.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-array.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-array/Macros_1.scala b/test/pending/run/macro-reify-array/Macros_1.scala new file mode 100644 index 0000000000..af42321484 --- /dev/null +++ b/test/pending/run/macro-reify-array/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: String) = macro Impls.foo[T] + + object Impls { + def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify { + Array(s.eval) + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-array/Test_2.scala b/test/pending/run/macro-reify-array/Test_2.scala new file mode 100644 index 0000000000..e40d5b40e0 --- /dev/null +++ b/test/pending/run/macro-reify-array/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val arr = Macros.foo("hello", "world") + println(arr.getClass) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-eval-vs-value.flags b/test/pending/run/macro-reify-eval-vs-value.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-eval-vs-value.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala b/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala new file mode 100644 index 0000000000..98dd93b0f8 --- /dev/null +++ b/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala @@ -0,0 +1,25 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def fooEval(s: String) = macro Impls.fooEval + def fooValue(s: String) = macro Impls.fooValue + + object Impls { + def fooEval(c: Ctx)(s: c.Expr[String]) = c.reify { + println("hello " + s.eval) + println("hello " + s.eval) + } + + def fooValue(c: Ctx)(s: c.Expr[String]) = c.reify { + { + println("hello " + s.value) + def sayHello = println(s.value) + sayHello + } + println("hello " + s.eval); + { + println("hello " + s.eval) + } + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-eval-vs-value/Test_2.scala b/test/pending/run/macro-reify-eval-vs-value/Test_2.scala new file mode 100644 index 0000000000..8e62e6e0e7 --- /dev/null +++ b/test/pending/run/macro-reify-eval-vs-value/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + Macros.fooEval({ println("in ur logz"); "world"}) + println("======================") + Macros.fooValue({ println("i can has cheezburger?"); "world"}) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check new file mode 100644 index 0000000000..7e4b000c52 --- /dev/null +++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check @@ -0,0 +1,2 @@ +TypeTag(List[Int]) +TypeTag(List[List[Int]]) diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala new file mode 100644 index 0000000000..4b264d83af --- /dev/null +++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTagHK[C[_]: GroundTypeTag, T: GroundTypeTag] = { + println(implicitly[GroundTypeTag[C[T]]]) + println(implicitly[GroundTypeTag[List[C[T]]]]) + } + fooTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagful-b.check b/test/pending/run/macro-reify-tagful-b.check new file mode 100644 index 0000000000..5bd9fe2156 --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b.check @@ -0,0 +1 @@ +List(List(hello world)) diff --git a/test/pending/run/macro-reify-tagful-b.flags b/test/pending/run/macro-reify-tagful-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagful-b/Macros_1.scala b/test/pending/run/macro-reify-tagful-b/Macros_1.scala new file mode 100644 index 0000000000..38b839330b --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b/Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[List[T]] + + object Impls { + def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify { + List(s.eval) + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagful-b/Test_2.scala b/test/pending/run/macro-reify-tagful-b/Test_2.scala new file mode 100644 index 0000000000..142234901f --- /dev/null +++ b/test/pending/run/macro-reify-tagful-b/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val list: List[List[String]] = Macros.foo(List("hello world")) + println(list) +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagless-b.check b/test/pending/run/macro-reify-tagless-b.check new file mode 100644 index 0000000000..49acd94ad6 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b.check @@ -0,0 +1,3 @@ +error: macro must not return an expr that contains free type variables (namely: T). have you forgot to use c.TypeTag annotations for type parameters external to a reifee? + +java.lang.Error: reflective compilation has failed diff --git a/test/pending/run/macro-reify-tagless-b.flags b/test/pending/run/macro-reify-tagless-b.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala b/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala new file mode 100644 index 0000000000..fac7ba5b98 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.makro.{Context => Ctx} + +object Macros { + def foo[T](s: T) = macro Impls.foo[List[T]] + + object Impls { + def foo[T](c: Ctx)(s: c.Expr[T]) = c.reify { + List(s.eval) + } + } +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-tagless-b/Test_2.scala b/test/pending/run/macro-reify-tagless-b/Test_2.scala new file mode 100644 index 0000000000..419ee42101 --- /dev/null +++ b/test/pending/run/macro-reify-tagless-b/Test_2.scala @@ -0,0 +1,11 @@ +object Test extends App { + //val list: List[String] = Macros.foo("hello world") + //println(list) + + import scala.reflect.mirror._ + val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass))) + val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world")))) + val list = ValDef(NoMods, newTermName("list"), tpt, rhs) + val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name)))) + println(tree.eval) +} diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-notags.check b/test/pending/run/macro-reify-typetag-hktypeparams-notags.check new file mode 100644 index 0000000000..db8a19d5f7 --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-notags.check @@ -0,0 +1,2 @@ +TypeTag(C[T]) +TypeTag(List[C[T]]) diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala b/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala new file mode 100644 index 0000000000..9a370189a7 --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooNoTypeTagHK[C[_], T] = { + println(implicitly[TypeTag[C[T]]]) + println(implicitly[TypeTag[List[C[T]]]]) + } + fooNoTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-tags.check b/test/pending/run/macro-reify-typetag-hktypeparams-tags.check new file mode 100644 index 0000000000..7e4b000c52 --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-tags.check @@ -0,0 +1,2 @@ +TypeTag(List[Int]) +TypeTag(List[List[Int]]) diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala new file mode 100644 index 0000000000..0358da9b0d --- /dev/null +++ b/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala @@ -0,0 +1,9 @@ +import scala.reflect.mirror._ + +object Test extends App { + def fooTypeTagHK[C[_]: TypeTag, T: TypeTag] = { + println(implicitly[TypeTag[C[T]]]) + println(implicitly[TypeTag[List[C[T]]]]) + } + fooTypeTagHK[List, Int] +} \ No newline at end of file diff --git a/test/pending/run/reify_addressbook.scala b/test/pending/run/reify_addressbook.scala index 54dd5545bd..7cb6dc08fd 100644 --- a/test/pending/run/reify_addressbook.scala +++ b/test/pending/run/reify_addressbook.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class Person(name: String, age: Int) /** An AddressBook takes a variable number of arguments @@ -62,9 +60,5 @@ object Test extends App { ; println(page) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_brainf_ck.scala b/test/pending/run/reify_brainf_ck.scala index 0034644b81..e4bcb257bd 100644 --- a/test/pending/run/reify_brainf_ck.scala +++ b/test/pending/run/reify_brainf_ck.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { import scala.annotation._ trait Func[T] { @@ -76,9 +74,5 @@ object Test extends App { <.#>+++++++++++[<+++++>-]<.>++++++++[<++ +>-]<.+++.------.--------.[-]>++++++++[<++++> -]<+.[-]++++++++++.""") - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_callccinterpreter.scala b/test/pending/run/reify_callccinterpreter.scala index 96ae9c5c17..0e23f75dcc 100644 --- a/test/pending/run/reify_callccinterpreter.scala +++ b/test/pending/run/reify_callccinterpreter.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { type Answer = Value; /** @@ -85,9 +83,5 @@ object Test extends App { println(test(term0)) println(test(term1)) println(test(term2)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_classfileann_b.check b/test/pending/run/reify_classfileann_b.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/pending/run/reify_classfileann_b.scala b/test/pending/run/reify_classfileann_b.scala deleted file mode 100644 index c31826377a..0000000000 --- a/test/pending/run/reify_classfileann_b.scala +++ /dev/null @@ -1,24 +0,0 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation - -object Test extends App { - // test 1: reify - val tree = scala.reflect.Code.lift{ - class C { - def x: Int = { - 2: @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) - } - } - }.tree - println(tree.toString) - - // test 2: import and compile - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(tree) -} \ No newline at end of file diff --git a/test/pending/run/reify_closure2b.scala b/test/pending/run/reify_closure2b.scala index b9c0063290..f9ed16d309 100644 --- a/test/pending/run/reify_closure2b.scala +++ b/test/pending/run/reify_closure2b.scala @@ -1,17 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo(y: Int): Int => Int = { class Foo(y: Int) { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + y }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure3b.scala b/test/pending/run/reify_closure3b.scala index 8f161dbff3..8ef0a60c66 100644 --- a/test/pending/run/reify_closure3b.scala +++ b/test/pending/run/reify_closure3b.scala @@ -1,19 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo(y: Int): Int => Int = { class Foo(y: Int) { def y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + y1 }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure4b.scala b/test/pending/run/reify_closure4b.scala index 238795d4dd..9eeb01b459 100644 --- a/test/pending/run/reify_closure4b.scala +++ b/test/pending/run/reify_closure4b.scala @@ -1,19 +1,14 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo(y: Int): Int => Int = { class Foo(y: Int) { val y1 = y - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + y1 }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure5b.scala b/test/pending/run/reify_closure5b.scala index bdb2583e8a..51f1ec318d 100644 --- a/test/pending/run/reify_closure5b.scala +++ b/test/pending/run/reify_closure5b.scala @@ -1,17 +1,12 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { def foo[T](ys: List[T]): Int => Int = { class Foo[T](ys: List[T]) { - val fun = reflect.Code.lift{(x: Int) => { + val fun = reflect.mirror.reify{(x: Int) => { x + ys.length }} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(ys).fun.tree) dyn.asInstanceOf[Int => Int] } diff --git a/test/pending/run/reify_closure8b.check b/test/pending/run/reify_closure8b.check deleted file mode 100644 index 9a037142aa..0000000000 --- a/test/pending/run/reify_closure8b.check +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/test/pending/run/reify_closure8b.scala b/test/pending/run/reify_closure8b.scala deleted file mode 100644 index 38031c217b..0000000000 --- a/test/pending/run/reify_closure8b.scala +++ /dev/null @@ -1,16 +0,0 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - class Foo(y: Int) { - def fun = lift{y} - } - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - val dyn = toolbox.runExpr(new Foo(10).fun.tree) - val foo = dyn.asInstanceOf[Int] - println(foo) -} diff --git a/test/pending/run/reify_closure9a.scala b/test/pending/run/reify_closure9a.scala index 185f4ffca1..1fc18cfa13 100644 --- a/test/pending/run/reify_closure9a.scala +++ b/test/pending/run/reify_closure9a.scala @@ -1,16 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - +import scala.reflect.mirror._ object Test extends App { def foo(y: Int) = { class Foo(val y: Int) { - def fun = lift{y} + def fun = reify{y} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int] } diff --git a/test/pending/run/reify_closure9b.scala b/test/pending/run/reify_closure9b.scala index ad279fac6d..32b05d00ee 100644 --- a/test/pending/run/reify_closure9b.scala +++ b/test/pending/run/reify_closure9b.scala @@ -1,16 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - +import scala.reflect.mirror._ object Test extends App { def foo(y: Int) = { class Foo(y: Int) { - def fun = lift{y} + def fun = reify{y} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(new Foo(y).fun.tree) dyn.asInstanceOf[Int] } diff --git a/test/pending/run/reify_closures11.scala b/test/pending/run/reify_closures11.scala index 2c4177b8f2..ceb224c6d6 100644 --- a/test/pending/run/reify_closures11.scala +++ b/test/pending/run/reify_closures11.scala @@ -1,16 +1,11 @@ -import scala.reflect.Code._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - +import scala.reflect.mirror._ object Test extends App { def fun() = { def z() = 2 - lift{z} + reify{z} } - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) + val toolbox = mkToolBox() val dyn = toolbox.runExpr(fun().tree) val foo = dyn.asInstanceOf[Int] println(foo) diff --git a/test/pending/run/reify_csv.scala b/test/pending/run/reify_csv.scala index a6a616fab0..966521575c 100644 --- a/test/pending/run/reify_csv.scala +++ b/test/pending/run/reify_csv.scala @@ -1,6 +1,4 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { val csv = """ @@ -18,7 +16,7 @@ object Test extends App { val fields = csv.head.split(";").map{_.trim()}.toList println(fields) - val code = scala.reflect.Code.lift({ + reify({ object Csv { case class record(`phase name`: String, id: String, description: String) @@ -33,9 +31,5 @@ object Test extends App { } Csv.record.parse(csv) foreach println - }) - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }).eval } diff --git a/test/pending/run/reify_gadts.scala b/test/pending/run/reify_gadts.scala index 9feb7a5726..652a7d99d8 100644 --- a/test/pending/run/reify_gadts.scala +++ b/test/pending/run/reify_gadts.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /* The syntax tree of a toy language */ abstract class Term[T] @@ -36,9 +34,5 @@ object Test extends App { } println( eval(If(IsZero(Lit(1)), Lit(41), Succ(Lit(41))))) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_lazyevaluation.scala b/test/pending/run/reify_lazyevaluation.scala index 0720a7c979..1a0c858914 100644 --- a/test/pending/run/reify_lazyevaluation.scala +++ b/test/pending/run/reify_lazyevaluation.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object lazyLib { /** Delay the evaluation of an expression until it is needed. */ @@ -56,9 +54,5 @@ object Test extends App { println("sl2 = " + sl2) println("sl2() = " + sl2()) println("sl2 = " + sl2) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_newimpl_07.scala b/test/pending/run/reify_newimpl_07.scala new file mode 100644 index 0000000000..13ca6bda8b --- /dev/null +++ b/test/pending/run/reify_newimpl_07.scala @@ -0,0 +1,13 @@ +import scala.reflect.mirror._ + +object Test extends App { + { + class C(val y: Int) { + val code = reify { + reify{y}.eval + } + } + + println(new C(2).code.eval) + } +} \ No newline at end of file diff --git a/test/pending/run/reify_newimpl_08.scala b/test/pending/run/reify_newimpl_08.scala new file mode 100644 index 0000000000..e2faa3c9af --- /dev/null +++ b/test/pending/run/reify_newimpl_08.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + val code = reify { + class C(val y: Int) { + val code = reify { + reify{y}.eval + } + } + + new C(2).code.eval + } + + println(code.eval) +} \ No newline at end of file diff --git a/test/pending/run/reify_newimpl_35.scala b/test/pending/run/reify_newimpl_35.scala new file mode 100644 index 0000000000..5e1d163e9e --- /dev/null +++ b/test/pending/run/reify_newimpl_35.scala @@ -0,0 +1,10 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xlog-free-types" + def code = """ +import scala.reflect.mirror._ +def foo[T: TypeTag] = reify{List[T]()} +println(foo) + """ +} diff --git a/test/pending/run/reify_newimpl_46.scala b/test/pending/run/reify_newimpl_46.scala new file mode 100644 index 0000000000..840d695e83 --- /dev/null +++ b/test/pending/run/reify_newimpl_46.scala @@ -0,0 +1,12 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T[_] >: Null] { + val code = reify{val x: T[String] = null; println("ima worx"); x} + println(freeTypes(code)) + val T = freeTypes(code)(0) + mkToolBox().runExpr(code, Map(T -> definitions.ListClass.asType)) + } + + new C[List] +} \ No newline at end of file diff --git a/test/pending/run/reify_newimpl_53.scala b/test/pending/run/reify_newimpl_53.scala new file mode 100644 index 0000000000..26645dea6a --- /dev/null +++ b/test/pending/run/reify_newimpl_53.scala @@ -0,0 +1,15 @@ +import scala.reflect.mirror._ + +object Test extends App { + class C[T >: Null] { + val code = reify{ + val tt = implicitly[TypeTag[T]] + println("mah typetag is: %s".format(tt)) + } + println(freeTypes(code)) + val T = freeTypes(code)(0) + mkToolBox().runExpr(code, Map(T -> definitions.StringClass.asType)) + } + + new C[String] +} \ No newline at end of file diff --git a/test/pending/run/reify_properties.scala b/test/pending/run/reify_properties.scala index 265c344b8e..5cacc262ac 100644 --- a/test/pending/run/reify_properties.scala +++ b/test/pending/run/reify_properties.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { /** A mutable property whose getter and setter may be customized. */ case class Property[T](init: T) { private var value: T = init @@ -54,9 +52,5 @@ object Test extends App { println("user1: " + user1) println("user2: " + user2) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/reify_simpleinterpreter.scala b/test/pending/run/reify_simpleinterpreter.scala index 4762afb3cc..2193edeea7 100644 --- a/test/pending/run/reify_simpleinterpreter.scala +++ b/test/pending/run/reify_simpleinterpreter.scala @@ -1,9 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class M[A](value: A) { def bind[B](k: A => M[B]): M[B] = k(value) def map[B](f: A => B): M[B] = bind(x => unitM(f(x))) @@ -73,9 +71,5 @@ object Test extends App { println(test(term0)) println(test(term1)) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5258a.check b/test/pending/run/t5258a.check new file mode 100644 index 0000000000..4e0b2da04c --- /dev/null +++ b/test/pending/run/t5258a.check @@ -0,0 +1 @@ +int \ No newline at end of file diff --git a/test/pending/run/t5258a.scala b/test/pending/run/t5258a.scala new file mode 100644 index 0000000000..755d135468 --- /dev/null +++ b/test/pending/run/t5258a.scala @@ -0,0 +1,5 @@ +object Test extends App { + reify { + println(classOf[Int]) + }.eval +} \ No newline at end of file diff --git a/test/pending/run/t5258b.scala b/test/pending/run/t5258b.scala index 3a603095b3..8ad1ff114e 100644 --- a/test/pending/run/t5258b.scala +++ b/test/pending/run/t5258b.scala @@ -1,14 +1,6 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { - val code = scala.reflect.Code.lift{ + reify { class C println(classOf[C]) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } \ No newline at end of file diff --git a/test/pending/run/t5258c.scala b/test/pending/run/t5258c.scala index b0d16ba0b1..1f76391162 100644 --- a/test/pending/run/t5258c.scala +++ b/test/pending/run/t5258c.scala @@ -1,14 +1,6 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object E extends Enumeration { val foo, bar = Value } println(E.foo) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } \ No newline at end of file diff --git a/test/pending/run/t5271_1.scala b/test/pending/run/t5271_1.scala index afbd8fe465..fae64350e3 100644 --- a/test/pending/run/t5271_1.scala +++ b/test/pending/run/t5271_1.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class C(foo: Int, bar: Int) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5271_2.scala b/test/pending/run/t5271_2.scala index d85d945973..d25e1fe804 100644 --- a/test/pending/run/t5271_2.scala +++ b/test/pending/run/t5271_2.scala @@ -1,15 +1,9 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5271_3.scala b/test/pending/run/t5271_3.scala index 5a624de903..65a03ae323 100644 --- a/test/pending/run/t5271_3.scala +++ b/test/pending/run/t5271_3.scala @@ -1,16 +1,10 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { object C { def qwe = 4 } case class C(foo: Int, bar: Int) val c = C(2, 2) println(c.foo * c.bar == C.qwe) - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } diff --git a/test/pending/run/t5418.scala b/test/pending/run/t5418.scala index fe813cf5ae..9b0a954e47 100644 --- a/test/pending/run/t5418.scala +++ b/test/pending/run/t5418.scala @@ -1,13 +1,7 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox +import scala.reflect.mirror._ object Test extends App { - val code = scala.reflect.Code.lift{ + reify { new Object().getClass - }; - - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(code.tree) + }.eval } \ No newline at end of file -- cgit v1.2.3 From 2c28680ca95c042c5b66de6c4b58c8367599cb44 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Apr 2012 18:08:46 -0700 Subject: Implementation of SIP 13 - implicit classes --- src/compiler/scala/reflect/internal/StdNames.scala | 4 + .../tools/nsc/typechecker/MethodSynthesis.scala | 89 ++++++++++++++-------- .../scala/tools/nsc/typechecker/Namers.scala | 16 ++-- .../scala/tools/nsc/typechecker/Typers.scala | 82 ++++++++++---------- .../scala/tools/nsc/typechecker/Unapplies.scala | 15 ++-- test/files/run/implicitclasses.scala | 10 +++ 6 files changed, 133 insertions(+), 83 deletions(-) create mode 100644 test/files/run/implicitclasses.scala (limited to 'test/files/run') diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index 0cd3616ba9..dbd9bb4f50 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -101,6 +101,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val ROOT: NameType = "" val PACKAGE: NameType = "package" val SPECIALIZED_SUFFIX: NameType = "$sp" + val WRAPPER_SUFFIX: NameType = "$wrapper" // value types (and AnyRef) are all used as terms as well // as (at least) arguments to the @specialize annotation. @@ -535,6 +536,9 @@ trait StdNames extends NameManglers { self: SymbolTable => def moduleVarName(name: TermName): TermName = newTermNameCached("" + name + MODULE_VAR_SUFFIX) + def implicitWrapperName(name: TypeName): TermName = + newTermNameCached("" + name + WRAPPER_SUFFIX) + val ROOTPKG: TermName = "_root_" /** Base strings from which synthetic names are derived. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 3d8c2ea564..e622ad7d4b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -155,28 +155,23 @@ trait MethodSynthesis { /** There are two key methods in here. * - * 1) enterGetterSetter is called from Namer with a ValDef which - * may need accessors. Some setup is performed. In general this - * creates symbols and enters them into the scope of the owner. + * 1) Enter methods such as enterGetterSetterare called + * from Namer with a tree which may generate further trees such as accessors or + * implicit wrappers. Some setup is performed. In general this creates symbols + * and enters them into the scope of the owner. * - * 2) finishGetterSetter is called from Typer when a Template is typed. + * 2) addDerivedTrees is called from Typer when a Template is typed. * It completes the job, returning a list of trees with their symbols - * set to those created in enterGetterSetter. Those trees then become + * set to those created in the enter methods. Those trees then become * part of the typed template. */ trait MethodSynth { self: Namer => import NamerErrorGen._ - - /** TODO - synthesize method. - */ - def enterImplicitClass(tree: ClassDef) { - /** e.g. - val ClassDef(mods, name, tparams, impl) = tree - val converter = ImplicitClassConverter(tree).createAndEnterSymbol() - ... - */ + + def enterImplicitWrapper(tree: ClassDef) { + ImplicitClassWrapper(tree).createAndEnterSymbol() } def enterGetterSetter(tree: ValDef) { @@ -203,7 +198,8 @@ trait MethodSynthesis { enterBeans(tree) } - def finishGetterSetter(typer: Typer, stat: Tree): List[Tree] = stat match { + + def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match { case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) && !vd.symbol.isLazy => // If we don't save the annotations, they seem to wander off. val annotations = stat.symbol.initialize.annotations @@ -234,35 +230,59 @@ trait MethodSynthesis { field ::: standardAccessors(vd) ::: beanAccessors(vd) } + /** This trait assembles what's needed for synthesizing derived methods. + * Important: Typically, instances of this trait are created TWICE for each derived + * symbol; once form Namers in an enter method, and once from Typers in addDerivedTrees. + * So it's important that creating an instance of Derived does not have a side effect, + * or if it has a side effect, control that it is done only once. + */ trait Derived { - /** The tree from which we are deriving a synthetic member. */ + + /** The tree from which we are deriving a synthetic member. Typically, that's + * given as an argument of the instance. */ def tree: Tree + + /** The name of the method */ def name: TermName + + /** The flags that are retained from the original symbol */ + def flagsMask: Long + + /** The flags that the derived symbol has in addition to those retained from + * the original symbol*/ def flagsExtra: Long - - /** The tree, symbol, and type completer for the synthetic member. */ + + /** type completer for the synthetic member. + */ def completer(sym: Symbol): Type + + /** The derived symbol. It is assumed that this symbol already exists and has been + * entered in the parent scope when derivedSym is called */ def derivedSym: Symbol + + /** The definition tree of the derived symbol. */ def derivedTree: Tree } - + trait DerivedFromMemberDef extends Derived { def tree: MemberDef - + def enclClass: Symbol + // Final methods to make the rest easier to reason about. final def mods = tree.mods final def basisSym = tree.symbol - final def enclClass = basisSym.enclClass final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra } - + trait DerivedFromClassDef extends DerivedFromMemberDef { def tree: ClassDef + final def enclClass = basisSym.owner.enclClass } trait DerivedFromValDef extends DerivedFromMemberDef { def tree: ValDef + final def enclClass = basisSym.enclClass /** Which meta-annotation is associated with this kind of entity. * Presently one of: field, getter, setter, beanGetter, beanSetter, param. @@ -334,15 +354,22 @@ trait MethodSynthesis { /** A synthetic method which performs the implicit conversion implied by * the declaration of an implicit class. Yet to be written. */ - case class ImplicitClassConverter(tree: ClassDef) extends DerivedFromClassDef { - def completer(sym: Symbol): Type = ??? - def derivedSym: Symbol = ??? - def derivedTree: DefDef = ??? - def flagsExtra: Long = ??? - def flagsMask: Long = ??? - def name: TermName = ??? - } - + case class ImplicitClassWrapper(tree: ClassDef) extends DerivedFromClassDef { + def completer(sym: Symbol): Type = ??? // not needed + def createAndEnterSymbol(): Symbol = enterSyntheticSym(derivedTree) + def derivedSym: Symbol = { + val result = enclClass.info decl name + assert(result != NoSymbol, "not found: "+name+" in "+enclClass+" "+enclClass.info.decls) + result + } + def derivedTree: DefDef = util.trace("derivedTree = ")( + factoryMeth(mods & flagsMask | flagsExtra, name, tree, symbolic = false) + ) + def flagsExtra: Long = METHOD | IMPLICIT + def flagsMask: Long = AccessFlags + def name: TermName = nme.implicitWrapperName(tree.name) + } + case class Getter(tree: ValDef) extends DerivedGetter { def name = tree.name def category = GetterTargetClass diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 2539091966..98f845f403 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -99,7 +99,7 @@ trait Namers extends MethodSynthesis { owner.unsafeTypeParams foreach (paramContext.scope enter _) newNamer(paramContext) } - + def enclosingNamerWithScope(scope: Scope) = { var cx = context while (cx != NoContext && cx.scope != scope) cx = cx.outer @@ -666,10 +666,12 @@ trait Namers extends MethodSynthesis { "If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead." ) } - + // Suggested location only. - if (mods.isImplicit) - enterImplicitClass(tree) + if (mods.isImplicit) { + println("enter implicit wrapper "+tree+", owner = "+owner) + enterImplicitWrapper(tree) + } } // this logic is needed in case typer was interrupted half @@ -1404,10 +1406,10 @@ trait Namers extends MethodSynthesis { if (sym.isImplicit) { if (sym.isConstructor) fail(ImplicitConstr) - if (!sym.isTerm) - fail(ImplicitNotTerm) + if (!(sym.isTerm || (sym.isClass && !sym.isTrait))) + fail(ImplicitNotTermOrClass) if (sym.owner.isPackageClass) - fail(ImplicitTopObject) + fail(ImplicitAtToplevel) } if (sym.isClass) { if (sym.isAnyOverride && !sym.hasFlag(TRAIT)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f558e0afc7..9b09145dc3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1653,7 +1653,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val body = if (isPastTyper || reporter.hasErrors) templ.body - else templ.body flatMap rewrappingWrapperTrees(namer.finishGetterSetter(Typer.this, _)) + else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _)) val body1 = typedStats(body, templ.symbol) @@ -2474,54 +2474,53 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { || (looker.hasAccessorFlag && !accessed.hasAccessorFlag && accessed.isPrivate) ) - def checkNoDoubleDefsAndAddSynthetics(stats: List[Tree]): List[Tree] = { + def checkNoDoubleDefs(stats: List[Tree]): Unit = { val scope = if (inBlock) context.scope else context.owner.info.decls - var newStats = new ListBuffer[Tree] - var needsCheck = true - var moreToAdd = true - while (moreToAdd) { - val initSize = scope.size - var e = scope.elems - while ((e ne null) && e.owner == scope) { - - // check no double def - if (needsCheck) { - var e1 = scope.lookupNextEntry(e) - while ((e1 ne null) && e1.owner == scope) { - if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) && - (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe) || e.sym.isMacro && e1.sym.isMacro)) - // default getters are defined twice when multiple overloads have defaults. an - // error for this is issued in RefChecks.checkDefaultsInOverloaded - if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefault && - !e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) { - log("Double definition detected:\n " + - ((e.sym.getClass, e.sym.info, e.sym.ownerChain)) + "\n " + - ((e1.sym.getClass, e1.sym.info, e1.sym.ownerChain))) - - DefDefinedTwiceError(e.sym, e1.sym) - scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779 - } - e1 = scope.lookupNextEntry(e1) + var e = scope.elems + while ((e ne null) && e.owner == scope) { + var e1 = scope.lookupNextEntry(e) + while ((e1 ne null) && e1.owner == scope) { + if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) && + (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe))) + // default getters are defined twice when multiple overloads have defaults. an + // error for this is issued in RefChecks.checkDefaultsInOverloaded + if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefaultFlag && + !e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) { + log("Double definition detected:\n " + + ((e.sym.getClass, e.sym.info, e.sym.ownerChain)) + "\n " + + ((e1.sym.getClass, e1.sym.info, e1.sym.ownerChain))) + + DefDefinedTwiceError(e.sym, e1.sym) + scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779 } - } - - // add synthetics - context.unit.synthetics get e.sym foreach { tree => - newStats += typedStat(tree) // might add even more synthetics to the scope - context.unit.synthetics -= e.sym + e1 = scope.lookupNextEntry(e1) } - e = e.next } - needsCheck = false - // the type completer of a synthetic might add more synthetics. example: if the - // factory method of a case class (i.e. the constructor) has a default. - moreToAdd = initSize != scope.size + } + + def addSynthetics(stats: List[Tree]): List[Tree] = { + val scope = if (inBlock) context.scope else context.owner.info.decls + var newStats = new ListBuffer[Tree] + var moreToAdd = true + while (moreToAdd) { + val initElems = scope.elems + for (sym <- scope) + for (tree <- context.unit.synthetics get sym) { + newStats += typedStat(tree) // might add even more synthetics to the scope + context.unit.synthetics -= sym + } + // the type completer of a synthetic might add more synthetics. example: if the + // factory method of a case class (i.e. the constructor) has a default. + moreToAdd = scope.elems ne initElems } if (newStats.isEmpty) stats else { // put default getters next to the method they belong to, // same for companion objects. fixes #2489 and #4036. + // [Martin] This is pretty ugly. I think we could avoid + // this code by associating defaults and companion objects + // with the original tree instead of the new symbol. def matches(stat: Tree, synt: Tree) = (stat, synt) match { case (DefDef(_, statName, _, _, _, _), DefDef(mods, syntName, _, _, _, _)) => mods.hasDefaultFlag && syntName.toString.startsWith(statName.toString) @@ -2551,7 +2550,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } context.updateBuffer(statsErrors) if (phase.erasedTypes) stats1 - else checkNoDoubleDefsAndAddSynthetics(stats1) + else { + checkNoDoubleDefs(stats1) + addSynthetics(stats1) + } } def typedArg(arg: Tree, mode: Int, newmode: Int, pt: Type): Tree = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 4f5b6868ae..1f79d8212d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -112,8 +112,8 @@ trait Unapplies extends ast.TreeDSL private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus - private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = { - val tycon = REF(cdef.symbol) + private def classType(cdef: ClassDef, tparams: List[TypeDef], symbolic: Boolean = true): Tree = { + val tycon = if (symbolic) REF(cdef.symbol) else Ident(cdef.name) if (tparams.isEmpty) tycon else AppliedTypeTree(tycon, tparams map toIdent) } @@ -166,15 +166,20 @@ trait Unapplies extends ast.TreeDSL /** The apply method corresponding to a case class */ - def caseModuleApplyMeth(cdef: ClassDef): DefDef = { + def factoryMeth(mods: Modifiers, name: TermName, cdef: ClassDef, symbolic: Boolean): DefDef = { val tparams = cdef.tparams map copyUntypedInvariant val cparamss = constrParamss(cdef) + def classtpe = classType(cdef, tparams, symbolic) atPos(cdef.pos.focus)( - DefDef(caseMods, nme.apply, tparams, cparamss, classType(cdef, tparams), - New(classType(cdef, tparams), mmap(cparamss)(gen.paramToArg))) + DefDef(mods, name, tparams, cparamss, classtpe, + New(classtpe, mmap(cparamss)(gen.paramToArg))) ) } + /** The apply method corresponding to a case class + */ + def caseModuleApplyMeth(cdef: ClassDef): DefDef = factoryMeth(caseMods, nme.apply, cdef, symbolic = true) + /** The unapply method corresponding to a case class */ def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = { diff --git a/test/files/run/implicitclasses.scala b/test/files/run/implicitclasses.scala new file mode 100644 index 0000000000..5c3ad588e6 --- /dev/null +++ b/test/files/run/implicitclasses.scala @@ -0,0 +1,10 @@ +object Test extends App { + + implicit class C(s: String) { + def nElems = s.length + } + + "abc".nElems + +} + -- cgit v1.2.3 From c297b97072cbeadad869338ff1b2e1c9955407a6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Apr 2012 18:10:11 -0700 Subject: Implementation of SIP 13 take 2. --- src/compiler/scala/reflect/internal/StdNames.scala | 4 -- .../tools/nsc/typechecker/MethodSynthesis.scala | 53 +++++++++++++--------- .../scala/tools/nsc/typechecker/Namers.scala | 2 +- test/files/run/implicitclasses.scala | 2 +- 4 files changed, 33 insertions(+), 28 deletions(-) (limited to 'test/files/run') diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index dbd9bb4f50..0cd3616ba9 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -101,7 +101,6 @@ trait StdNames extends NameManglers { self: SymbolTable => val ROOT: NameType = "" val PACKAGE: NameType = "package" val SPECIALIZED_SUFFIX: NameType = "$sp" - val WRAPPER_SUFFIX: NameType = "$wrapper" // value types (and AnyRef) are all used as terms as well // as (at least) arguments to the @specialize annotation. @@ -536,9 +535,6 @@ trait StdNames extends NameManglers { self: SymbolTable => def moduleVarName(name: TermName): TermName = newTermNameCached("" + name + MODULE_VAR_SUFFIX) - def implicitWrapperName(name: TypeName): TermName = - newTermNameCached("" + name + WRAPPER_SUFFIX) - val ROOTPKG: TermName = "_root_" /** Base strings from which synthetic names are derived. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index e622ad7d4b..097af5d456 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -65,7 +65,24 @@ trait MethodSynthesis { MethodType(params, symbols.last.typeConstructor) } - } + + /** The annotations amongst those found on the original symbol which + * should be propagated to this kind of accessor. + */ + def deriveAnnotations(initial: List[AnnotationInfo], category: Symbol, keepClean: Boolean): List[AnnotationInfo] = { + initial filter { ann => + // There are no meta-annotation arguments attached to `ann` + if (ann.metaAnnotations.isEmpty) { + // A meta-annotation matching `annotKind` exists on `ann`'s definition. + (ann.defaultTargets contains category) || + // `ann`'s definition has no meta-annotations, and `keepClean` is true. + (ann.defaultTargets.isEmpty && keepClean) + } + // There are meta-annotation arguments, and one of them matches `annotKind` + else ann.metaAnnotations exists (_ matches category) + } + } + } import synthesisUtil._ class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) { @@ -207,9 +224,18 @@ trait MethodSynthesis { map (acc => atPos(vd.pos.focus)(acc derive annotations)) filterNot (_ eq EmptyTree) ) + case cd @ ClassDef(mods, _, _, _) if mods.isImplicit => + val annotations = stat.symbol.initialize.annotations + // TODO: need to shuffle annotations between wrapper and class. + val wrapper = ImplicitClassWrapper(cd) + val meth = wrapper.derivedSym + val mdef = context.unit.synthetics(meth) + meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, false) + cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, true) + List(cd, mdef) case _ => List(stat) - } + } def standardAccessors(vd: ValDef): List[DerivedFromValDef] = ( if (vd.mods.isMutable && !vd.mods.isLazy) List(Getter(vd), Setter(vd)) @@ -306,22 +332,6 @@ trait MethodSynthesis { enterInScope(sym) sym setInfo completer(sym) } - /** The annotations amongst those found on the original symbol which - * should be propagated to this kind of accessor. - */ - private def deriveAnnotations(initial: List[AnnotationInfo]): List[AnnotationInfo] = { - initial filter { ann => - // There are no meta-annotation arguments attached to `ann` - if (ann.metaAnnotations.isEmpty) { - // A meta-annotation matching `annotKind` exists on `ann`'s definition. - (ann.defaultTargets contains category) || - // `ann`'s definition has no meta-annotations, and `keepClean` is true. - (ann.defaultTargets.isEmpty && keepClean) - } - // There are meta-annotation arguments, and one of them matches `annotKind` - else ann.metaAnnotations exists (_ matches category) - } - } private def logDerived(result: Tree): Tree = { debuglog("[+derived] " + ojoin(mods.flagString, basisSym.accurateKindString, basisSym.getterName.decode) + " (" + derivedSym + ")\n " + result) @@ -330,7 +340,7 @@ trait MethodSynthesis { } final def derive(initial: List[AnnotationInfo]): Tree = { validate() - derivedSym setAnnotations deriveAnnotations(initial) + derivedSym setAnnotations deriveAnnotations(initial, category, keepClean) logDerived(derivedTree) } } @@ -362,12 +372,11 @@ trait MethodSynthesis { assert(result != NoSymbol, "not found: "+name+" in "+enclClass+" "+enclClass.info.decls) result } - def derivedTree: DefDef = util.trace("derivedTree = ")( + def derivedTree: DefDef = factoryMeth(mods & flagsMask | flagsExtra, name, tree, symbolic = false) - ) def flagsExtra: Long = METHOD | IMPLICIT def flagsMask: Long = AccessFlags - def name: TermName = nme.implicitWrapperName(tree.name) + def name: TermName = tree.name.toTermName } case class Getter(tree: ValDef) extends DerivedGetter { diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 98f845f403..8a3bf71644 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -669,7 +669,7 @@ trait Namers extends MethodSynthesis { // Suggested location only. if (mods.isImplicit) { - println("enter implicit wrapper "+tree+", owner = "+owner) + log("enter implicit wrapper "+tree+", owner = "+owner) enterImplicitWrapper(tree) } } diff --git a/test/files/run/implicitclasses.scala b/test/files/run/implicitclasses.scala index 5c3ad588e6..886d4dede0 100644 --- a/test/files/run/implicitclasses.scala +++ b/test/files/run/implicitclasses.scala @@ -4,7 +4,7 @@ object Test extends App { def nElems = s.length } - "abc".nElems + assert("abc".nElems == 3) } -- cgit v1.2.3 From 46d0d73f66111d5d31b9fd593972970d7e9056bb Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 12 Apr 2012 11:32:31 +0200 Subject: GroundTypeTag => ConcreteTypeTag --- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- .../scala/reflect/internal/Definitions.scala | 22 +-- src/compiler/scala/reflect/internal/StdNames.scala | 4 +- .../scala/reflect/makro/runtime/Reifiers.scala | 8 +- src/compiler/scala/reflect/reify/Errors.scala | 4 +- src/compiler/scala/reflect/reify/Reifiers.scala | 6 +- .../scala/reflect/reify/codegen/Types.scala | 20 +-- src/compiler/scala/reflect/reify/package.scala | 6 +- .../scala/tools/nsc/typechecker/Implicits.scala | 4 +- .../scala/tools/nsc/typechecker/Macros.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- src/library/scala/Predef.scala | 26 ++-- src/library/scala/reflect/ClassTags.scala | 15 +- src/library/scala/reflect/TagMaterialization.scala | 42 +++--- .../scala/reflect/api/StandardDefinitions.scala | 4 +- src/library/scala/reflect/api/TypeTags.scala | 153 +++++++++++---------- src/library/scala/reflect/makro/Aliases.scala | 4 +- src/library/scala/reflect/makro/Reifiers.scala | 2 +- .../scala/reflect/makro/internal/typeTagImpl.scala | 18 +-- src/library/scala/reflect/package.scala | 16 +-- ...o-reify-groundtypetag-hktypeparams-notags.check | 8 +- .../Test.scala | 4 +- ...cro-reify-groundtypetag-typeparams-notags.check | 8 +- .../Test.scala | 4 +- .../neg/macro-reify-groundtypetag-usetypetag.check | 8 +- .../Test.scala | 4 +- test/files/neg/t3507.check | 2 +- test/files/neg/t3692.check | 4 +- test/files/run/groundtypetags_core.check | 30 ++-- test/files/run/groundtypetags_core.scala | 60 ++++---- test/files/run/macro-expand-nullary-generic.check | 10 +- test/files/run/macro-expand-tparams-explicit.check | 2 +- test/files/run/macro-expand-tparams-implicit.check | 4 +- test/files/run/macro-expand-tparams-prefix-a.check | 8 +- test/files/run/macro-expand-tparams-prefix-b.check | 4 +- .../files/run/macro-expand-tparams-prefix-c1.check | 6 +- .../files/run/macro-expand-tparams-prefix-c2.check | 6 +- .../files/run/macro-expand-tparams-prefix-d1.check | 2 +- .../macro-reify-groundtypetag-notypeparams.check | 4 +- .../Test.scala | 4 +- ...macro-reify-groundtypetag-typeparams-tags.check | 4 +- .../Test.scala | 6 +- .../run/macro-reify-typetag-notypeparams.check | 4 +- .../macro-reify-typetag-typeparams-notags.check | 4 +- .../run/macro-reify-typetag-typeparams-tags.check | 4 +- .../run/macro-reify-typetag-usegroundtypetag.check | 4 +- .../Test.scala | 2 +- .../files/run/macro-typecheck-macrosdisabled.check | 2 +- test/files/run/macro-undetparams-consfromsls.check | 6 +- test/files/run/macro-undetparams-implicitval.check | 2 +- test/files/run/macro-undetparams-macroitself.check | 4 +- test/files/run/primitive-sigs-2.check | 2 +- test/files/run/reify_newimpl_25.check | 2 +- test/files/run/reify_newimpl_26.check | 2 +- .../run/toolbox_typecheck_macrosdisabled.check | 2 +- test/files/run/typetags_core.check | 30 ++-- .../Test.scala | 6 +- 58 files changed, 320 insertions(+), 310 deletions(-) (limited to 'test/files/run') diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index d74b6353d9..3f94b85db9 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -d2808836aef2cbee506f9b0b0e346c749cac9ad8 ?scala-compiler.jar +82af2cfc6a81ae12f39c55c9cf684c5ec01971d3 ?scala-compiler.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 78e9f0b593..bf1f4829f2 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -752baeeb4a01c7c50ac0dc6e0f59f5598696a223 ?scala-library.jar +6a58ca2e4398623145c179f4ce215bfb86a065c4 ?scala-library.jar diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index b1c822ed97..12b083b4f6 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -477,16 +477,16 @@ trait Definitions extends reflect.api.StandardDefinitions { def ExprValue = getMember(ExprClass, nme.value) lazy val ExprModule = getMember(getRequiredClass("scala.reflect.api.Exprs"), nme.Expr) - lazy val ClassTagClass = getRequiredClass("scala.reflect.ClassTag") - def ClassTagErasure = getMember(ClassTagClass, nme.erasure) - def ClassTagTpe = getMember(ClassTagClass, nme.tpe) - lazy val ClassTagModule = getRequiredModule("scala.reflect.ClassTag") - lazy val TypeTagsClass = getRequiredClass("scala.reflect.api.TypeTags") - lazy val TypeTagClass = getMember(TypeTagsClass, tpnme.TypeTag) - def TypeTagTpe = getMember(TypeTagClass, nme.tpe) - lazy val TypeTagModule = getMember(TypeTagsClass, nme.TypeTag) - lazy val GroundTypeTagClass = getMember(TypeTagsClass, tpnme.GroundTypeTag) - lazy val GroundTypeTagModule = getMember(TypeTagsClass, nme.GroundTypeTag) + lazy val ClassTagClass = getRequiredClass("scala.reflect.ClassTag") + def ClassTagErasure = getMember(ClassTagClass, nme.erasure) + def ClassTagTpe = getMember(ClassTagClass, nme.tpe) + lazy val ClassTagModule = getRequiredModule("scala.reflect.ClassTag") + lazy val TypeTagsClass = getRequiredClass("scala.reflect.api.TypeTags") + lazy val TypeTagClass = getMember(TypeTagsClass, tpnme.TypeTag) + def TypeTagTpe = getMember(TypeTagClass, nme.tpe) + lazy val TypeTagModule = getMember(TypeTagsClass, nme.TypeTag) + lazy val ConcreteTypeTagClass = getMember(TypeTagsClass, tpnme.ConcreteTypeTag) + lazy val ConcreteTypeTagModule = getMember(TypeTagsClass, nme.ConcreteTypeTag) lazy val MacroContextClass = getRequiredClass("scala.reflect.makro.Context") def MacroContextPrefix = getMember(MacroContextClass, nme.prefix) @@ -497,7 +497,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal") def MacroInternal_materializeClassTag = getMember(MacroInternalPackage, nme.materializeClassTag) def MacroInternal_materializeTypeTag = getMember(MacroInternalPackage, nme.materializeTypeTag) - def MacroInternal_materializeGroundTypeTag = getMember(MacroInternalPackage, nme.materializeGroundTypeTag) + def MacroInternal_materializeConcreteTypeTag = getMember(MacroInternalPackage, nme.materializeConcreteTypeTag) lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature") lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature") diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index b72610f1e0..1666887133 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -126,7 +126,7 @@ trait StdNames extends NameManglers { self: SymbolTable => final val Symbol: NameType = "Symbol" final val ClassTag: NameType = "ClassTag" final val TypeTag : NameType = "TypeTag" - final val GroundTypeTag: NameType = "GroundTypeTag" + final val ConcreteTypeTag: NameType = "ConcreteTypeTag" // fictions we use as both types and terms final val ERROR: NameType = "" @@ -396,7 +396,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val map: NameType = "map" val materializeClassTag: NameType = "materializeClassTag" val materializeTypeTag: NameType = "materializeTypeTag" - val materializeGroundTypeTag: NameType = "materializeGroundTypeTag" + val materializeConcreteTypeTag: NameType = "materializeConcreteTypeTag" val mirror : NameType = "mirror" val moduleClass : NameType = "moduleClass" val name: NameType = "name" diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index 826fa7153f..2488b06d6c 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -21,16 +21,16 @@ trait Reifiers { def reifyTree(prefix: Tree, tree: Tree): Tree = reifyTopLevel(prefix, tree) - def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, noTypeVariablesInResult: Boolean = false): Tree = - reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, noTypeVariablesInResult) + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = + reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag) def unreifyTree(tree: Tree): Tree = Select(tree, definitions.ExprEval) - def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree = { + def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = { // [Eugene] the plumbing is not very pretty, but anyways factoring out the reifier seems like a necessary step to me import scala.reflect.reify._ - val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireGroundTypeTag) + val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireConcreteTypeTag) try { val result = reifier.reified diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 8bfe64621b..30c6c06c7b 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -33,8 +33,8 @@ trait Errors { throw new ReificationError(defaultErrorPosition, msg) } - def CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe: Type) = { - val msg = "cannot reify GroundTypeTag having unresolved type parameter %s".format(tpe) + def CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe: Type) = { + val msg = "cannot reify ConcreteTypeTag having unresolved type parameter %s".format(tpe) throw new ReificationError(defaultErrorPosition, msg) } diff --git a/src/compiler/scala/reflect/reify/Reifiers.scala b/src/compiler/scala/reflect/reify/Reifiers.scala index 6854710949..16c26734b2 100644 --- a/src/compiler/scala/reflect/reify/Reifiers.scala +++ b/src/compiler/scala/reflect/reify/Reifiers.scala @@ -21,7 +21,7 @@ abstract class Reifier extends Phases val prefix: Tree val reifee: Any val dontSpliceAtTopLevel: Boolean - val requireGroundTypeTag: Boolean + val requireConcreteTypeTag: Boolean /** * For ``reifee'' and other reification parameters, generate a tree of the form @@ -74,7 +74,7 @@ abstract class Reifier extends Phases val manifestedType = typer.packedType(tree, NoSymbol) val manifestedRtype = reifyType(manifestedType) - val tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType))) Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype)))) @@ -85,7 +85,7 @@ abstract class Reifier extends Phases val rtree = reify(tpe) val manifestedType = tpe - var tagModule = if (definitelyGround) GroundTypeTagModule else TypeTagModule + var tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType))) Apply(ctor, List(rtree)) diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 6f3a60a076..9bc113e8a4 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -67,8 +67,8 @@ trait Types { private var spliceTypesEnabled = !dontSpliceAtTopLevel /** Keeps track of whether this reification contains abstract type parameters */ - var maybeGround = true - var definitelyGround = true + var maybeConcrete = true + var definitelyConcrete = true def eligibleForSplicing(tpe: Type): Boolean = { // [Eugene] is this comprehensive? @@ -88,7 +88,7 @@ trait Types { if (reifyDebug) println("splicing " + tpe) if (spliceTypesEnabled) { - var tagClass = if (requireGroundTypeTag) GroundTypeTagClass else TypeTagClass + var tagClass = if (requireConcreteTypeTag) ConcreteTypeTagClass else TypeTagClass val tagTpe = singleType(prefix.tpe, prefix.tpe member tagClass.name) // [Eugene] this should be enough for an abstract type, right? @@ -99,16 +99,16 @@ trait Types { // to find out the whereabouts of the error run scalac with -Ydebug if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe)) val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireGroundTypeTag) match { + typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireConcreteTypeTag) match { case failure if failure.isEmpty => if (reifyDebug) println("implicit search was fruitless") - definitelyGround &= false - maybeGround &= false + definitelyConcrete &= false + maybeConcrete &= false EmptyTree case success => if (reifyDebug) println("implicit search has produced a result: " + success) - definitelyGround |= requireGroundTypeTag - maybeGround |= true + definitelyConcrete |= requireConcreteTypeTag + maybeConcrete |= true var splice = Select(success, nme.tpe) splice match { case InlinedTypeSplice(_, inlinedSymbolTable, tpe) => @@ -126,8 +126,8 @@ trait Types { if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false") } - if (requireGroundTypeTag) - CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe) + if (requireConcreteTypeTag) + CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe) } spliceTypesEnabled = true diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 7041fbf6ed..85cf92fe2f 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -3,12 +3,12 @@ package scala.reflect import scala.tools.nsc.Global package object reify { - def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Reifier { val mirror: global.type } = { + def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Reifier { val mirror: global.type } = { val typer1: typer.type = typer val prefix1: prefix.type = prefix val reifee1 = reifee val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel - val requireGroundTypeTag1 = requireGroundTypeTag + val requireConcreteTypeTag1 = requireConcreteTypeTag new { val mirror: global.type = global @@ -16,7 +16,7 @@ package object reify { val prefix = prefix1 val reifee = reifee1 val dontSpliceAtTopLevel = dontSpliceAtTopLevel1 - val requireGroundTypeTag = requireGroundTypeTag1 + val requireConcreteTypeTag = requireConcreteTypeTag1 } with Reifier } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 8aa257983a..3a789b83b6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1099,11 +1099,11 @@ trait Implicits { } // these should be lazy, otherwise we wouldn't be able to compile scala-library with starr - private val TagSymbols = Set(ClassTagClass, TypeTagClass, GroundTypeTagClass) + private val TagSymbols = Set(ClassTagClass, TypeTagClass, ConcreteTypeTagClass) private val TagMaterializers = Map( ClassTagClass -> MacroInternal_materializeClassTag, TypeTagClass -> MacroInternal_materializeTypeTag, - GroundTypeTagClass -> MacroInternal_materializeGroundTypeTag + ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag ) def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 3b270a92ad..9608108a0d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -877,7 +877,7 @@ trait Macros { self: Analyzer => tpe }) map (tpe => { val ttag = TypeTag(tpe) - if (ttag.isGround) ttag.toGround else ttag + if (ttag.isConcrete) ttag.toConcrete else ttag }) argss = argss.dropRight(1) :+ (evidences ++ argss.last) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1b508a96fe..5d9b8ae94a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5020,7 +5020,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { def resolveTypeTag(tree: Tree, pre: Type, tp: Type, full: Boolean): Tree = beforeTyper { inferImplicit( EmptyTree, - appliedType(singleType(pre, pre member (if (full) GroundTypeTagClass else TypeTagClass).name), List(tp)), + appliedType(singleType(pre, pre member (if (full) ConcreteTypeTagClass else TypeTagClass).name), List(tp)), /*reportAmbiguous =*/ true, /*isView =*/ false, /*context =*/ context, diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index d241d2ddc0..837ce96baa 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -103,12 +103,12 @@ object Predef extends LowPriorityImplicits { type ClassManifest[T] = scala.reflect.ClassManifest[T] @deprecated("OptManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") type OptManifest[T] = scala.reflect.OptManifest[T] - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") type Manifest[T] = scala.reflect.Manifest[T] @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") val ClassManifest = scala.reflect.ClassManifest // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") lazy val Manifest = scala.reflect.Manifest // needs to be lazy, because requires scala.reflect.mirror instance @deprecated("NoManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") lazy val NoManifest = scala.reflect.NoManifest // needs to be lazy, because requires scala.reflect.mirror instance @@ -118,20 +118,20 @@ object Predef extends LowPriorityImplicits { def optManifest[T](implicit m: OptManifest[T]) = m // Tag types and companions, and incantations for summoning - type ClassTag[T] = scala.reflect.ClassTag[T] - type TypeTag[T] = scala.reflect.TypeTag[T] - type GroundTypeTag[T] = scala.reflect.GroundTypeTag[T] - val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type + type ClassTag[T] = scala.reflect.ClassTag[T] + type TypeTag[T] = scala.reflect.TypeTag[T] + type ConcreteTypeTag[T] = scala.reflect.ConcreteTypeTag[T] + val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. - lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance - lazy val GroundTypeTag = scala.reflect.GroundTypeTag + lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance + lazy val ConcreteTypeTag = scala.reflect.ConcreteTypeTag // [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts - def classTag[T](implicit ctag: ClassTag[T]) = ctag - def tag[T](implicit ttag: TypeTag[T]) = ttag - def typeTag[T](implicit ttag: TypeTag[T]) = ttag - def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag - def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def classTag[T](implicit ctag: ClassTag[T]) = ctag + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag // Minor variations on identity functions def identity[A](x: A): A = x // @see `conforms` for the implicit version diff --git a/src/library/scala/reflect/ClassTags.scala b/src/library/scala/reflect/ClassTags.scala index 2833e7cc8e..cde6da5539 100644 --- a/src/library/scala/reflect/ClassTags.scala +++ b/src/library/scala/reflect/ClassTags.scala @@ -4,11 +4,20 @@ import java.lang.{ Class => jClass } import scala.reflect.{ mirror => rm } /** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. + * * This is useful in itself, but also enables very important use case. * Having this knowledge ClassTag can instantiate `Arrays` * in those cases where the element type is unknown at compile time. * Hence, ClassTag[T] conforms to the ArrayTag[T] trait. - */ + * + * If an implicit value of type u.ClassTag[T] is required, the compiler will make one up on demand. + * The implicitly created value contains in its erasure field the Java class that is the result of erasing type T. + * In that value, any occurrences of type parameters or abstract types U which come themselves with a ClassTag + * or a reflect.mirror.ConcreteTypeTag are represented by the type referenced by that tag. + * If the type T contains unresolved references to type parameters or abstract types, a static error results. + * + * A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion + * (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available). */ // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` // class tags, and all tags in general, should be as minimalistic as possible @annotation.implicitNotFound(msg = "No ClassTag available for ${T}") @@ -20,7 +29,7 @@ abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { /** A Scala reflection type representing T. * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure). - * For TypeTags and GroundTypeTags the representation is almost precise, because it uses reification + * For TypeTags and ConcreteTypeTags the representation is almost precise, because they use reification * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */ def tpe: rm.Type = rm.classToType(erasure) @@ -153,6 +162,6 @@ class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) - @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.GroundTypeTag` to capture and analyze type arguments", "2.10.0") + @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") def typeArguments: List[OptManifest[_]] = List() } \ No newline at end of file diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala index 991feb3bac..5918b6effc 100644 --- a/src/library/scala/reflect/TagMaterialization.scala +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -18,13 +18,13 @@ object TagMaterialization { def materializeTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.TypeTag[T]] = { import c.mirror._ val tpe = implicitly[c.TypeTag[T]].tpe - c.materializeTypeTag(tpe, requireGroundTypeTag = false) + c.materializeTypeTag(tpe, requireConcreteTypeTag = false) } - def materializeGroundTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.GroundTypeTag[T]] = { + def materializeConcreteTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.ConcreteTypeTag[T]] = { import c.mirror._ val tpe = implicitly[c.TypeTag[T]].tpe - c.materializeTypeTag(tpe, requireGroundTypeTag = true) + c.materializeTypeTag(tpe, requireConcreteTypeTag = true) } private implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils @@ -52,17 +52,17 @@ object TagMaterialization { NothingClass.asType -> newTermName("Nothing"), NullClass.asType -> newTermName("Null")) - val ReflectPackage = staticModule("scala.reflect.package") - val Reflect_mirror = selectTerm(ReflectPackage, "mirror") - val ClassTagClass = staticClass("scala.reflect.ClassTag") - val ClassTagErasure = selectTerm(ClassTagClass, "erasure") - val ClassTagModule = staticModule("scala.reflect.ClassTag") - val TypeTagsClass = staticClass("scala.reflect.api.TypeTags") - val TypeTagClass = selectType(TypeTagsClass, "TypeTag") - val TypeTagTpe = selectTerm(TypeTagClass, "tpe") - val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag") - val GroundTypeTagClass = selectType(TypeTagsClass, "GroundTypeTag") - val GroundTypeTagModule = selectTerm(TypeTagsClass, "GroundTypeTag") + val ReflectPackage = staticModule("scala.reflect.package") + val Reflect_mirror = selectTerm(ReflectPackage, "mirror") + val ClassTagClass = staticClass("scala.reflect.ClassTag") + val ClassTagErasure = selectTerm(ClassTagClass, "erasure") + val ClassTagModule = staticModule("scala.reflect.ClassTag") + val TypeTagsClass = staticClass("scala.reflect.api.TypeTags") + val TypeTagClass = selectType(TypeTagsClass, "TypeTag") + val TypeTagTpe = selectTerm(TypeTagClass, "tpe") + val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag") + val ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag") + val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag") def materializeClassTag(tpe: Type): Tree = { val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) @@ -70,8 +70,8 @@ object TagMaterialization { } def materializeClassTag(prefix: Tree, tpe: Type): Tree = { - val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) typetagInScope match { case success if !success.isEmpty && !typetagIsSynthetic(success) => val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) @@ -104,19 +104,19 @@ object TagMaterialization { } } - def materializeTypeTag(tpe: Type, requireGroundTypeTag: Boolean): Tree = { + def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = { def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix - materializeTypeTag(prefix, tpe, requireGroundTypeTag) + materializeTypeTag(prefix, tpe, requireConcreteTypeTag) } - def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { - val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule val result = tpe match { case coreTpe if coreTags contains coreTpe => Select(Select(prefix, tagModule.name), coreTags(coreTpe)) case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) catch { case ex: Throwable => // [Eugene] cannot pattern match on an abstract type, so had to do this diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index b4fedbe055..e457bb73e0 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -113,8 +113,8 @@ trait StandardDefinitions { self: Universe => def ClassTagModule: Symbol def TypeTagClass: Symbol def TypeTagModule: Symbol - def GroundTypeTagClass: Symbol - def GroundTypeTagModule: Symbol + def ConcreteTypeTagClass: Symbol + def ConcreteTypeTagModule: Symbol /** Given a type T, returns the type corresponding to the VM's * representation: ClassClass's type constructor applied to `arg`. diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala index a38c21a9d4..ed47620e13 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -14,14 +14,16 @@ import scala.reflect.{ mirror => rm } * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler. * * Type tags are organized in a hierarchy of two classes: - * [[scala.reflect.ClassTag]], [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#GroundTypeTag]]. - * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. + * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#ConcreteTypeTag]]. * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. - * A [[scala.reflect.api.Universe#GroundTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * A [[scala.reflect.api.Universe#ConcreteTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * + * It is also possible to capture Java classes by using a different kind of tag. + * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. * * TypeTags correspond loosely to Manifests. More precisely: * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag, - * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.GroundTypeTag, + * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.ConcreteTypeTag, * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]]. * * Implicit in the contract for all Tag classes is that the reified type tpe represents the type parameter T. @@ -59,38 +61,34 @@ trait TypeTags { self: Universe => def sym = tpe.typeSymbol - def isGround = !isNotGround - def isNotGround = tpe exists (_.typeSymbol.isAbstractType) - - def toGround: GroundTypeTag[T] = { - assert(isGround, tpe) - GroundTypeTag[T](tpe) - } + def isConcrete = !isNotConcrete + def isNotConcrete = tpe exists (_.typeSymbol.isAbstractType) + def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe) override def toString = { - var prefix = if (isGround) "GroundTypeTag" else "TypeTag" + var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" if (prefix != this.productPrefix) prefix = "*" + prefix prefix + "[" + tpe + "]" } } object TypeTag { - val Byte : TypeTag[scala.Byte] = GroundTypeTag.Byte - val Short : TypeTag[scala.Short] = GroundTypeTag.Short - val Char : TypeTag[scala.Char] = GroundTypeTag.Char - val Int : TypeTag[scala.Int] = GroundTypeTag.Int - val Long : TypeTag[scala.Long] = GroundTypeTag.Long - val Float : TypeTag[scala.Float] = GroundTypeTag.Float - val Double : TypeTag[scala.Double] = GroundTypeTag.Double - val Boolean : TypeTag[scala.Boolean] = GroundTypeTag.Boolean - val Unit : TypeTag[scala.Unit] = GroundTypeTag.Unit - val Any : TypeTag[scala.Any] = GroundTypeTag.Any - val Object : TypeTag[java.lang.Object] = GroundTypeTag.Object - val AnyVal : TypeTag[scala.AnyVal] = GroundTypeTag.AnyVal - val AnyRef : TypeTag[scala.AnyRef] = GroundTypeTag.AnyRef - val Nothing : TypeTag[scala.Nothing] = GroundTypeTag.Nothing - val Null : TypeTag[scala.Null] = GroundTypeTag.Null - val String : TypeTag[java.lang.String] = GroundTypeTag.String + val Byte : TypeTag[scala.Byte] = ConcreteTypeTag.Byte + val Short : TypeTag[scala.Short] = ConcreteTypeTag.Short + val Char : TypeTag[scala.Char] = ConcreteTypeTag.Char + val Int : TypeTag[scala.Int] = ConcreteTypeTag.Int + val Long : TypeTag[scala.Long] = ConcreteTypeTag.Long + val Float : TypeTag[scala.Float] = ConcreteTypeTag.Float + val Double : TypeTag[scala.Double] = ConcreteTypeTag.Double + val Boolean : TypeTag[scala.Boolean] = ConcreteTypeTag.Boolean + val Unit : TypeTag[scala.Unit] = ConcreteTypeTag.Unit + val Any : TypeTag[scala.Any] = ConcreteTypeTag.Any + val Object : TypeTag[java.lang.Object] = ConcreteTypeTag.Object + val AnyVal : TypeTag[scala.AnyVal] = ConcreteTypeTag.AnyVal + val AnyRef : TypeTag[scala.AnyRef] = ConcreteTypeTag.AnyRef + val Nothing : TypeTag[scala.Nothing] = ConcreteTypeTag.Nothing + val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null + val String : TypeTag[java.lang.String] = ConcreteTypeTag.String def apply[T](tpe: Type): TypeTag[T] = tpe match { @@ -115,64 +113,67 @@ trait TypeTags { self: Universe => } /** - * If an implicit value of type u.GroundTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. + * If an implicit value of type u.ConcreteTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. * However, if the resulting type still contains references to type parameters or abstract types, a static error results. * * @see [[scala.reflect.api.TypeTags]] */ - @annotation.implicitNotFound(msg = "No GroundTypeTag available for ${T}") - class GroundTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { - assert(isGround, tpe) - override def productPrefix = "GroundTypeTag" + @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") + class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + // it's unsafe to use assert here, because we might run into deadlocks with Predef + // also see comments in ClassTags.scala + //assert(isConcrete, tpe) + if (isNotConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) + override def productPrefix = "ConcreteTypeTag" } - object GroundTypeTag { - val Byte : GroundTypeTag[scala.Byte] = new GroundTypeTag[scala.Byte](ByteTpe) { private def readResolve() = GroundTypeTag.Byte } - val Short : GroundTypeTag[scala.Short] = new GroundTypeTag[scala.Short](ShortTpe) { private def readResolve() = GroundTypeTag.Short } - val Char : GroundTypeTag[scala.Char] = new GroundTypeTag[scala.Char](CharTpe) { private def readResolve() = GroundTypeTag.Char } - val Int : GroundTypeTag[scala.Int] = new GroundTypeTag[scala.Int](IntTpe) { private def readResolve() = GroundTypeTag.Int } - val Long : GroundTypeTag[scala.Long] = new GroundTypeTag[scala.Long](LongTpe) { private def readResolve() = GroundTypeTag.Long } - val Float : GroundTypeTag[scala.Float] = new GroundTypeTag[scala.Float](FloatTpe) { private def readResolve() = GroundTypeTag.Float } - val Double : GroundTypeTag[scala.Double] = new GroundTypeTag[scala.Double](DoubleTpe) { private def readResolve() = GroundTypeTag.Double } - val Boolean : GroundTypeTag[scala.Boolean] = new GroundTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = GroundTypeTag.Boolean } - val Unit : GroundTypeTag[scala.Unit] = new GroundTypeTag[scala.Unit](UnitTpe) { private def readResolve() = GroundTypeTag.Unit } - val Any : GroundTypeTag[scala.Any] = new GroundTypeTag[scala.Any](AnyTpe) { private def readResolve() = GroundTypeTag.Any } - val Object : GroundTypeTag[java.lang.Object] = new GroundTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = GroundTypeTag.Object } - val AnyVal : GroundTypeTag[scala.AnyVal] = new GroundTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = GroundTypeTag.AnyVal } - val AnyRef : GroundTypeTag[scala.AnyRef] = new GroundTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = GroundTypeTag.AnyRef } - val Nothing : GroundTypeTag[scala.Nothing] = new GroundTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = GroundTypeTag.Nothing } - val Null : GroundTypeTag[scala.Null] = new GroundTypeTag[scala.Null](NullTpe) { private def readResolve() = GroundTypeTag.Null } - val String : GroundTypeTag[java.lang.String] = new GroundTypeTag[java.lang.String](StringTpe) { private def readResolve() = GroundTypeTag.String } - - def apply[T](tpe: Type): GroundTypeTag[T] = + object ConcreteTypeTag { + val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe) { private def readResolve() = ConcreteTypeTag.Byte } + val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe) { private def readResolve() = ConcreteTypeTag.Short } + val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe) { private def readResolve() = ConcreteTypeTag.Char } + val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe) { private def readResolve() = ConcreteTypeTag.Int } + val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe) { private def readResolve() = ConcreteTypeTag.Long } + val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe) { private def readResolve() = ConcreteTypeTag.Float } + val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe) { private def readResolve() = ConcreteTypeTag.Double } + val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = ConcreteTypeTag.Boolean } + val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe) { private def readResolve() = ConcreteTypeTag.Unit } + val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe) { private def readResolve() = ConcreteTypeTag.Any } + val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = ConcreteTypeTag.Object } + val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = ConcreteTypeTag.AnyVal } + val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = ConcreteTypeTag.AnyRef } + val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = ConcreteTypeTag.Nothing } + val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe) { private def readResolve() = ConcreteTypeTag.Null } + val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe) { private def readResolve() = ConcreteTypeTag.String } + + def apply[T](tpe: Type): ConcreteTypeTag[T] = tpe match { - case ByteTpe => GroundTypeTag.Byte.asInstanceOf[GroundTypeTag[T]] - case ShortTpe => GroundTypeTag.Short.asInstanceOf[GroundTypeTag[T]] - case CharTpe => GroundTypeTag.Char.asInstanceOf[GroundTypeTag[T]] - case IntTpe => GroundTypeTag.Int.asInstanceOf[GroundTypeTag[T]] - case LongTpe => GroundTypeTag.Long.asInstanceOf[GroundTypeTag[T]] - case FloatTpe => GroundTypeTag.Float.asInstanceOf[GroundTypeTag[T]] - case DoubleTpe => GroundTypeTag.Double.asInstanceOf[GroundTypeTag[T]] - case BooleanTpe => GroundTypeTag.Boolean.asInstanceOf[GroundTypeTag[T]] - case UnitTpe => GroundTypeTag.Unit.asInstanceOf[GroundTypeTag[T]] - case AnyTpe => GroundTypeTag.Any.asInstanceOf[GroundTypeTag[T]] - case ObjectTpe => GroundTypeTag.Object.asInstanceOf[GroundTypeTag[T]] - case AnyValTpe => GroundTypeTag.AnyVal.asInstanceOf[GroundTypeTag[T]] - case AnyRefTpe => GroundTypeTag.AnyRef.asInstanceOf[GroundTypeTag[T]] - case NothingTpe => GroundTypeTag.Nothing.asInstanceOf[GroundTypeTag[T]] - case NullTpe => GroundTypeTag.Null.asInstanceOf[GroundTypeTag[T]] - case StringTpe => GroundTypeTag.String.asInstanceOf[GroundTypeTag[T]] - case _ => new GroundTypeTag[T](tpe) {} + case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]] + case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]] + case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]] + case IntTpe => ConcreteTypeTag.Int.asInstanceOf[ConcreteTypeTag[T]] + case LongTpe => ConcreteTypeTag.Long.asInstanceOf[ConcreteTypeTag[T]] + case FloatTpe => ConcreteTypeTag.Float.asInstanceOf[ConcreteTypeTag[T]] + case DoubleTpe => ConcreteTypeTag.Double.asInstanceOf[ConcreteTypeTag[T]] + case BooleanTpe => ConcreteTypeTag.Boolean.asInstanceOf[ConcreteTypeTag[T]] + case UnitTpe => ConcreteTypeTag.Unit.asInstanceOf[ConcreteTypeTag[T]] + case AnyTpe => ConcreteTypeTag.Any.asInstanceOf[ConcreteTypeTag[T]] + case ObjectTpe => ConcreteTypeTag.Object.asInstanceOf[ConcreteTypeTag[T]] + case AnyValTpe => ConcreteTypeTag.AnyVal.asInstanceOf[ConcreteTypeTag[T]] + case AnyRefTpe => ConcreteTypeTag.AnyRef.asInstanceOf[ConcreteTypeTag[T]] + case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]] + case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]] + case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]] + case _ => new ConcreteTypeTag[T](tpe) {} } - def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isGround) Some(ttag.tpe) else None + def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None - implicit def toClassTag[T](ttag: rm.GroundTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) - implicit def toDeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) + implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) // this class should not be used directly in client code - class DeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { + class DeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe @@ -180,7 +181,7 @@ trait TypeTags { self: Universe => def >:>(that: Manifest[_]): Boolean = that <:< ttag @deprecated("Use `tpe` to analyze the type arguments", "2.10.0") - override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.GroundTypeTag(targ)) + override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.ConcreteTypeTag(targ)) } } @@ -188,6 +189,6 @@ trait TypeTags { self: Universe => // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros // def tag[T](implicit ttag: TypeTag[T]) = ttag // def typeTag[T](implicit ttag: TypeTag[T]) = ttag -// def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag -// def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +// def concreteTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag +// def concreteTypeTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag } \ No newline at end of file diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala index e8b847600c..38b1065a40 100644 --- a/src/library/scala/reflect/makro/Aliases.scala +++ b/src/library/scala/reflect/makro/Aliases.scala @@ -21,6 +21,6 @@ trait Aliases { /** incantations for summoning tags */ def tag[T](implicit ttag: TypeTag[T]) = ttag def typeTag[T](implicit ttag: TypeTag[T]) = ttag - def groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag - def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag } diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala index 9bd25cf0f8..d690df6aee 100644 --- a/src/library/scala/reflect/makro/Reifiers.scala +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -46,7 +46,7 @@ trait Reifiers { * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). * For more information and examples see the documentation for ``Context.reifyTree'' and ``Universe.reify''. */ - def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: Boolean = false): Tree + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree /** Undoes reification of a tree. * diff --git a/src/library/scala/reflect/makro/internal/typeTagImpl.scala b/src/library/scala/reflect/makro/internal/typeTagImpl.scala index 6c49ef45de..de404ff39f 100644 --- a/src/library/scala/reflect/makro/internal/typeTagImpl.scala +++ b/src/library/scala/reflect/makro/internal/typeTagImpl.scala @@ -16,14 +16,14 @@ package object internal { /** This method is required by the compiler and should not be used in client code. */ def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] = - c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = false))(c.TypeTag.Nothing) + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = false))(c.TypeTag.Nothing) /** This method is required by the compiler and should not be used in client code. */ - def materializeGroundTypeTag[T](u: Universe): u.GroundTypeTag[T] = macro materializeGroundTypeTag_impl[T] + def materializeConcreteTypeTag[T](u: Universe): u.ConcreteTypeTag[T] = macro materializeConcreteTypeTag_impl[T] /** This method is required by the compiler and should not be used in client code. */ - def materializeGroundTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.GroundTypeTag[T]] = - c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = true))(c.TypeTag.Nothing) + def materializeConcreteTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.ConcreteTypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = true))(c.TypeTag.Nothing) /** This method is required by the compiler and should not be used in client code. */ private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils @@ -54,8 +54,8 @@ package internal { NullClass.asType -> newTermName("Null")) def materializeClassTag(prefix: Tree, tpe: Type): Tree = { - val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, TypeTagClass, Nil), List(tpe))) - def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) typetagInScope match { case success if !success.isEmpty && !typetagIsSynthetic(success) => val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) @@ -88,14 +88,14 @@ package internal { } } - def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { - val tagModule = if (requireGroundTypeTag) GroundTypeTagModule else TypeTagModule + def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule val result = tpe match { case coreTpe if coreTags contains coreTpe => Select(Select(prefix, tagModule.name), coreTags(coreTpe)) case _ => - try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireGroundTypeTag = requireGroundTypeTag) + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) catch { case ex: Throwable => // [Eugene] cannot pattern match on an abstract type, so had to do this diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 7a8267e689..1738642932 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -43,21 +43,21 @@ package object reflect { type ClassManifest[T] = ClassTag[T] @deprecated("OptManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") type OptManifest[T] = TypeTag[T] - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") - type Manifest[T] = GroundTypeTag[T] + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + type Manifest[T] = ConcreteTypeTag[T] @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") val ClassManifest = ClassTag - @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") - lazy val Manifest = GroundTypeTag + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + lazy val Manifest = ConcreteTypeTag @deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable // ClassTag class is defined separately from the mirror - type TypeTag[T] = scala.reflect.mirror.TypeTag[T] - type GroundTypeTag[T] = scala.reflect.mirror.GroundTypeTag[T] + type TypeTag[T] = scala.reflect.mirror.TypeTag[T] + type ConcreteTypeTag[T] = scala.reflect.mirror.ConcreteTypeTag[T] // ClassTag object is defined separately from the mirror - lazy val TypeTag = scala.reflect.mirror.TypeTag - lazy val GroundTypeTag = scala.reflect.mirror.GroundTypeTag + lazy val TypeTag = scala.reflect.mirror.TypeTag + lazy val ConcreteTypeTag = scala.reflect.mirror.ConcreteTypeTag } diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check index d9c390ba25..39e90f827e 100644 --- a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check @@ -1,7 +1,7 @@ -Test.scala:5: error: No GroundTypeTag available for C[T] - println(implicitly[GroundTypeTag[C[T]]]) +Test.scala:5: error: No ConcreteTypeTag available for C[T] + println(implicitly[ConcreteTypeTag[C[T]]]) ^ -Test.scala:6: error: No GroundTypeTag available for List[C[T]] - println(implicitly[GroundTypeTag[List[C[T]]]]) +Test.scala:6: error: No ConcreteTypeTag available for List[C[T]] + println(implicitly[ConcreteTypeTag[List[C[T]]]]) ^ two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala index d5ee61b91d..1302999da6 100644 --- a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala @@ -2,8 +2,8 @@ import scala.reflect.mirror._ object Test extends App { def fooNoTypeTagHK[C[_], T] = { - println(implicitly[GroundTypeTag[C[T]]]) - println(implicitly[GroundTypeTag[List[C[T]]]]) + println(implicitly[ConcreteTypeTag[C[T]]]) + println(implicitly[ConcreteTypeTag[List[C[T]]]]) } fooNoTypeTagHK[List, Int] } \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check index c678a2a313..164ca3543f 100644 --- a/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check @@ -1,7 +1,7 @@ -Test.scala:5: error: No GroundTypeTag available for T - println(implicitly[GroundTypeTag[T]]) +Test.scala:5: error: No ConcreteTypeTag available for T + println(implicitly[ConcreteTypeTag[T]]) ^ -Test.scala:6: error: No GroundTypeTag available for List[T] - println(implicitly[GroundTypeTag[List[T]]]) +Test.scala:6: error: No ConcreteTypeTag available for List[T] + println(implicitly[ConcreteTypeTag[List[T]]]) ^ two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala index 98bdf6d67f..d2276ce333 100644 --- a/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala @@ -2,8 +2,8 @@ import scala.reflect.mirror._ object Test extends App { def fooNoTypeTag[T] = { - println(implicitly[GroundTypeTag[T]]) - println(implicitly[GroundTypeTag[List[T]]]) + println(implicitly[ConcreteTypeTag[T]]) + println(implicitly[ConcreteTypeTag[List[T]]]) } fooNoTypeTag[Int] } \ No newline at end of file diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag.check b/test/files/neg/macro-reify-groundtypetag-usetypetag.check index c678a2a313..164ca3543f 100644 --- a/test/files/neg/macro-reify-groundtypetag-usetypetag.check +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag.check @@ -1,7 +1,7 @@ -Test.scala:5: error: No GroundTypeTag available for T - println(implicitly[GroundTypeTag[T]]) +Test.scala:5: error: No ConcreteTypeTag available for T + println(implicitly[ConcreteTypeTag[T]]) ^ -Test.scala:6: error: No GroundTypeTag available for List[T] - println(implicitly[GroundTypeTag[List[T]]]) +Test.scala:6: error: No ConcreteTypeTag available for List[T] + println(implicitly[ConcreteTypeTag[List[T]]]) ^ two errors found diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala index 507d03a390..d82cdc33e9 100644 --- a/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala @@ -2,8 +2,8 @@ import scala.reflect.mirror._ object Test extends App { def fooTypeTag[T: TypeTag] = { - println(implicitly[GroundTypeTag[T]]) - println(implicitly[GroundTypeTag[List[T]]]) + println(implicitly[ConcreteTypeTag[T]]) + println(implicitly[ConcreteTypeTag[List[T]]]) } fooTypeTag[Int] } \ No newline at end of file diff --git a/test/files/neg/t3507.check b/test/files/neg/t3507.check index 6b6df6ba76..71bf295039 100644 --- a/test/files/neg/t3507.check +++ b/test/files/neg/t3507.check @@ -1,4 +1,4 @@ -t3507.scala:13: error: No GroundTypeTag available for _1.b.c.type +t3507.scala:13: error: No ConcreteTypeTag available for _1.b.c.type mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier ^ one error found diff --git a/test/files/neg/t3692.check b/test/files/neg/t3692.check index ec67e76bb4..d83abd31e2 100644 --- a/test/files/neg/t3692.check +++ b/test/files/neg/t3692.check @@ -1,7 +1,7 @@ -t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { ^ -t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.GroundTypeTag` instead +t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = { ^ t3692.scala:15: error: unreachable code diff --git a/test/files/run/groundtypetags_core.check b/test/files/run/groundtypetags_core.check index d1b71f0926..62fcb481ae 100644 --- a/test/files/run/groundtypetags_core.check +++ b/test/files/run/groundtypetags_core.check @@ -1,30 +1,30 @@ true -GroundTypeTag[Byte] +ConcreteTypeTag[Byte] true -GroundTypeTag[Short] +ConcreteTypeTag[Short] true -GroundTypeTag[Char] +ConcreteTypeTag[Char] true -GroundTypeTag[Int] +ConcreteTypeTag[Int] true -GroundTypeTag[Long] +ConcreteTypeTag[Long] true -GroundTypeTag[Float] +ConcreteTypeTag[Float] true -GroundTypeTag[Double] +ConcreteTypeTag[Double] true -GroundTypeTag[Boolean] +ConcreteTypeTag[Boolean] true -GroundTypeTag[Unit] +ConcreteTypeTag[Unit] true -GroundTypeTag[Any] +ConcreteTypeTag[Any] true -GroundTypeTag[Object] +ConcreteTypeTag[Object] true -GroundTypeTag[AnyVal] +ConcreteTypeTag[AnyVal] true -GroundTypeTag[AnyRef] +ConcreteTypeTag[AnyRef] true -GroundTypeTag[Null] +ConcreteTypeTag[Null] true -GroundTypeTag[Nothing] +ConcreteTypeTag[Nothing] diff --git a/test/files/run/groundtypetags_core.scala b/test/files/run/groundtypetags_core.scala index d779e3fc7e..8b81a0c795 100644 --- a/test/files/run/groundtypetags_core.scala +++ b/test/files/run/groundtypetags_core.scala @@ -1,32 +1,32 @@ object Test extends App { - println(implicitly[GroundTypeTag[Byte]] eq GroundTypeTag.Byte) - println(implicitly[GroundTypeTag[Byte]]) - println(implicitly[GroundTypeTag[Short]] eq GroundTypeTag.Short) - println(implicitly[GroundTypeTag[Short]]) - println(implicitly[GroundTypeTag[Char]] eq GroundTypeTag.Char) - println(implicitly[GroundTypeTag[Char]]) - println(implicitly[GroundTypeTag[Int]] eq GroundTypeTag.Int) - println(implicitly[GroundTypeTag[Int]]) - println(implicitly[GroundTypeTag[Long]] eq GroundTypeTag.Long) - println(implicitly[GroundTypeTag[Long]]) - println(implicitly[GroundTypeTag[Float]] eq GroundTypeTag.Float) - println(implicitly[GroundTypeTag[Float]]) - println(implicitly[GroundTypeTag[Double]] eq GroundTypeTag.Double) - println(implicitly[GroundTypeTag[Double]]) - println(implicitly[GroundTypeTag[Boolean]] eq GroundTypeTag.Boolean) - println(implicitly[GroundTypeTag[Boolean]]) - println(implicitly[GroundTypeTag[Unit]] eq GroundTypeTag.Unit) - println(implicitly[GroundTypeTag[Unit]]) - println(implicitly[GroundTypeTag[Any]] eq GroundTypeTag.Any) - println(implicitly[GroundTypeTag[Any]]) - println(implicitly[GroundTypeTag[Object]] eq GroundTypeTag.Object) - println(implicitly[GroundTypeTag[Object]]) - println(implicitly[GroundTypeTag[AnyVal]] eq GroundTypeTag.AnyVal) - println(implicitly[GroundTypeTag[AnyVal]]) - println(implicitly[GroundTypeTag[AnyRef]] eq GroundTypeTag.AnyRef) - println(implicitly[GroundTypeTag[AnyRef]]) - println(implicitly[GroundTypeTag[Null]] eq GroundTypeTag.Null) - println(implicitly[GroundTypeTag[Null]]) - println(implicitly[GroundTypeTag[Nothing]] eq GroundTypeTag.Nothing) - println(implicitly[GroundTypeTag[Nothing]]) + println(implicitly[ConcreteTypeTag[Byte]] eq ConcreteTypeTag.Byte) + println(implicitly[ConcreteTypeTag[Byte]]) + println(implicitly[ConcreteTypeTag[Short]] eq ConcreteTypeTag.Short) + println(implicitly[ConcreteTypeTag[Short]]) + println(implicitly[ConcreteTypeTag[Char]] eq ConcreteTypeTag.Char) + println(implicitly[ConcreteTypeTag[Char]]) + println(implicitly[ConcreteTypeTag[Int]] eq ConcreteTypeTag.Int) + println(implicitly[ConcreteTypeTag[Int]]) + println(implicitly[ConcreteTypeTag[Long]] eq ConcreteTypeTag.Long) + println(implicitly[ConcreteTypeTag[Long]]) + println(implicitly[ConcreteTypeTag[Float]] eq ConcreteTypeTag.Float) + println(implicitly[ConcreteTypeTag[Float]]) + println(implicitly[ConcreteTypeTag[Double]] eq ConcreteTypeTag.Double) + println(implicitly[ConcreteTypeTag[Double]]) + println(implicitly[ConcreteTypeTag[Boolean]] eq ConcreteTypeTag.Boolean) + println(implicitly[ConcreteTypeTag[Boolean]]) + println(implicitly[ConcreteTypeTag[Unit]] eq ConcreteTypeTag.Unit) + println(implicitly[ConcreteTypeTag[Unit]]) + println(implicitly[ConcreteTypeTag[Any]] eq ConcreteTypeTag.Any) + println(implicitly[ConcreteTypeTag[Any]]) + println(implicitly[ConcreteTypeTag[Object]] eq ConcreteTypeTag.Object) + println(implicitly[ConcreteTypeTag[Object]]) + println(implicitly[ConcreteTypeTag[AnyVal]] eq ConcreteTypeTag.AnyVal) + println(implicitly[ConcreteTypeTag[AnyVal]]) + println(implicitly[ConcreteTypeTag[AnyRef]] eq ConcreteTypeTag.AnyRef) + println(implicitly[ConcreteTypeTag[AnyRef]]) + println(implicitly[ConcreteTypeTag[Null]] eq ConcreteTypeTag.Null) + println(implicitly[ConcreteTypeTag[Null]]) + println(implicitly[ConcreteTypeTag[Nothing]] eq ConcreteTypeTag.Nothing) + println(implicitly[ConcreteTypeTag[Nothing]]) } \ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic.check b/test/files/run/macro-expand-nullary-generic.check index 34a453cd3a..6dfe04af12 100644 --- a/test/files/run/macro-expand-nullary-generic.check +++ b/test/files/run/macro-expand-nullary-generic.check @@ -1,6 +1,6 @@ -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] -it works GroundTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] +it works ConcreteTypeTag[Int] kkthxbai diff --git a/test/files/run/macro-expand-tparams-explicit.check b/test/files/run/macro-expand-tparams-explicit.check index 54da026aa8..5670e27c4e 100644 --- a/test/files/run/macro-expand-tparams-explicit.check +++ b/test/files/run/macro-expand-tparams-explicit.check @@ -1 +1 @@ -GroundTypeTag[Int] +ConcreteTypeTag[Int] diff --git a/test/files/run/macro-expand-tparams-implicit.check b/test/files/run/macro-expand-tparams-implicit.check index 60c021a35b..e57fc1217b 100644 --- a/test/files/run/macro-expand-tparams-implicit.check +++ b/test/files/run/macro-expand-tparams-implicit.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[String] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check index 1447c2478f..922be1a6dd 100644 --- a/test/files/run/macro-expand-tparams-prefix-a.check +++ b/test/files/run/macro-expand-tparams-prefix-a.check @@ -1,4 +1,4 @@ -GroundTypeTag[Int] -GroundTypeTag[Int] -GroundTypeTag[String] -GroundTypeTag[Boolean] +ConcreteTypeTag[Int] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check index c7ec594b92..a336bb51ec 100644 --- a/test/files/run/macro-expand-tparams-prefix-b.check +++ b/test/files/run/macro-expand-tparams-prefix-b.check @@ -1,2 +1,2 @@ -GroundTypeTag[Boolean] GroundTypeTag[Int] -GroundTypeTag[Boolean] GroundTypeTag[String] +ConcreteTypeTag[Boolean] ConcreteTypeTag[Int] +ConcreteTypeTag[Boolean] ConcreteTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check index fac58e9516..87f295aa49 100644 --- a/test/files/run/macro-expand-tparams-prefix-c1.check +++ b/test/files/run/macro-expand-tparams-prefix-c1.check @@ -1,3 +1,3 @@ -GroundTypeTag[Int] -GroundTypeTag[String] -GroundTypeTag[Boolean] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check index fac58e9516..87f295aa49 100644 --- a/test/files/run/macro-expand-tparams-prefix-c2.check +++ b/test/files/run/macro-expand-tparams-prefix-c2.check @@ -1,3 +1,3 @@ -GroundTypeTag[Int] -GroundTypeTag[String] -GroundTypeTag[Boolean] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-d1.check b/test/files/run/macro-expand-tparams-prefix-d1.check index f78ddea4f3..ca7a220475 100644 --- a/test/files/run/macro-expand-tparams-prefix-d1.check +++ b/test/files/run/macro-expand-tparams-prefix-d1.check @@ -1,3 +1,3 @@ TypeTag[T] TypeTag[U] -GroundTypeTag[Boolean] +ConcreteTypeTag[Boolean] diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams.check b/test/files/run/macro-reify-groundtypetag-notypeparams.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-groundtypetag-notypeparams.check +++ b/test/files/run/macro-reify-groundtypetag-notypeparams.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala index 3aa40251ec..d2f8fab5ec 100644 --- a/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala +++ b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ object Test extends App { - println(implicitly[GroundTypeTag[Int]]) - println(implicitly[GroundTypeTag[List[Int]]]) + println(implicitly[ConcreteTypeTag[Int]]) + println(implicitly[ConcreteTypeTag[List[Int]]]) } \ No newline at end of file diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags.check b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-groundtypetag-typeparams-tags.check +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala index 21735c10d5..6d7eab5f9a 100644 --- a/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala @@ -1,9 +1,9 @@ import scala.reflect.mirror._ object Test extends App { - def fooTypeTag[T: GroundTypeTag] = { - println(implicitly[GroundTypeTag[T]]) - println(implicitly[GroundTypeTag[List[T]]]) + def fooTypeTag[T: ConcreteTypeTag] = { + println(implicitly[ConcreteTypeTag[T]]) + println(implicitly[ConcreteTypeTag[List[T]]]) } fooTypeTag[Int] } \ No newline at end of file diff --git a/test/files/run/macro-reify-typetag-notypeparams.check b/test/files/run/macro-reify-typetag-notypeparams.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-typetag-notypeparams.check +++ b/test/files/run/macro-reify-typetag-notypeparams.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-typeparams-notags.check b/test/files/run/macro-reify-typetag-typeparams-notags.check index 3da30c71ba..af4877e205 100644 --- a/test/files/run/macro-reify-typetag-typeparams-notags.check +++ b/test/files/run/macro-reify-typetag-typeparams-notags.check @@ -1,2 +1,2 @@ -GroundTypeTag[T] -GroundTypeTag[List[T]] +ConcreteTypeTag[T] +ConcreteTypeTag[List[T]] diff --git a/test/files/run/macro-reify-typetag-typeparams-tags.check b/test/files/run/macro-reify-typetag-typeparams-tags.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-typetag-typeparams-tags.check +++ b/test/files/run/macro-reify-typetag-typeparams-tags.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag.check b/test/files/run/macro-reify-typetag-usegroundtypetag.check index 24612cd4b7..d75b3c72b2 100644 --- a/test/files/run/macro-reify-typetag-usegroundtypetag.check +++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[List[Int]] +ConcreteTypeTag[Int] +ConcreteTypeTag[List[Int]] diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala index c9b210f35a..de235f51cc 100644 --- a/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala +++ b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala @@ -1,7 +1,7 @@ import scala.reflect.mirror._ object Test extends App { - def fooTypeTag[T: GroundTypeTag] = { + def fooTypeTag[T: ConcreteTypeTag] = { println(implicitly[TypeTag[T]]) println(implicitly[TypeTag[List[T]]]) } diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check index 9760c117a7..b432a539fc 100644 --- a/test/files/run/macro-typecheck-macrosdisabled.check +++ b/test/files/run/macro-typecheck-macrosdisabled.check @@ -1,5 +1,5 @@ { val $mr: reflect.mirror.type = scala.reflect.`package`.mirror; - $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) } mr.reify[Int](2) diff --git a/test/files/run/macro-undetparams-consfromsls.check b/test/files/run/macro-undetparams-consfromsls.check index 6bf9bcca5a..49e9140d5a 100644 --- a/test/files/run/macro-undetparams-consfromsls.check +++ b/test/files/run/macro-undetparams-consfromsls.check @@ -1,5 +1,5 @@ -A = GroundTypeTag[Int] -B = GroundTypeTag[Nothing] +A = ConcreteTypeTag[Int] +B = ConcreteTypeTag[Nothing] List(1) -A = GroundTypeTag[Any] +A = ConcreteTypeTag[Any] List(abc, 1) diff --git a/test/files/run/macro-undetparams-implicitval.check b/test/files/run/macro-undetparams-implicitval.check index 352a2e6480..6c2b601aa5 100644 --- a/test/files/run/macro-undetparams-implicitval.check +++ b/test/files/run/macro-undetparams-implicitval.check @@ -1 +1 @@ -GroundTypeTag[Nothing] +ConcreteTypeTag[Nothing] diff --git a/test/files/run/macro-undetparams-macroitself.check b/test/files/run/macro-undetparams-macroitself.check index 60c021a35b..e57fc1217b 100644 --- a/test/files/run/macro-undetparams-macroitself.check +++ b/test/files/run/macro-undetparams-macroitself.check @@ -1,2 +1,2 @@ -GroundTypeTag[Int] -GroundTypeTag[String] +ConcreteTypeTag[Int] +ConcreteTypeTag[String] diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check index 761aa1ca72..1b6e24ed20 100644 --- a/test/files/run/primitive-sigs-2.check +++ b/test/files/run/primitive-sigs-2.check @@ -1,7 +1,7 @@ T List(A, char, class java.lang.Object) a -public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.api.TypeTags.scala.reflect.api.TypeTags$GroundTypeTag) +public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.api.TypeTags.scala.reflect.api.TypeTags$ConcreteTypeTag) public float[] Arr.arr3(float[][]) public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) public scala.collection.immutable.List Arr.arr1(int[]) diff --git a/test/files/run/reify_newimpl_25.check b/test/files/run/reify_newimpl_25.check index 31ece627e1..37ff83c9ee 100644 --- a/test/files/run/reify_newimpl_25.check +++ b/test/files/run/reify_newimpl_25.check @@ -14,7 +14,7 @@ scala> { :13: free term: Ident(newTermName("x")) defined by res0 in :12:21 val tt = implicitly[TypeTag[x.type]] ^ -GroundTypeTag[x.type] +ConcreteTypeTag[x.type] scala> diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check index 68b0ee8c99..bfbf1d653d 100644 --- a/test/files/run/reify_newimpl_26.check +++ b/test/files/run/reify_newimpl_26.check @@ -16,7 +16,7 @@ scala> def foo[T]{ foo: [T]=> Unit scala> foo[Int] -GroundTypeTag[List[T]] +ConcreteTypeTag[List[T]] scala> diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check index fe2323ea06..cf2420bc17 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled.check +++ b/test/files/run/toolbox_typecheck_macrosdisabled.check @@ -1,5 +1,5 @@ { val $mr: mr.type = mr; - $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.GroundTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) + $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)))) } mr.reify[Int](2) diff --git a/test/files/run/typetags_core.check b/test/files/run/typetags_core.check index d1b71f0926..62fcb481ae 100644 --- a/test/files/run/typetags_core.check +++ b/test/files/run/typetags_core.check @@ -1,30 +1,30 @@ true -GroundTypeTag[Byte] +ConcreteTypeTag[Byte] true -GroundTypeTag[Short] +ConcreteTypeTag[Short] true -GroundTypeTag[Char] +ConcreteTypeTag[Char] true -GroundTypeTag[Int] +ConcreteTypeTag[Int] true -GroundTypeTag[Long] +ConcreteTypeTag[Long] true -GroundTypeTag[Float] +ConcreteTypeTag[Float] true -GroundTypeTag[Double] +ConcreteTypeTag[Double] true -GroundTypeTag[Boolean] +ConcreteTypeTag[Boolean] true -GroundTypeTag[Unit] +ConcreteTypeTag[Unit] true -GroundTypeTag[Any] +ConcreteTypeTag[Any] true -GroundTypeTag[Object] +ConcreteTypeTag[Object] true -GroundTypeTag[AnyVal] +ConcreteTypeTag[AnyVal] true -GroundTypeTag[AnyRef] +ConcreteTypeTag[AnyRef] true -GroundTypeTag[Null] +ConcreteTypeTag[Null] true -GroundTypeTag[Nothing] +ConcreteTypeTag[Nothing] diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala index 4b264d83af..ef70a66f1a 100644 --- a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala +++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala @@ -1,9 +1,9 @@ import scala.reflect.mirror._ object Test extends App { - def fooTypeTagHK[C[_]: GroundTypeTag, T: GroundTypeTag] = { - println(implicitly[GroundTypeTag[C[T]]]) - println(implicitly[GroundTypeTag[List[C[T]]]]) + def fooTypeTagHK[C[_]: ConcreteTypeTag, T: ConcreteTypeTag] = { + println(implicitly[ConcreteTypeTag[C[T]]]) + println(implicitly[ConcreteTypeTag[List[C[T]]]]) } fooTypeTagHK[List, Int] } \ No newline at end of file -- cgit v1.2.3