Skip to content

Commit efcdf18

Browse files
committed
Split Symbol.newType into 2 methods and add tests
1 parent 429ac32 commit efcdf18

File tree

10 files changed

+93
-19
lines changed

10 files changed

+93
-19
lines changed

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -2613,11 +2613,15 @@ 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 =
2616+
2617+
def newTypeAlias(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, dotc.core.Types.TypeAlias(tpe), privateWithin)
2620+
2621+
def newBoundedType(owner: Symbol, name: String, flags: Flags, tpe: TypeBounds, privateWithin: Symbol): Symbol =
26182622
checkValidFlags(flags.toTypeFlags, Flags.validTypeFlags)
26192623
dotc.core.Symbols.newSymbol(owner, name.toTypeName, flags | dotc.core.Flags.Deferred, tpe, privateWithin)
2620-
2624+
26212625
def noSymbol: Symbol = dotc.core.Symbols.NoSymbol
26222626

26232627
private inline def checkValidFlags(inline flags: Flags, inline valid: Flags): Unit =
@@ -2959,6 +2963,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
29592963
// Keep: aligned with Quotes's `newBind` doc
29602964
private[QuotesImpl] def validBindFlags: Flags = Case // Flags that could be allowed: Implicit | Given | Erased
29612965

2966+
// Keep: aligned with Quotes's 'newType' doc
29622967
private[QuotesImpl] def validTypeFlags: Flags = Private | Protected | Override | Deferred | Final | Infix | Local
29632968

29642969
end Flags

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

+22-4
Original file line numberDiff line numberDiff line change
@@ -3915,23 +3915,41 @@ 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-
*
3918+
/** Generate a new type symbol for a type alias 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 the type alias
3928+
* @param privateWithin the symbol within which this new method symbol should be private. May be noSymbol.
3929+
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
3930+
* direct or indirect children of the reflection context's owner.
3931+
*/
3932+
@experimental
3933+
// Keep: `flags` doc aligned with QuotesImpl's `validTypeFlags`
3934+
def newTypeAlias(parent: Symbol, name: String, flags: Flags, tpe: TypeRepr, privateWithin: Symbol): Symbol
3935+
3936+
/** Generate a new type symbol for a type bounds with the given parent, name and type
3937+
*
39203938
* This symbol starts without an accompanying definition.
39213939
* It is the meta-programmer's responsibility to provide exactly one corresponding definition by passing
39223940
* this symbol to the TypeDef constructor.
39233941
*
39243942
* @param parent The owner of the type
39253943
* @param name The name of the type
39263944
* @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
3945+
* @param tpe The bounds of the type
39283946
* @param privateWithin the symbol within which this new method symbol should be private. May be noSymbol.
39293947
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
39303948
* direct or indirect children of the reflection context's owner.
39313949
*/
39323950
@experimental
39333951
// Keep: `flags` doc aligned with QuotesImpl's `validTypeFlags`
3934-
def newType(parent: Symbol, name: String, flags: Flags, tpe: TypeRepr, privateWithin: Symbol): Symbol
3952+
def newBoundedType(parent: Symbol, name: String, flags: Flags, tpe: TypeBounds, privateWithin: Symbol): Symbol
39353953

39363954
/** Definition not available */
39373955
def noSymbol: Symbol
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//> using options -experimental -Yno-experimental
2+
import scala.quoted.*
3+
4+
inline def testMacro = ${ testImpl }
5+
6+
transparent inline def transparentTestMacro = ${ testImpl }
7+
8+
def testImpl(using Quotes): Expr[Object] = {
9+
import quotes.reflect.*
10+
11+
def makeType(owner: Symbol): Symbol =
12+
Symbol.newBoundedType(owner, "mytype", Flags.EmptyFlags, TypeBounds.lower(TypeRepr.of[String]), Symbol.noSymbol)
13+
14+
val typeDef = TypeDef(makeType(Symbol.spliceOwner))
15+
// Expr printer does not work here, see comment:
16+
// https://github.com/scala/scala3/pull/20347#issuecomment-2096824617
17+
assert(typeDef.toString == "TypeDef(mytype,TypeTree[TypeBounds(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class java)),object lang),String),TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Any))])")
18+
19+
val clsSymbol = Symbol.newClass(Symbol.spliceOwner, "CLS", List(TypeRepr.of[Object]), sym => List(makeType(sym)), None)
20+
val classDef: ClassDef = ClassDef(clsSymbol, List(TypeTree.of[Object]), List(TypeDef(clsSymbol.typeMember("mytype"))))
21+
Block(List(classDef), Apply(Select(New(TypeIdent(clsSymbol)), clsSymbol.primaryConstructor), List.empty)).asExprOf[Object]
22+
}
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//> using options -experimental -Yno-experimental
2+
def test =
3+
testMacro
4+
transparentTestMacro
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//> using options -experimental -Yno-experimental
2+
import scala.quoted.*
3+
4+
inline def testMacro = ${ testImpl }
5+
6+
transparent inline def transparentTestMacro = ${ testImpl }
7+
8+
def testImpl(using Quotes): Expr[Object] = {
9+
import quotes.reflect.*
10+
11+
def makeType(owner: Symbol): Symbol =
12+
Symbol.newTypeAlias(owner, "mytype", Flags.EmptyFlags, TypeRepr.of[String], Symbol.noSymbol)
13+
14+
val clsSymbol = Symbol.newClass(Symbol.spliceOwner, "CLS", List(TypeRepr.of[Object]), sym => List(makeType(sym)), None)
15+
val classDef: ClassDef = ClassDef(clsSymbol, List(TypeTree.of[Object]), List(TypeDef(clsSymbol.typeMember("mytype"))))
16+
17+
Block(List(classDef), Apply(Select(New(TypeIdent(clsSymbol)), clsSymbol.primaryConstructor), List.empty)).asExprOf[Object]
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//> using options -experimental -Yno-experimental
2+
def test =
3+
testMacro
4+
transparentTestMacro

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

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

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

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
//> using options -experimental -Yno-experimental
2+
def test = testMacro

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

-10
This file was deleted.

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

-2
This file was deleted.

0 commit comments

Comments
 (0)