Skip to content

Commit 7e991d2

Browse files
committed
Add more tests, checks for flags and improve docs
1 parent 9afd40c commit 7e991d2

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
@@ -2724,6 +2724,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
27242724
assert(!clsPrivateWithin.exists || clsPrivateWithin.isType, "clsPrivateWithin must be a type symbol or `Symbol.noSymbol`")
27252725
assert(!conPrivateWithin.exists || conPrivateWithin.isType, "consPrivateWithin must be a type symbol or `Symbol.noSymbol`")
27262726
checkValidFlags(clsFlags.toTypeFlags, Flags.validClassFlags)
2727+
checkValidFlags(conFlags, Flags.validClassConstructorFlags)
27272728
val cls = dotc.core.Symbols.newNormalizedClassSymbolUsingClassSymbolinParents(
27282729
owner,
27292730
name.toTypeName,
@@ -2765,12 +2766,14 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
27652766
}
27662767
for ((name, tpe, isType, clauseIdx), elementIdx) <- getParamAccessors(methodType, 0) do
27672768
if isType then
2769+
checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags.validClassTypeParamFlags)
27682770
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)
27692771
paramRefMap.addOne(elementIdx, symbol)
27702772
cls.enter(symbol)
27712773
else
2774+
checkValidFlags(conParamFlags(clauseIdx)(elementIdx), Flags.validClassTermParamFlags)
27722775
val fixedType = paramRefRemapper(tpe)
2773-
cls.enter(dotc.core.Symbols.newSymbol(cls, name.toTermName, Flags.ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, Symbol.noSymbol)) // set privateWithin
2776+
cls.enter(dotc.core.Symbols.newSymbol(cls, name.toTermName, Flags.ParamAccessor | conParamFlags(clauseIdx)(elementIdx), fixedType, Symbol.noSymbol)) // TODO set privateWithin?
27742777
for sym <- decls(cls) do cls.enter(sym)
27752778
cls
27762779

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

3190+
// Keep: aligned with Quote's 'newClass'
3191+
// Private constructor would be currently useless, but if we decide to add a way to register companions in the future it might be useful
3192+
private[QuotesImpl] def validClassConstructorFlags: Flags = Synthetic | Method | Private | Protected | PrivateLocal | Local
3193+
3194+
// Keep: aligned with Quotes's `newClass`
3195+
private[QuotesImpl] def validClassTypeParamFlags: Flags = Param | Deferred | Private | PrivateLocal | Local
3196+
3197+
// Keep: aligned with Quotes's `newClass`
3198+
private[QuotesImpl] def validClassTermParamFlags: Flags = ParamAccessor | Private | Protected | PrivateLocal | Local
3199+
31873200
end Flags
31883201

31893202
given FlagsMethods: FlagsMethods with

library/src/scala/quoted/Quotes.scala

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

3858-
/** Generates a new class symbol for a class with a public constructor.
3857+
/** Generates a new class symbol for a class with a public single term clause constructor.
38593858
*
38603859
* @param owner The owner of the class
38613860
* @param name The name of the class
@@ -3866,7 +3865,13 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
38663865
* @param conParamNames constructor parameter names.
38673866
* @param conParamTypes constructor parameter types.
38683867
*
3869-
* Parameters can be obtained via classSymbol.memberField
3868+
* Parameters assigned by the constructor can be obtained via `classSymbol.memberField`.
3869+
* This symbol starts without an accompanying definition.
3870+
* It is the meta-programmer's responsibility to provide exactly one corresponding definition by passing
3871+
* this symbol to the ClassDef constructor.
3872+
*
3873+
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
3874+
* direct or indirect children of the reflection context's owner.
38703875
*/
38713876
@experimental def newClass(
38723877
owner: Symbol,
@@ -3879,24 +3884,32 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
38793884
conParamTypes: List[TypeRepr]
38803885
): Symbol
38813886

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

0 commit comments

Comments
 (0)