Skip to content

Commit 85fdd02

Browse files
committed
Add more tests, checks for flags and improve docs
1 parent bf14f5b commit 85fdd02

File tree

2 files changed

+48
-22
lines changed

2 files changed

+48
-22
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

+14-1
Original file line numberDiff line numberDiff line change
@@ -2687,6 +2687,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
26872687
assert(!clsPrivateWithin.exists || clsPrivateWithin.isType, "clsPrivateWithin must be a type symbol or `Symbol.noSymbol`")
26882688
assert(!conPrivateWithin.exists || conPrivateWithin.isType, "consPrivateWithin must be a type symbol or `Symbol.noSymbol`")
26892689
checkValidFlags(clsFlags.toTypeFlags, Flags.validClassFlags)
2690+
checkValidFlags(conFlags, Flags.validClassConstructorFlags)
26902691
val cls = dotc.core.Symbols.newNormalizedClassSymbolUsingClassSymbolinParents(
26912692
owner,
26922693
name.toTypeName,
@@ -2728,12 +2729,14 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
27282729
}
27292730
for ((name, tpe, isType, clauseIdx), elementIdx) <- getParamAccessors(methodType, 0) do
27302731
if isType then
2732+
checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags.validClassTypeParamFlags)
27312733
val symbol = dotc.core.Symbols.newSymbol(cls, name.toTypeName, Flags.Param | Flags.Deferred | Flags.Private | Flags.PrivateLocal | Flags.Local | conParamFlags(clauseIdx)(elementIdx), tpe, Symbol.noSymbol)
27322734
paramRefMap.addOne(elementIdx, symbol)
27332735
cls.enter(symbol)
27342736
else
2737+
checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags.validClassTermParamFlags)
27352738
val fixedType = paramRefRemapper(tpe)
2736-
cls.enter(dotc.core.Symbols.newSymbol(cls, name.toTermName, Flags.ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, Symbol.noSymbol)) // set privateWithin
2739+
cls.enter(dotc.core.Symbols.newSymbol(cls, name.toTermName, Flags.ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, Symbol.noSymbol)) // TODO set privateWithin?
27372740
for sym <- decls(cls) do cls.enter(sym)
27382741
cls
27392742

@@ -3147,6 +3150,16 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
31473150
// Keep: aligned with Quotes's `newClass`
31483151
private[QuotesImpl] def validClassFlags: Flags = Private | Protected | PrivateLocal | Local | Final | Trait | Abstract // AbsOverride, Open
31493152

3153+
// Keep: aligned with Quote's 'newClass'
3154+
// Private constructor would be currently useless, but if we decide to add a way to register companions in the future it might be useful
3155+
private[QuotesImpl] def validClassConstructorFlags: Flags = Synthetic | Method | Private | Protected | PrivateLocal | Local
3156+
3157+
// Keep: aligned with Quotes's `newClass`
3158+
private[QuotesImpl] def validClassTypeParamFlags: Flags = Param | Deferred | Private | PrivateLocal | Local
3159+
3160+
// Keep: aligned with Quotes's `newClass`
3161+
private[QuotesImpl] def validClassTermParamFlags: Flags = ParamAccessor | Private | Protected | PrivateLocal | Local
3162+
31503163
end Flags
31513164

31523165
given FlagsMethods: FlagsMethods with

library/src/scala/quoted/Quotes.scala

+34-21
Original file line numberDiff line numberDiff line change
@@ -3837,10 +3837,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
38373837
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
38383838
* direct or indirect children of the reflection context's owner.
38393839
*/
3840-
// TODO: add flags and privateWithin
38413840
@experimental def newClass(owner: Symbol, name: String, parents: List[TypeRepr], decls: Symbol => List[Symbol], selfType: Option[TypeRepr]): Symbol
38423841

