diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 17d8d8fef925..4ac4328e626c 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -67,7 +67,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Context_requiredMethod(self: Context)(path: String): Symbol = self.requiredMethod(path) def Context_isJavaCompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.JavaCompilationUnit] def Context_isScala2CompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.Scala2CompilationUnit] - def Context_compilationUnitClassname(self: Context): String = + def Context_compilationUnitClassname(self: Context): String = self.compilationUnit match { case cu: fromtasty.JavaCompilationUnit => cu.className case cu: fromtasty.Scala2CompilationUnit => cu.className @@ -1758,10 +1758,11 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Symbol_of(fullName: String)(using ctx: Context): Symbol = ctx.requiredClass(fullName) - def Symbol_newMethod(parent: Symbol, name: String, flags: Flags, tpe: Type, privateWithin: Symbol)(using ctx: Context): Symbol = { - val computedFlags = flags | Flags.Method - ctx.newSymbol(parent, name.toTermName, computedFlags, tpe, privateWithin) - } + def Symbol_newMethod(parent: Symbol, name: String, flags: Flags, tpe: Type, privateWithin: Symbol)(using ctx: Context): Symbol = + ctx.newSymbol(parent, name.toTermName, flags | Flags.Method, tpe, privateWithin) + + def Symbol_newVal(parent: Symbol, name: String, flags: Flags, tpe: Type, privateWithin: Symbol)(using ctx: Context): Symbol = + ctx.newSymbol(parent, name.toTermName, flags, tpe, privateWithin) def Symbol_isTypeParam(self: Symbol)(using ctx: Context): Boolean = self.isTypeParam diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 6a7c3d39f4f0..1612ce8352ed 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -2109,6 +2109,22 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => def newMethod(parent: Symbol, name: String, tpe: Type, flags: Flags, privateWithin: Symbol)(using ctx: Context): Symbol = internal.Symbol_newMethod(parent, name, flags, tpe, privateWithin) + /** Generates a new val/var/lazy val symbol with the given parent, name and type. + * + * This symbol starts without an accompanying definition. + * It is the meta-programmer's responsibility to provide exactly one corresponding definition by passing + * this symbol to the ValDef constructor. + * + * Note: Also see Reflection.let + * + * @param flags extra flags to with which the symbol should be constructed + * @param privateWithin the symbol within which this new method symbol should be private. May be noSymbol. + * @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be + * direct or indirect children of the reflection context's owner. + */ + def newVal(parent: Symbol, name: String, tpe: Type, flags: Flags, privateWithin: Symbol)(using ctx: Context): Symbol = + internal.Symbol_newVal(parent, name, flags, tpe, privateWithin) + /** Definition not available */ def noSymbol(using ctx: Context): Symbol = internal.Symbol_noSymbol @@ -2772,19 +2788,8 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => /** Bind the `rhs` to a `val` and use it in `body` */ def let(rhs: Term)(body: Ident => Term)(using ctx: Context): Term = { - import scala.quoted.QuoteContext - given QuoteContext = new QuoteContext(this) - val expr = (rhs.seal: @unchecked) match { - case '{ $rhsExpr: $t } => - '{ - val x = $rhsExpr - ${ - val id = ('x).unseal.asInstanceOf[Ident] - body(id).seal - } - } - } - expr.unseal + val sym = Symbol.newVal(ctx.owner, "x", rhs.tpe.widen, Flags.EmptyFlags, Symbol.noSymbol) + Block(List(ValDef(sym, Some(rhs))), body(Ref(sym).asInstanceOf[Ident])) } /** Bind the given `terms` to names and use them in the `body` */ diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 4d8bde281daf..26707acdf941 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -1309,6 +1309,8 @@ trait CompilerInterface { def Symbol_newMethod(parent: Symbol, name: String, flags: Flags, tpe: Type, privateWithin: Symbol)(using ctx: Context): Symbol + def Symbol_newVal(parent: Symbol, name: String, flags: Flags, tpe: Type, privateWithin: Symbol)(using ctx: Context): Symbol + def Symbol_isTypeParam(self: Symbol)(using ctx: Context): Boolean def Symbol_isPackageDef(symbol: Symbol)(using ctx: Context): Boolean