Skip to content

Add Reflection.Symbol.newVal #8291

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
29 changes: 16 additions & 13 deletions library/src/scala/tasty/Reflection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2109,6 +2109,20 @@ 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.
*
* @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
Expand Down Expand Up @@ -2772,19 +2786,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` */
Expand Down
2 changes: 2 additions & 0 deletions library/src/scala/tasty/reflect/CompilerInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down