3843-
/** Generates a new class symbol for a class with a public constructor.
3842+
/** Generates a new class symbol for a class with a public single term clause constructor.
38443843
*
38453844
* @param owner The owner of the class
38463845
* @param name The name of the class
@@ -3851,7 +3850,13 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
38513850
* @param conParamNames constructor parameter names.
38523851
* @param conParamTypes constructor parameter types.
38533852
*
3854-
* Parameters can be obtained via classSymbol.memberField
3853+
* Parameters assigned by the constructor can be obtained via `classSymbol.memberField`.
3854+
* This symbol starts without an accompanying definition.
3855+
* It is the meta-programmer's responsibility to provide exactly one corresponding definition by passing
3856+
* this symbol to the ClassDef constructor.
3857+
*
3858+
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
3859+
* direct or indirect children of the reflection context's owner.
38553860
*/
38563861
@experimental def newClass(
38573862
owner: Symbol,
@@ -3864,24 +3869,32 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
38643869
conParamTypes: List[TypeRepr]
38653870
): Symbol
38663871

3867-
/**
3868-
*
3869-
*
3870-
* @param owner The owner of the class
3871-
* @param name The name of the class
3872-
* @param parents Function returning the parent classes of the class. The first parent must not be a trait
3873-
* Takes the constructed class symbol as an argument. Calling `cls.typeRef.asType` as part of this function will lead to cyclic reference errors.
3874-
* @param decls The member declarations of the class provided the symbol of this class
3875-
* @param selfType The self type of the class if it has one
3876-
* @param clsFlags extra flags with which the class symbol should be constructed
3877-
* @param clsPrivateWithin the symbol within which this new class symbol should be private. May be noSymbol
3878-
* @param conMethodType The MethodOrPoly type representing the type of the constructor.
3879-
* PolyType may only represent the first clause of the constructor.
3880-
* @param conFlags extra flags with which the constructor symbol should be constructed
3881-
* @param conPrivateWithin the symbol within which the constructor for this new class symbol should be private. May be noSymbol.
3882-
* @param conParamFlags extra flags with which the constructor parameter symbols should be constructed. Must match the shape of `conMethodType`.
3883-
*
3884-
*/
3872+
/** Generates a new class symbol with a constructor of the shape signified by a passed PolyOrMethod parameter.
3873+
* TODO example with PolyType
3874+
*
3875+
* @param owner The owner of the class
3876+
* @param name The name of the class
3877+
* @param parents Function returning the parent classes of the class. The first parent must not be a trait
3878+
* Takes the constructed class symbol as an argument. Calling `cls.typeRef.asType` as part of this function will lead to cyclic reference errors.
3879+
* @param decls The member declarations of the class provided the symbol of this class
3880+
* @param selfType The self type of the class if it has one
3881+
* @param clsFlags extra flags with which the class symbol should be constructed
3882+
* @param clsPrivateWithin the symbol within which this new class symbol should be private. May be noSymbol
3883+
* @param conMethodType Function returning MethodOrPoly type representing the type of the constructor.
3884+
* Takes the result type as parameter which must be returned from the innermost MethodOrPoly.
3885+
* PolyType may only represent the first clause of the constructor.
3886+
* @param conFlags extra flags with which the constructor symbol should be constructed
3887+
* @param conPrivateWithin the symbol within which the constructor for this new class symbol should be private. May be noSymbol.
3888+
* @param conParamFlags extra flags with which the constructor parameter symbols should be constructed. Must match the shape of `conMethodType`.
3889+
*
3890+
* Term and type parameters assigned by the constructor can be obtained via `classSymbol.memberField`/`classSymbol.memberType`.
3891+
* This symbol starts without an accompanying definition.
3892+
* It is the meta-programmer's responsibility to provide exactly one corresponding definition by passing
3893+
* this symbol to the ClassDef constructor.
3894+
*
3895+
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
3896+
* direct or indirect children of the reflection context's owner.
3897+
*/
38853898
@experimental def newClass(
38863899
owner: Symbol,
38873900
name: String,

0 commit comments

Comments
 (0)