From 0b388a6fe787e923c68dfd5c7a2dd93edb324b5d Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Fri, 3 Jul 2020 19:31:00 +0200 Subject: [PATCH 1/4] Disable upickle For some reason it fails the Community Build. FTTB disable it as a hotfix. --- .../test/scala/dotty/communitybuild/CommunityBuildTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala index c68f39e0529c..52e05cad0d70 100644 --- a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala +++ b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala @@ -378,7 +378,7 @@ class CommunityBuildTest: @Test def sourcecode = projects.sourcecode.run() @Test def oslib = projects.oslib.run() @Test def ujson = projects.ujson.run() - @Test def upickle = projects.upickle.run() + // @Test def upickle = projects.upickle.run() // @Test def oslibWatch = projects.oslibWatch.run() @Test def geny = projects.geny.run() @Test def stdLib213 = projects.stdLib213.run() From b99faf8bf3ed87e99f4360b296254a1433d1273d Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Wed, 24 Jun 2020 14:10:19 +0200 Subject: [PATCH 2/4] Add defaultParams method to Tasty Reflect Symbol API --- .../ReflectionCompilerInterface.scala | 16 ++++++++++++++++ library/src/scala/tasty/Reflection.scala | 8 ++++++++ .../scala/tasty/reflect/CompilerInterface.scala | 7 +++++++ tests/run-macros/reflect-defaultParams.check | 1 + .../reflect-defaultParams/Macro_1.scala | 11 +++++++++++ .../reflect-defaultParams/Test_2.scala | 4 ++++ 6 files changed, 47 insertions(+) create mode 100644 tests/run-macros/reflect-defaultParams.check create mode 100644 tests/run-macros/reflect-defaultParams/Macro_1.scala create mode 100644 tests/run-macros/reflect-defaultParams/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 5d512eafa90c..eba97c25ca9a 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -1779,6 +1779,22 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend case sym if sym.is(Flags.CaseAccessor) => sym.asTerm } + def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Ref] = + assert(self.isClass && self.flags.is(Flags.Case)) + val comp: Symbol = self.companionClass + val names: List[String] = + for p <- Symbol_caseFields(self) if p.flags.is(Flags.HasDefault) + yield Symbol_name(p) + + val body = ClassDef_body(Symbol_tree(comp).asInstanceOf[ClassDef]) + val idents: List[Ref] = + for case deff @ DefDef(name, _, _, _, tree) <- body + if name.toString.startsWith("$lessinit$greater$default") + yield Ref_apply(deff.symbol) + + names.zip(idents).toMap + end Symbol_defaultParams + def Symbol_children(self: Symbol)(using ctx: Context): List[Symbol] = self.children diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 94ba1f558bc0..95629e79c361 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -2284,6 +2284,14 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => def caseFields(using ctx: Context): List[Symbol] = internal.Symbol_caseFields(sym) + /** Default parameters of a case class. Keys are names of the parameters and values – + * symbols of the definitions sites of the default values. + * Implementation restriction: only the default parameters in the first parameter group + * are returned. + */ + def defaultParams(using ctx: Context): Map[String, Ref] = + internal.Symbol_defaultParams(sym) + def isTypeParam(using ctx: Context): Boolean = internal.Symbol_isTypeParam(sym) diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 60c5d7887535..791f12e905be 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -1332,6 +1332,13 @@ trait CompilerInterface { /** Fields of a case class type -- only the ones declared in primary constructor */ def Symbol_caseFields(self: Symbol)(using ctx: Context): List[Symbol] + /** Default parameters of a case class. Keys are names of the parameters and values – + * symbols of the definitions sites of the default values. + * Implementation restriction: only the default parameters in the first parameter group + * are returned. + */ + def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Ref] + def Symbol_of(fullName: String)(using ctx: Context): Symbol def Symbol_newMethod(parent: Symbol, name: String, flags: Flags, tpe: Type, privateWithin: Symbol)(using ctx: Context): Symbol diff --git a/tests/run-macros/reflect-defaultParams.check b/tests/run-macros/reflect-defaultParams.check new file mode 100644 index 000000000000..9f09f9d6c9ee --- /dev/null +++ b/tests/run-macros/reflect-defaultParams.check @@ -0,0 +1 @@ +Map(address -> Home, age -> 1) diff --git a/tests/run-macros/reflect-defaultParams/Macro_1.scala b/tests/run-macros/reflect-defaultParams/Macro_1.scala new file mode 100644 index 000000000000..af49dd92e7da --- /dev/null +++ b/tests/run-macros/reflect-defaultParams/Macro_1.scala @@ -0,0 +1,11 @@ +import scala.quoted._ + +inline def defaultParams[T]: Map[String, Any] = ${ defaultParamsImpl[T] } +private def defaultParamsImpl[T]( + using tpe: Type[T], qctx: QuoteContext): Expr[Map[String, Any]] = + import qctx.tasty._ + val sym = tpe.unseal.symbol + val exprs: Map[String, Expr[Any]] = + sym.defaultParams.view.mapValues(_.seal.cast[Any]).toMap + Expr.ofMapValues(exprs) +end defaultParamsImpl diff --git a/tests/run-macros/reflect-defaultParams/Test_2.scala b/tests/run-macros/reflect-defaultParams/Test_2.scala new file mode 100644 index 000000000000..9a2e0773f3d7 --- /dev/null +++ b/tests/run-macros/reflect-defaultParams/Test_2.scala @@ -0,0 +1,4 @@ +case class Cat(name: String, address: String = "Home", age: Int = 1) + +@main def Test = + println(defaultParams[Cat]) From 3c3a06df17e9967682eac9cddffb3b6c65e87fd2 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Wed, 24 Jun 2020 16:13:45 +0200 Subject: [PATCH 3/4] defaultParams returns Symbols Co-authored-by: Nicolas Stucki Update tests --- .../tastyreflect/ReflectionCompilerInterface.scala | 10 +++++----- library/src/scala/tasty/Reflection.scala | 2 +- .../src/scala/tasty/reflect/CompilerInterface.scala | 2 +- tests/run-macros/reflect-defaultParams/Macro_1.scala | 3 ++- tests/run-macros/reflect-defaultParams/Test_2.scala | 5 +++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index eba97c25ca9a..bc2d6572c8b4 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -1779,7 +1779,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend case sym if sym.is(Flags.CaseAccessor) => sym.asTerm } - def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Ref] = + def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Symbol] = assert(self.isClass && self.flags.is(Flags.Case)) val comp: Symbol = self.companionClass val names: List[String] = @@ -1787,11 +1787,11 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend yield Symbol_name(p) val body = ClassDef_body(Symbol_tree(comp).asInstanceOf[ClassDef]) - val idents: List[Ref] = - for case deff @ DefDef(name, _, _, _, tree) <- body + val idents: List[Symbol] = + for case deff @ DefDef(name, Nil, Nil, _, _) <- body if name.toString.startsWith("$lessinit$greater$default") - yield Ref_apply(deff.symbol) - + yield deff.symbol + assert(names.size == idents.size) names.zip(idents).toMap end Symbol_defaultParams diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 95629e79c361..49738c376372 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -2289,7 +2289,7 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => * Implementation restriction: only the default parameters in the first parameter group * are returned. */ - def defaultParams(using ctx: Context): Map[String, Ref] = + def defaultParams(using ctx: Context): Map[String, Symbol] = internal.Symbol_defaultParams(sym) def isTypeParam(using ctx: Context): Boolean = diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 791f12e905be..38789d4a3c69 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -1337,7 +1337,7 @@ trait CompilerInterface { * Implementation restriction: only the default parameters in the first parameter group * are returned. */ - def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Ref] + def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Symbol] def Symbol_of(fullName: String)(using ctx: Context): Symbol diff --git a/tests/run-macros/reflect-defaultParams/Macro_1.scala b/tests/run-macros/reflect-defaultParams/Macro_1.scala index af49dd92e7da..32c4bf797777 100644 --- a/tests/run-macros/reflect-defaultParams/Macro_1.scala +++ b/tests/run-macros/reflect-defaultParams/Macro_1.scala @@ -6,6 +6,7 @@ private def defaultParamsImpl[T]( import qctx.tasty._ val sym = tpe.unseal.symbol val exprs: Map[String, Expr[Any]] = - sym.defaultParams.view.mapValues(_.seal.cast[Any]).toMap + sym.defaultParams.view.mapValues(sym => + Ref(sym).seal.cast[Any]).toMap Expr.ofMapValues(exprs) end defaultParamsImpl diff --git a/tests/run-macros/reflect-defaultParams/Test_2.scala b/tests/run-macros/reflect-defaultParams/Test_2.scala index 9a2e0773f3d7..226ae9d7e514 100644 --- a/tests/run-macros/reflect-defaultParams/Test_2.scala +++ b/tests/run-macros/reflect-defaultParams/Test_2.scala @@ -1,4 +1,5 @@ -case class Cat(name: String, address: String = "Home", age: Int = 1) +case class Cat(name: String, address: String = "Home", + age: Int = 1)(a: Int = age, b: String = address + age) @main def Test = - println(defaultParams[Cat]) + println(defaultParams[Cat].toList.sortBy(_._1)) From d991b85856e321697de01523e238dd72e1642b33 Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Fri, 3 Jul 2020 18:49:21 +0200 Subject: [PATCH 4/4] defaultParams returns a List of pairs Update tests --- .../tastyreflect/ReflectionCompilerInterface.scala | 4 ++-- library/src/scala/tasty/Reflection.scala | 6 +++--- .../scala/tasty/reflect/CompilerInterface.scala | 6 +++--- tests/run-macros/reflect-defaultParams.check | 2 +- .../run-macros/reflect-defaultParams/Macro_1.scala | 14 ++++++++------ .../run-macros/reflect-defaultParams/Test_2.scala | 5 ++--- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index bc2d6572c8b4..7b38586563e1 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -1779,7 +1779,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend case sym if sym.is(Flags.CaseAccessor) => sym.asTerm } - def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Symbol] = + def Symbol_defaultParams(self: Symbol)(using ctx: Context): List[(String, Symbol)] = assert(self.isClass && self.flags.is(Flags.Case)) val comp: Symbol = self.companionClass val names: List[String] = @@ -1792,7 +1792,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend if name.toString.startsWith("$lessinit$greater$default") yield deff.symbol assert(names.size == idents.size) - names.zip(idents).toMap + names.zip(idents) end Symbol_defaultParams def Symbol_children(self: Symbol)(using ctx: Context): List[Symbol] = diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 49738c376372..521cc11704f1 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -2284,12 +2284,12 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => def caseFields(using ctx: Context): List[Symbol] = internal.Symbol_caseFields(sym) - /** Default parameters of a case class. Keys are names of the parameters and values – - * symbols of the definitions sites of the default values. + /** Default parameters of a case class. The first elements of the pairs are names of + * the parameters and values – symbols of the definitions sites of the default values. * Implementation restriction: only the default parameters in the first parameter group * are returned. */ - def defaultParams(using ctx: Context): Map[String, Symbol] = + def defaultParams(using ctx: Context): List[(String, Symbol)] = internal.Symbol_defaultParams(sym) def isTypeParam(using ctx: Context): Boolean = diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 38789d4a3c69..8cbbc93c54a1 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -1332,12 +1332,12 @@ trait CompilerInterface { /** Fields of a case class type -- only the ones declared in primary constructor */ def Symbol_caseFields(self: Symbol)(using ctx: Context): List[Symbol] - /** Default parameters of a case class. Keys are names of the parameters and values – - * symbols of the definitions sites of the default values. + /** Default parameters of a case class. The first elements of the pairs are names of + * the parameters and values – symbols of the definitions sites of the default values. * Implementation restriction: only the default parameters in the first parameter group * are returned. */ - def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Symbol] + def Symbol_defaultParams(self: Symbol)(using ctx: Context): List[(String, Symbol)] def Symbol_of(fullName: String)(using ctx: Context): Symbol diff --git a/tests/run-macros/reflect-defaultParams.check b/tests/run-macros/reflect-defaultParams.check index 9f09f9d6c9ee..b36edcfbd951 100644 --- a/tests/run-macros/reflect-defaultParams.check +++ b/tests/run-macros/reflect-defaultParams.check @@ -1 +1 @@ -Map(address -> Home, age -> 1) +List((address,Home), (age,1)) diff --git a/tests/run-macros/reflect-defaultParams/Macro_1.scala b/tests/run-macros/reflect-defaultParams/Macro_1.scala index 32c4bf797777..e042877cf691 100644 --- a/tests/run-macros/reflect-defaultParams/Macro_1.scala +++ b/tests/run-macros/reflect-defaultParams/Macro_1.scala @@ -1,12 +1,14 @@ import scala.quoted._ -inline def defaultParams[T]: Map[String, Any] = ${ defaultParamsImpl[T] } +inline def defaultParams[T]: List[(String, Any)] = ${ defaultParamsImpl[T] } private def defaultParamsImpl[T]( - using tpe: Type[T], qctx: QuoteContext): Expr[Map[String, Any]] = + using tpe: Type[T], qctx: QuoteContext): Expr[List[(String, Any)]] = import qctx.tasty._ val sym = tpe.unseal.symbol - val exprs: Map[String, Expr[Any]] = - sym.defaultParams.view.mapValues(sym => - Ref(sym).seal.cast[Any]).toMap - Expr.ofMapValues(exprs) + val defaultParams = sym.defaultParams + val values: List[Expr[Any]] = + defaultParams.map { case (k, v) => Ref(v).seal } + val names: List[Expr[String]] = + defaultParams.map { case (k, v) => Expr(k) } + '{ ${ Expr.ofList(names) }.zip(${ Expr.ofList(values) }) } end defaultParamsImpl diff --git a/tests/run-macros/reflect-defaultParams/Test_2.scala b/tests/run-macros/reflect-defaultParams/Test_2.scala index 226ae9d7e514..407934920b33 100644 --- a/tests/run-macros/reflect-defaultParams/Test_2.scala +++ b/tests/run-macros/reflect-defaultParams/Test_2.scala @@ -1,5 +1,4 @@ -case class Cat(name: String, address: String = "Home", - age: Int = 1)(a: Int = age, b: String = address + age) +case class Cat(name: String, address: String = "Home", age: Int = 1)(a: Int = age, b: String = address + age) @main def Test = - println(defaultParams[Cat].toList.sortBy(_._1)) + println(defaultParams[Cat])