From 385f347946c91b619f51098d89b00a79c4155bc9 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 4 Jul 2019 17:27:09 +0200 Subject: [PATCH 1/2] Fix inner object macro implementations The interpreter did not load inner objects with the correct class name. --- .../dotty/tools/dotc/transform/Splicer.scala | 17 +++++++++----- tests/pos-macros/i6803b/Macro_1.scala | 17 ++++++++++++++ tests/pos-macros/i6803b/Test_2.scala | 11 ++++++++++ tests/run-macros/inline-case-objects.check | 2 +- .../inline-macro-inner-object.check | 3 +++ .../inline-macro-inner-object/Macro_1.scala | 22 +++++++++++++++++++ .../inline-macro-inner-object/Test_2.scala | 9 ++++++++ 7 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 tests/pos-macros/i6803b/Macro_1.scala create mode 100644 tests/pos-macros/i6803b/Test_2.scala create mode 100644 tests/run-macros/inline-macro-inner-object.check create mode 100644 tests/run-macros/inline-macro-inner-object/Macro_1.scala create mode 100644 tests/run-macros/inline-macro-inner-object/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index bc371b4ace70..fe385c8ca566 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -141,7 +141,7 @@ object Splicer { loadModule(fn.moduleClass) protected def interpretNew(fn: Symbol, args: => List[Result])(implicit env: Env): Object = { - val clazz = loadClass(fn.owner.fullName) + val clazz = loadClass(fn.owner.fullName.toString) val constr = clazz.getConstructor(paramsSig(fn): _*) constr.newInstance(args: _*).asInstanceOf[Object] } @@ -152,11 +152,18 @@ object Splicer { private def loadModule(sym: Symbol): Object = { if (sym.owner.is(Package)) { // is top level object - val moduleClass = loadClass(sym.fullName) + val moduleClass = loadClass(sym.fullName.toString) moduleClass.getField(str.MODULE_INSTANCE_FIELD).get(null) } else { // nested object in an object - val clazz = loadClass(sym.fullNameSeparated(FlatName)) + val className = { + val pack = sym.topLevelClass.owner + val prefix = + if (pack == defn.RootPackage || pack == defn.EmptyPackageClass) "" + else pack.showFullName + "." + prefix + sym.fullNameSeparated(FlatName) + } + val clazz = loadClass(className) clazz.getConstructor().newInstance().asInstanceOf[Object] } } @@ -166,8 +173,8 @@ object Splicer { lineClassloader.loadClass(moduleClass.name.firstPart.toString) } - private def loadClass(name: Name): Class[_] = { - try classLoader.loadClass(name.toString) + private def loadClass(name: String): Class[_] = { + try classLoader.loadClass(name) catch { case _: ClassNotFoundException => val msg = s"Could not find class $name in classpath$extraMsg" diff --git a/tests/pos-macros/i6803b/Macro_1.scala b/tests/pos-macros/i6803b/Macro_1.scala new file mode 100644 index 000000000000..bf0170d16bbe --- /dev/null +++ b/tests/pos-macros/i6803b/Macro_1.scala @@ -0,0 +1,17 @@ +package blah + +import scala.language.implicitConversions +import scala.quoted._ +import scala.quoted.autolift._ + +object AsObject { + final class LineNo(val lineNo: Int) + object LineNo { + def unsafe(i: Int): LineNo = new LineNo(i) + inline delegate x for LineNo = ${impl} + private def impl given (qctx: QuoteContext): Expr[LineNo] = { + import qctx.tasty._ + '{unsafe(${rootPosition.startLine})} + } + } +} diff --git a/tests/pos-macros/i6803b/Test_2.scala b/tests/pos-macros/i6803b/Test_2.scala new file mode 100644 index 000000000000..7f2fe666928a --- /dev/null +++ b/tests/pos-macros/i6803b/Test_2.scala @@ -0,0 +1,11 @@ +import blah._ + +object Test { + def main(args: Array[String]): Unit = { + + def testO(): Unit = { + import AsObject.LineNo + the[LineNo] given LineNo.x + } + } +} diff --git a/tests/run-macros/inline-case-objects.check b/tests/run-macros/inline-case-objects.check index 77e4a94bb071..e264f798023d 100644 --- a/tests/run-macros/inline-case-objects.check +++ b/tests/run-macros/inline-case-objects.check @@ -3,4 +3,4 @@ scala.None$ Bar$ Bar.Baz$ foo.Bar$ -Bar.Baz$ +foo.Bar.Baz$ diff --git a/tests/run-macros/inline-macro-inner-object.check b/tests/run-macros/inline-macro-inner-object.check new file mode 100644 index 000000000000..480feef5f62f --- /dev/null +++ b/tests/run-macros/inline-macro-inner-object.check @@ -0,0 +1,3 @@ +A.f +A.B.f +A.B.C.f diff --git a/tests/run-macros/inline-macro-inner-object/Macro_1.scala b/tests/run-macros/inline-macro-inner-object/Macro_1.scala new file mode 100644 index 000000000000..ab6b8f3faafc --- /dev/null +++ b/tests/run-macros/inline-macro-inner-object/Macro_1.scala @@ -0,0 +1,22 @@ +package blah + +import scala.quoted._ + +object A { + inline def f: Unit = ${impl} + private def impl given (qctx: QuoteContext): Expr[Unit] = { + '{println("A.f")} + } + object B { + inline def f: Unit = ${impl} + private def impl given (qctx: QuoteContext): Expr[Unit] = { + '{println("A.B.f")} + } + object C { + inline def f: Unit = ${impl} + private def impl given (qctx: QuoteContext): Expr[Unit] = { + '{println("A.B.C.f")} + } + } + } +} diff --git a/tests/run-macros/inline-macro-inner-object/Test_2.scala b/tests/run-macros/inline-macro-inner-object/Test_2.scala new file mode 100644 index 000000000000..6f078264f0f0 --- /dev/null +++ b/tests/run-macros/inline-macro-inner-object/Test_2.scala @@ -0,0 +1,9 @@ +import blah._ + +object Test { + def main(args: Array[String]): Unit = { + A.f + A.B.f + A.B.C.f + } +} From 312822d83a562591b3a95d71877169aed5f7b272 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jul 2019 06:47:32 +0200 Subject: [PATCH 2/2] Use flatName --- compiler/src/dotty/tools/dotc/transform/Splicer.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index fe385c8ca566..b65fee47d7c9 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -158,10 +158,8 @@ object Splicer { // nested object in an object val className = { val pack = sym.topLevelClass.owner - val prefix = - if (pack == defn.RootPackage || pack == defn.EmptyPackageClass) "" - else pack.showFullName + "." - prefix + sym.fullNameSeparated(FlatName) + if (pack == defn.RootPackage || pack == defn.EmptyPackageClass) sym.flatName.toString + else pack.showFullName + "." + sym.flatName } val clazz = loadClass(className) clazz.getConstructor().newInstance().asInstanceOf[Object]