Skip to content

Commit 38eab54

Browse files
committed
Add the possibility to create a typeSymbol in the Quotes API
1 parent fef6576 commit 38eab54

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

Diff for: compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

+8
Original file line numberDiff line numberDiff line change
@@ -2613,6 +2613,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
26132613
def newBind(owner: Symbol, name: String, flags: Flags, tpe: TypeRepr): Symbol =
26142614
checkValidFlags(flags.toTermFlags, Flags.validBindFlags)
26152615
dotc.core.Symbols.newSymbol(owner, name.toTermName, flags | dotc.core.Flags.Case, tpe)
2616+
2617+
def newType(owner: Symbol, name: String, flags: Flags, tpe: TypeRepr, privateWithin: Symbol): Symbol =
2618+
checkValidFlags(flags.toTypeFlags, Flags.validTypeFlags)
2619+
dotc.core.Symbols.newSymbol(owner, name.toTypeName, flags | dotc.core.Flags.Deferred, tpe, privateWithin)
2620+
26162621
def noSymbol: Symbol = dotc.core.Symbols.NoSymbol
26172622

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

29542959
// Keep: aligned with Quotes's `newBind` doc
29552960
private[QuotesImpl] def validBindFlags: Flags = Case // Flags that could be allowed: Implicit | Given | Erased
2961+
2962+
private[QuotesImpl] def validTypeFlags: Flags = Private | Protected | Override | Deferred | Final | Infix | Local
2963+
29562964
end Flags
29572965

29582966
given FlagsMethods: FlagsMethods with

Diff for: library/src/scala/quoted/Quotes.scala

+17
Original file line numberDiff line numberDiff line change
@@ -3915,6 +3915,23 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
39153915
// Keep: `flags` doc aligned with QuotesImpl's `validBindFlags`
39163916
def newBind(parent: Symbol, name: String, flags: Flags, tpe: TypeRepr): Symbol
39173917

3918+
/** Generate a new type symbol with the given parent, name and type
3919+
*
3920+
* This symbol starts without an accompanying definition.
3921+
* It is the meta-programmer's responsibility to provide exactly one corresponding definition by passing
3922+
* this symbol to the TypeDef constructor.
3923+
*
3924+
* @param parent The owner of the type
3925+
* @param name The name of the type
3926+
* @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`
3927+
* @param tpe The rhs or bounds of the type
3928+
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
3929+
* direct or indirect children of the reflection context's owner.
3930+
*/
3931+
@experimental
3932+
// Keep: `flags` doc aligned with QuotesImpl's `validTypeFlags`
3933+
def newType(parent: Symbol, name: String, flags: Flags, tpe: TypeRepr, privateWithin: Symbol): Symbol
3934+
39183935
/** Definition not available */
39193936
def noSymbol: Symbol
39203937

Diff for: tests/pos-macros/quoted-sym-newtype/Macro_1.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import scala.quoted.*
2+
3+
inline def testMacro = ${ testImpl }
4+
5+
def testImpl(using Quotes): Expr[Unit] = {
6+
import quotes.reflect.*
7+
val sym = Symbol.newType(Symbol.spliceOwner, "mytype", Flags.EmptyFlags, TypeRepr.of[String], Symbol.noSymbol)
8+
assert(TypeDef(sym).show == "type mytype = java.lang.String")
9+
'{ () }
10+
}

Diff for: tests/pos-macros/quoted-sym-newtype/Test_2.scala

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
def test = testMacro

0 commit comments

Comments
 (0)