Skip to content

Commit 9c4c18b

Browse files
committed
Add scala.quoted.Scope
1 parent 7d14d44 commit 9c4c18b

File tree

682 files changed

+3755
-4080
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

682 files changed

+3755
-4080
lines changed

.github/workflows/ci.yaml

Lines changed: 341 additions & 341 deletions
Large diffs are not rendered by default.

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Names._, StdNames._, NameOps._, Symbols._
88
import typer.ConstFold
99
import reporting.trace
1010
import dotty.tools.dotc.transform.SymUtils._
11+
import dotty.tools.dotc.transform.TypeUtils._
1112
import Decorators._
1213
import Constants.Constant
1314

@@ -397,7 +398,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
397398
case New(_) | Closure(_, _, _) =>
398399
Pure
399400
case TypeApply(fn, _) =>
400-
if (fn.symbol.is(Erased) || fn.symbol == defn.QuotedTypeModule_apply || fn.symbol == defn.Predef_classOf) Pure else exprPurity(fn)
401+
if (fn.symbol.is(Erased) || fn.symbol == defn.ScopeTypeModule_apply || fn.symbol == defn.Predef_classOf) Pure else exprPurity(fn)
401402
case Apply(fn, args) =>
402403
def isKnownPureOp(sym: Symbol) =
403404
sym.owner.isPrimitiveValueClass
@@ -907,7 +908,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
907908
* will return a type tree.
908909
*/
909910
def unapply(tree: tpd.Select)(using Context): Option[tpd.Tree] =
910-
if tree.symbol.isTypeSplice then Some(tree.qualifier) else None
911+
if tree.tpe.isTypeSplice || (tree.qualifier.tpe.widenTermRefExpr.typeSymbol == defn.ScopeTypeClass && tree.name == tpnme.spliceType) then Some(tree.qualifier)
912+
else None
911913
}
912914

