Skip to content

Commit

Permalink
Add the possibility to create a typeSymbol in the Quotes API
Browse files Browse the repository at this point in the history
  • Loading branch information
hamzaremmal committed May 6, 2024
1 parent fef6576 commit 38eab54
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
8 changes: 8 additions & 0 deletions compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2613,6 +2613,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
def newBind(owner: Symbol, name: String, flags: Flags, tpe: TypeRepr): Symbol =
checkValidFlags(flags.toTermFlags, Flags.validBindFlags)
dotc.core.Symbols.newSymbol(owner, name.toTermName, flags | dotc.core.Flags.Case, tpe)

def newType(owner: Symbol, name: String, flags: Flags, tpe: TypeRepr, privateWithin: Symbol): Symbol =
checkValidFlags(flags.toTypeFlags, Flags.validTypeFlags)
dotc.core.Symbols.newSymbol(owner, name.toTypeName, flags | dotc.core.Flags.Deferred, tpe, privateWithin)

def noSymbol: Symbol = dotc.core.Symbols.NoSymbol

private inline def checkValidFlags(inline flags: Flags, inline valid: Flags): Unit =
Expand Down Expand Up @@ -2953,6 +2958,9 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler

// Keep: aligned with Quotes's `newBind` doc
private[QuotesImpl] def validBindFlags: Flags = Case // Flags that could be allowed: Implicit | Given | Erased

private[QuotesImpl] def validTypeFlags: Flags = Private | Protected | Override | Deferred | Final | Infix | Local

end Flags

given FlagsMethods: FlagsMethods with
Expand Down
17 changes: 17 additions & 0 deletions library/src/scala/quoted/Quotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3915,6 +3915,23 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
// Keep: `flags` doc aligned with QuotesImpl's `validBindFlags`
def newBind(parent: Symbol, name: String, flags: Flags, tpe: TypeRepr): Symbol

/** Generate a new type 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 TypeDef constructor.
*
* @param parent The owner of the type
* @param name The name of the type
* @param flags extra flags to with which symbol can be constructed. `Deferred` flag will be added. Can be `Private` | `Protected` | `Override` | `Deferred` | `Final` | `Infix` | `Local`
* @param tpe The rhs or bounds of the type
* @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.
*/
@experimental
// Keep: `flags` doc aligned with QuotesImpl's `validTypeFlags`
def newType(parent: Symbol, name: String, flags: Flags, tpe: TypeRepr, privateWithin: Symbol): Symbol

/** Definition not available */
def noSymbol: Symbol

Expand Down
10 changes: 10 additions & 0 deletions tests/pos-macros/quoted-sym-newtype/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import scala.quoted.*

inline def testMacro = ${ testImpl }

def testImpl(using Quotes): Expr[Unit] = {
import quotes.reflect.*
val sym = Symbol.newType(Symbol.spliceOwner, "mytype", Flags.EmptyFlags, TypeRepr.of[String], Symbol.noSymbol)
assert(TypeDef(sym).show == "type mytype = java.lang.String")
'{ () }
}
2 changes: 2 additions & 0 deletions tests/pos-macros/quoted-sym-newtype/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

def test = testMacro

0 comments on commit 38eab54

Please sign in to comment.