913915
/** Extractor for not-null assertions.

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ object Trees {
5656
abstract class Tree[-T >: Untyped](implicit @constructorOnly src: SourceFile)
5757
extends Positioned, SrcPos, Product, Attachment.Container, printing.Showable {
5858

59+
type X <: AnyKind // FIXME used for reflection. find another way to add this type
60+
5961
if (Stats.enabled) ntrees += 1
6062

6163
/** The type constructor at the root of the tree */

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -682,22 +682,16 @@ class Definitions {
682682
@tu lazy val ClassTagModule_apply: Symbol = ClassTagModule.requiredMethod(nme.apply)
683683
@tu lazy val ReflectPackageClass: Symbol = requiredPackage("scala.reflect.package").moduleClass
684684

685+
@tu lazy val QuotedExprModule: Symbol = requiredModule("scala.quoted.Expr")
685686

686-
@tu lazy val QuotedExprClass: ClassSymbol = requiredClass("scala.quoted.Expr")
687-
@tu lazy val QuotedExprModule: Symbol = QuotedExprClass.companionModule
688-
689-
@tu lazy val QuoteContextClass: ClassSymbol = requiredClass("scala.quoted.QuoteContext")
687+
@tu lazy val TastyReflectionClass: ClassSymbol = requiredClass("scala.tasty.Reflection")
690688

691-
@tu lazy val LiftableModule: Symbol = requiredModule("scala.quoted.Liftable")
692-
@tu lazy val LiftableModule_BooleanIsLiftable: Symbol = LiftableModule.requiredMethod("BooleanIsLiftable")
693-
@tu lazy val LiftableModule_ByteIsLiftable: Symbol = LiftableModule.requiredMethod("ByteIsLiftable")
694-
@tu lazy val LiftableModule_ShortIsLiftable: Symbol = LiftableModule.requiredMethod("ShortIsLiftable")
695-
@tu lazy val LiftableModule_IntIsLiftable: Symbol = LiftableModule.requiredMethod("IntIsLiftable")
696-
@tu lazy val LiftableModule_LongIsLiftable: Symbol = LiftableModule.requiredMethod("LongIsLiftable")
697-
@tu lazy val LiftableModule_FloatIsLiftable: Symbol = LiftableModule.requiredMethod("FloatIsLiftable")
698-
@tu lazy val LiftableModule_DoubleIsLiftable: Symbol = LiftableModule.requiredMethod("DoubleIsLiftable")
699-
@tu lazy val LiftableModule_CharIsLiftable: Symbol = LiftableModule.requiredMethod("CharIsLiftable")
700-
@tu lazy val LiftableModule_StringIsLiftable: Symbol = LiftableModule.requiredMethod("StringIsLiftable")
689+
@tu lazy val ScopeClass: ClassSymbol = requiredClass("scala.quoted.Scope")
690+
@tu lazy val ScopeTypeModule: Symbol = ScopeClass.requiredMethod("Type")
691+
@tu lazy val ScopeTypeModule_apply: Symbol = ScopeTypeModule.requiredMethod(nme.apply)
692+
@tu lazy val ScopeExprClass: Symbol = ScopeClass.typeRef.select(tpnme.Expr).typeSymbol
693+
@tu lazy val ScopeTypeClass: Symbol = ScopeClass.typeRef.select(tpnme.Type).typeSymbol
694+
@tu lazy val Scope_Type_splice: Symbol = ScopeClass.typeRef.select(tpnme.Type).select(tpnme.spliceType).typeSymbol
701695

702696
@tu lazy val InternalQuotedModule: Symbol = requiredModule("scala.internal.quoted.CompileTime")
703697
@tu lazy val InternalQuoted_exprQuote : Symbol = InternalQuotedModule.requiredMethod("exprQuote")
@@ -716,18 +710,19 @@ class Definitions {
716710
@tu lazy val InternalQuotedExpr_unapply: Symbol = InternalQuotedExprModule.requiredMethod(nme.unapply)
717711
@tu lazy val InternalQuotedExpr_null: Symbol = InternalQuotedExprModule.requiredMethod(nme.null_)
718712
@tu lazy val InternalQuotedExpr_unit: Symbol = InternalQuotedExprModule.requiredMethod(nme.Unit)
713+
@tu lazy val InternalQuotedExpr_liftBoolean: Symbol = InternalQuotedExprModule.requiredMethod("liftBoolean")
714+
@tu lazy val InternalQuotedExpr_liftByte: Symbol = InternalQuotedExprModule.requiredMethod("liftByte")
715+
@tu lazy val InternalQuotedExpr_liftShort: Symbol = InternalQuotedExprModule.requiredMethod("liftShort")
716+
@tu lazy val InternalQuotedExpr_liftInt: Symbol = InternalQuotedExprModule.requiredMethod("liftInt")
717+
@tu lazy val InternalQuotedExpr_liftLong: Symbol = InternalQuotedExprModule.requiredMethod("liftLong")
718+
@tu lazy val InternalQuotedExpr_liftFloat: Symbol = InternalQuotedExprModule.requiredMethod("liftFloat")
719+
@tu lazy val InternalQuotedExpr_liftDouble: Symbol = InternalQuotedExprModule.requiredMethod("liftDouble")
720+
@tu lazy val InternalQuotedExpr_liftChar: Symbol = InternalQuotedExprModule.requiredMethod("liftChar")
721+
@tu lazy val InternalQuotedExpr_liftString: Symbol = InternalQuotedExprModule.requiredMethod("liftString")
719722

720723
@tu lazy val InternalQuotedTypeModule: Symbol = requiredModule("scala.internal.quoted.Type")
721724
@tu lazy val InternalQuotedType_unapply: Symbol = InternalQuotedTypeModule.requiredMethod(nme.unapply)
722725

723-
@tu lazy val QuotedTypeClass: ClassSymbol = requiredClass("scala.quoted.Type")
724-
@tu lazy val QuotedType_splice: Symbol = QuotedTypeClass.requiredType(tpnme.spliceType)
725-
726-
@tu lazy val QuotedTypeModule: Symbol = QuotedTypeClass.companionModule
727-
@tu lazy val QuotedTypeModule_apply: Symbol = QuotedTypeModule.requiredMethod("apply")
728-
729-
@tu lazy val TastyReflectionClass: ClassSymbol = requiredClass("scala.tasty.Reflection")
730-
731726
@tu lazy val Unpickler_unpickleExpr: Symbol = requiredMethod("scala.internal.quoted.Unpickler.unpickleExpr")
732727
@tu lazy val Unpickler_unpickleType: Symbol = requiredMethod("scala.internal.quoted.Unpickler.unpickleType")
733728

compiler/src/dotty/tools/dotc/core/StagingContext.scala

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ object StagingContext {
1717
private val QuotationLevel = new Property.Key[Int]
1818

1919
/** A key to be used in a context property that tracks the quoteation stack.
20-
* Stack containing the QuoteContext references recieved by the surrounding quotes.
20+
* Stack containing the Scope references recieved by the surrounding quotes.
2121
*/
22-
private val QuoteContextStack = new Property.Key[List[tpd.Tree]]
22+
private val ScopeStack = new Property.Key[List[tpd.Tree]]
2323

2424
private val TaggedTypes = new Property.Key[PCPCheckAndHeal.QuoteTypeTags]
2525

@@ -31,11 +31,11 @@ object StagingContext {
3131
def quoteContext(using Context): Context =
3232
ctx.fresh.setProperty(QuotationLevel, level + 1)
3333

34-
/** Context with an incremented quotation level and pushes a refecence to a QuoteContext on the quote context stack */
35-
def pushQuoteContext(qctxRef: tpd.Tree)(using Context): Context =
36-
val old = ctx.property(QuoteContextStack).getOrElse(List.empty)
34+
/** Context with an incremented quotation level and pushes a refecence to a Scope on the quote scope stack */
35+
def pushScope(scopeRef: tpd.Tree)(using Context): Context =
36+
val old = ctx.property(ScopeStack).getOrElse(List.empty)
3737
ctx.fresh.setProperty(QuotationLevel, level + 1)
38-
.setProperty(QuoteContextStack, qctxRef :: old)
38+
.setProperty(ScopeStack, scopeRef :: old)
3939

4040
/** Context with a decremented quotation level. */
4141
def spliceContext(using Context): Context =
@@ -47,17 +47,23 @@ object StagingContext {
4747
def getQuoteTypeTags(using Context): PCPCheckAndHeal.QuoteTypeTags =
4848
ctx.property(TaggedTypes).get
4949

50-
/** Context with a decremented quotation level and pops the Some of top of the quote context stack or None if the stack is empty.
50+
/** Context with a decremented quotation level and pops the Some of top of the quote scope stack or None if the stack is empty.
5151
* The quotation stack could be empty if we are in a top level splice or an eroneous splice directly witin a top level splice.
5252
*/
53-
def popQuoteContext()(using Context): (Option[tpd.Tree], Context) =
53+
def popScope()(using Context): (Option[tpd.Tree], Context) =
5454
val ctx1 = ctx.fresh.setProperty(QuotationLevel, level - 1)
5555
val head =
56-
ctx.property(QuoteContextStack) match
56+
ctx.property(ScopeStack) match
5757
case Some(x :: xs) =>
58-
ctx1.setProperty(QuoteContextStack, xs)
58+
ctx1.setProperty(ScopeStack, xs)
5959
Some(x)
6060
case _ =>
6161
None // Splice at level 0 or lower
6262
(head, ctx1)
63+
64+
def peekScope()(implicit ctx: Context): Option[tpd.Tree] =
65+
ctx.property(ScopeStack) match
66+
case Some(x :: xs) => Some(x)
67+
case _ => None // Splice at level 0 or lower
68+
6369
}

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ object StdNames {
578578
val setSymbol: N = "setSymbol"
579579
val setType: N = "setType"
580580
val setTypeSignature: N = "setTypeSignature"
581-
val spliceType: N = "T"
581+
val spliceType: N = "X"
582582
val standardInterpolator: N = "standardInterpolator"
583583
val staticClass : N = "staticClass"
584584
val staticModule : N = "staticModule"

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ object Types {
9292
*/
9393
abstract class Type extends Hashable with printing.Showable {
9494

95+
type X <: AnyKind // FIXME used for reflection. find another way to add this type
96+
9597
// ----- Tests -----------------------------------------------------
9698

9799
// // debug only: a unique identifier for a type

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import dotty.tools.dotc.core.tasty.TreePickler.Hole
1515
import dotty.tools.dotc.core.tasty.{ PositionPickler, TastyPickler, TastyPrinter }
1616
import dotty.tools.dotc.core.tasty.DottyUnpickler
1717
import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode
18-
import dotty.tools.dotc.quoted.QuoteContext
18+
import dotty.tools.dotc.quoted.Scope
1919
import dotty.tools.dotc.tastyreflect.ReflectionImpl
2020

2121
import dotty.tools.tasty.TastyString
@@ -31,25 +31,12 @@ object PickledQuotes {
3131
def pickleQuote(tree: Tree)(using Context): PickledQuote =
3232
if (ctx.reporter.hasErrors) Nil
3333
else {
34-
assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'{$x}` which should be optimized to `x`
34+
// FIXME re-enable
35+
// assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'{$x}` which should be optimized to `x`
3536
val pickled = pickle(tree)
3637
TastyString.pickle(pickled)
3738
}
3839

39-
/** Transform the expression into its fully spliced Tree */
40-
def quotedExprToTree[T](expr: quoted.Expr[T])(using Context): Tree = {
41-
val expr1 = expr.asInstanceOf[scala.internal.quoted.Expr[Tree]]
42-
QuoteContext.checkScopeId(expr1.scopeId)
43-
healOwner(expr1.tree)
44-
}
45-
46-
/** Transform the expression into its fully spliced TypeTree */
47-
def quotedTypeToTree(tpe: quoted.Type[?])(using Context): Tree = {
48-
val tpe1 = tpe.asInstanceOf[scala.internal.quoted.Type[Tree]]
49-
QuoteContext.checkScopeId(tpe1.scopeId)
50-
healOwner(tpe1.typeTree)
51-
}
52-
5340
/** Unpickle the tree contained in the TastyExpr */
5441
def unpickleExpr(tasty: PickledQuote, splices: PickledArgs)(using Context): Tree = {
5542
val tastyBytes = TastyString.unpickle(tasty)
@@ -76,13 +63,13 @@ object PickledQuotes {
7663
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match {
7764
case Hole(isTerm, idx, args) =>
7865
val reifiedArgs = args.map { arg =>
79-
if (arg.isTerm) (using qctx: scala.quoted.QuoteContext) => new scala.internal.quoted.Expr(arg, QuoteContext.scopeId)
80-
else new scala.internal.quoted.Type(arg, QuoteContext.scopeId)
66+
if (arg.isTerm) (using scope: scala.quoted.Scope) => arg
67+
else arg
8168
}
8269
if isTerm then
83-
val splice1 = splices(idx).asInstanceOf[Seq[Any] => scala.quoted.QuoteContext ?=> quoted.Expr[?]]
84-
val quotedExpr = splice1(reifiedArgs)(using dotty.tools.dotc.quoted.QuoteContext())
85-
val filled = PickledQuotes.quotedExprToTree(quotedExpr)
70+
val splice1 = splices(idx).asInstanceOf[Seq[Any] => scala.quoted.Scope ?=> Tree]
71+
val quotedExpr = splice1(reifiedArgs)(using dotty.tools.dotc.quoted.Scope())
72+
val filled = PickledQuotes.healOwner(quotedExpr)
8673

8774
// We need to make sure a hole is created with the source file of the surrounding context, even if
8875
// it filled with contents a different source file.
@@ -91,8 +78,8 @@ object PickledQuotes {
9178
else
9279
// Replaces type holes generated by ReifyQuotes (non-spliced types).
9380
// These are types defined in a quote and used at the same level in a nested quote.
94-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](reifiedArgs)
95-
PickledQuotes.quotedTypeToTree(quotedType)
81+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => Tree](reifiedArgs)
82+
PickledQuotes.healOwner(quotedType)
9683
case tree: Select =>
9784
// Retain selected members
9885
val qual = transform(tree.qualifier)
@@ -134,8 +121,8 @@ object PickledQuotes {
134121
assert(tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot))
135122
val tree = tdef.rhs match
136123
case TypeBoundsTree(_, Hole(_, idx, args), _) =>
137-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](args)
138-
PickledQuotes.quotedTypeToTree(quotedType)
124+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => Tree](args)
125+
PickledQuotes.healOwner(quotedType)
139126
case TypeBoundsTree(_, tpt, _) =>
140127
tpt
141128
(tdef.symbol, tree.tpe)

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ class TreePickler(pickler: TastyPickler) {
734734

735735
def pickle(trees: List[Tree])(using Context): Unit = {
736736
trees.foreach(tree => if (!tree.isEmpty) pickleTree(tree))
737-
def missing = forwardSymRefs.keysIterator.map(sym => sym.showLocated + "(line " + sym.srcPos.line + ")").toList
737+
def missing = forwardSymRefs.keysIterator.map(sym => sym.showLocated + (if sym.sourcePos.exists then "(line " + sym.srcPos.line + ")" else "")).toList
738738
assert(forwardSymRefs.isEmpty, i"unresolved symbols: $missing%, % when pickling ${ctx.source}")
739739
}
740740

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import scala.collection.mutable.ListBuffer
3838
import scala.collection.mutable
3939
import config.Printers.pickling
4040
import core.quoted.PickledQuotes
41-
import dotty.tools.dotc.quoted.QuoteContext
41+
import dotty.tools.dotc.quoted.Scope
4242

4343
import dotty.tools.tasty.TastyFormat._
4444

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
367367
else if (name.isTypeName) typeText(txt)
368368
else txt
369369
case tree @ Select(qual, name) =>
370-
if (!printDebug && tree.hasType && tree.symbol.isTypeSplice) typeText("${") ~ toTextLocal(qual) ~ typeText("}")
370+
if (!printDebug && tree.hasType && tree.tpe.asInstanceOf[Type].isTypeSplice) typeText("${") ~ toTextLocal(qual) ~ typeText("}")
371371
else if (qual.isType) toTextLocal(qual) ~ "#" ~ typeText(toText(name))
372372
else toTextLocal(qual) ~ ("." ~ nameIdText(tree) provided (name != nme.CONSTRUCTOR || printDebug))
373373
case tree: This =>
@@ -630,11 +630,11 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
630630
}
631631
case Number(digits, kind) =>
632632
digits
633-
case Quote(tree) if tree.isTerm =>
633+
case Quote(tree) if !printDebug && tree.isTerm =>
634634
keywordStr("'{") ~ toTextGlobal(dropBlock(tree)) ~ keywordStr("}")
635-
case Splice(tree) =>
635+
case Splice(tree) if !printDebug =>
636636
keywordStr("${") ~ toTextGlobal(dropBlock(tree)) ~ keywordStr("}")
637-
case TypSplice(tree) =>
637+
case TypSplice(tree) if !printDebug =>
638638
keywordStr("${") ~ toTextGlobal(dropBlock(tree)) ~ keywordStr("}")
639639
case tree: Applications.IntegratedTypeArgs =>
640640
toText(tree.app) ~ Str("(with integrated type args)").provided(printDebug)

compiler/src/dotty/tools/dotc/quoted/QuoteContext.scala

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dotty.tools.dotc.quoted
2+
3+
import dotty.tools.dotc.core.Contexts._
4+
import dotty.tools.dotc.tastyreflect.ReflectionImpl
5+
6+
object Scope {
7+
8+
def apply()(using Context): scala.quoted.Scope =
9+
new Scope(ReflectionImpl(summon[Context]))
10+
11+
}
12+
13+
class Scope(val tasty: scala.tasty.Reflection) extends scala.quoted.Scope

0 commit comments

Comments
 (0)