Skip to content

Commit d17cd16

Browse files
committed
Add scala.quoted.Scope
1 parent 01fc4a1 commit d17cd16

File tree

698 files changed

+3894
-4235
lines changed

Some content is hidden

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

698 files changed

+3894
-4235
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
import scala.collection.mutable
@@ -395,7 +396,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
395396
case New(_) | Closure(_, _, _) =>
396397
Pure
397398
case TypeApply(fn, _) =>
398-
if (fn.symbol.is(Erased) || fn.symbol == defn.QuotedTypeModule_apply || fn.symbol == defn.Predef_classOf) Pure else exprPurity(fn)
399+
if (fn.symbol.is(Erased) || fn.symbol == defn.ScopeTypeModule_apply || fn.symbol == defn.Predef_classOf) Pure else exprPurity(fn)
399400
case Apply(fn, args) =>
400401
def isKnownPureOp(sym: Symbol) =
401402
sym.owner.isPrimitiveValueClass
@@ -910,7 +911,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
910911
* will return a type tree.
911912
*/
912913
def unapply(tree: tpd.Select)(using Context): Option[tpd.Tree] =
913-
if tree.symbol.isTypeSplice then Some(tree.qualifier) else None
914+
if tree.tpe.isTypeSplice || (tree.qualifier.tpe.widenTermRefExpr.typeSymbol == defn.ScopeTypeClass && tree.name == tpnme.spliceType) then Some(tree.qualifier)
915+
else None
914916
}
915917

916918
/** 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
@@ -785,22 +785,16 @@ class Definitions {
785785
@tu lazy val ClassTagModule: Symbol = ClassTagClass.companionModule
786786
@tu lazy val ClassTagModule_apply: Symbol = ClassTagModule.requiredMethod(nme.apply)
787787

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

789-
@tu lazy val QuotedExprClass: ClassSymbol = requiredClass("scala.quoted.Expr")
790-
@tu lazy val QuotedExprModule: Symbol = QuotedExprClass.companionModule
791-
792-
@tu lazy val QuoteContextClass: ClassSymbol = requiredClass("scala.quoted.QuoteContext")
790+
@tu lazy val TastyReflectionClass: ClassSymbol = requiredClass("scala.tasty.Reflection")
793791

794-
@tu lazy val LiftableModule: Symbol = requiredModule("scala.quoted.Liftable")
795-
@tu lazy val LiftableModule_BooleanLiftable: Symbol = LiftableModule.requiredMethod("BooleanLiftable")
796-
@tu lazy val LiftableModule_ByteLiftable: Symbol = LiftableModule.requiredMethod("ByteLiftable")
797-
@tu lazy val LiftableModule_ShortLiftable: Symbol = LiftableModule.requiredMethod("ShortLiftable")
798-
@tu lazy val LiftableModule_IntLiftable: Symbol = LiftableModule.requiredMethod("IntLiftable")
799-
@tu lazy val LiftableModule_LongLiftable: Symbol = LiftableModule.requiredMethod("LongLiftable")
800-
@tu lazy val LiftableModule_FloatLiftable: Symbol = LiftableModule.requiredMethod("FloatLiftable")
801-
@tu lazy val LiftableModule_DoubleLiftable: Symbol = LiftableModule.requiredMethod("DoubleLiftable")
802-
@tu lazy val LiftableModule_CharLiftable: Symbol = LiftableModule.requiredMethod("CharLiftable")
803-
@tu lazy val LiftableModule_StringLiftable: Symbol = LiftableModule.requiredMethod("StringLiftable")
792+
@tu lazy val ScopeClass: ClassSymbol = requiredClass("scala.quoted.Scope")
793+
@tu lazy val ScopeTypeModule: Symbol = ScopeClass.requiredMethod("Type")
794+
@tu lazy val ScopeTypeModule_apply: Symbol = ScopeTypeModule.requiredMethod(nme.apply)
795+
@tu lazy val ScopeExprClass: Symbol = ScopeClass.typeRef.select(tpnme.Expr).typeSymbol
796+
@tu lazy val ScopeTypeClass: Symbol = ScopeClass.typeRef.select(tpnme.Type).typeSymbol
797+
@tu lazy val Scope_Type_splice: Symbol = ScopeClass.typeRef.select(tpnme.Type).select(tpnme.spliceType).typeSymbol
804798

805799
@tu lazy val InternalQuotedModule: Symbol = requiredModule("scala.internal.quoted.CompileTime")
806800
@tu lazy val InternalQuoted_exprQuote : Symbol = InternalQuotedModule.requiredMethod("exprQuote")
@@ -819,18 +813,19 @@ class Definitions {
819813
@tu lazy val InternalQuotedExpr_unapply: Symbol = InternalQuotedExprModule.requiredMethod(nme.unapply)
820814
@tu lazy val InternalQuotedExpr_null: Symbol = InternalQuotedExprModule.requiredMethod(nme.null_)
821815
@tu lazy val InternalQuotedExpr_unit: Symbol = InternalQuotedExprModule.requiredMethod(nme.Unit)
816+
@tu lazy val InternalQuotedExpr_liftBoolean: Symbol = InternalQuotedExprModule.requiredMethod("liftBoolean")
817+
@tu lazy val InternalQuotedExpr_liftByte: Symbol = InternalQuotedExprModule.requiredMethod("liftByte")
818+
@tu lazy val InternalQuotedExpr_liftShort: Symbol = InternalQuotedExprModule.requiredMethod("liftShort")
819+
@tu lazy val InternalQuotedExpr_liftInt: Symbol = InternalQuotedExprModule.requiredMethod("liftInt")
820+
@tu lazy val InternalQuotedExpr_liftLong: Symbol = InternalQuotedExprModule.requiredMethod("liftLong")
821+
@tu lazy val InternalQuotedExpr_liftFloat: Symbol = InternalQuotedExprModule.requiredMethod("liftFloat")
822+
@tu lazy val InternalQuotedExpr_liftDouble: Symbol = InternalQuotedExprModule.requiredMethod("liftDouble")
823+
@tu lazy val InternalQuotedExpr_liftChar: Symbol = InternalQuotedExprModule.requiredMethod("liftChar")
824+
@tu lazy val InternalQuotedExpr_liftString: Symbol = InternalQuotedExprModule.requiredMethod("liftString")
822825

823826
@tu lazy val InternalQuotedTypeModule: Symbol = requiredModule("scala.internal.quoted.Type")
824827
@tu lazy val InternalQuotedType_unapply: Symbol = InternalQuotedTypeModule.requiredMethod(nme.unapply)
825828

826-
@tu lazy val QuotedTypeClass: ClassSymbol = requiredClass("scala.quoted.Type")
827-
@tu lazy val QuotedType_splice: Symbol = QuotedTypeClass.requiredType(tpnme.spliceType)
828-
829-
@tu lazy val QuotedTypeModule: Symbol = QuotedTypeClass.companionModule
830-
@tu lazy val QuotedTypeModule_apply: Symbol = QuotedTypeModule.requiredMethod("apply")
831-
832-
@tu lazy val TastyReflectionClass: ClassSymbol = requiredClass("scala.tasty.Reflection")
833-
834829
@tu lazy val Unpickler_unpickleExpr: Symbol = requiredMethod("scala.internal.quoted.Unpickler.unpickleExpr")
835830
@tu lazy val Unpickler_unpickleType: Symbol = requiredMethod("scala.internal.quoted.Unpickler.unpickleType")
836831

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
@@ -582,7 +582,7 @@ object StdNames {
582582
val setSymbol: N = "setSymbol"
583583
val setType: N = "setType"
584584
val setTypeSignature: N = "setTypeSignature"
585-
val spliceType: N = "T"
585+
val spliceType: N = "X"
586586
val standardInterpolator: N = "standardInterpolator"
587587
val staticClass : N = "staticClass"
588588
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/tasty/TreePickler.scala

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

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

compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import scala.io.Codec
99
import dotty.tools.dotc.core.Contexts._
1010
import dotty.tools.dotc.core.Phases.Phase
1111
import dotty.tools.dotc.core.tasty.TastyPrinter
12-
import dotty.tools.dotc.quoted.QuoteContextImpl
12+
import dotty.tools.dotc.quoted.ScopeImpl
1313
import dotty.tools.io.File
1414

1515
/** Phase that prints the trees in all loaded compilation units.
@@ -44,7 +44,7 @@ class DecompilationPrinter extends Phase {
4444
else {
4545
val unitFile = unit.source.toString.replace("\\", "/").replace(".class", ".tasty")
4646
out.println(s"/** Decompiled from $unitFile */")
47-
out.println(QuoteContextImpl.showTree(unit.tpdTree))
47+
out.println(ScopeImpl.showTree(unit.tpdTree))
4848
}
4949
}
5050
}

compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import dotty.tools.dotc.core.Contexts._
66
import dotty.tools.dotc.core._
77
import dotty.tools.dotc.core.tasty.TastyHTMLPrinter
88
import dotty.tools.dotc.reporting._
9-
import dotty.tools.dotc.quoted.QuoteContextImpl
9+
import dotty.tools.dotc.quoted.ScopeImpl
1010

1111
/**
1212
* Decompiler to be used with IDEs
@@ -34,7 +34,7 @@ class IDEDecompilerDriver(val settings: List[String]) extends dotc.Driver {
3434
run.printSummary()
3535
val unit = ctx.run.units.head
3636

37-
val decompiled = QuoteContextImpl.showTree(unit.tpdTree)
37+
val decompiled = ScopeImpl.showTree(unit.tpdTree)
3838
val tree = new TastyHTMLPrinter(unit.pickled.head._2()).printContents()
3939

4040
reporter.removeBufferedMessages.foreach(message => System.err.println(message))

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

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

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

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ 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.ScopeImpl
1819
import dotty.tools.dotc.report
1920

2021
import dotty.tools.tasty.TastyString
2122

2223
import scala.reflect.ClassTag
2324

2425
import scala.internal.quoted.Unpickler._
25-
import scala.quoted.QuoteContext
2626
import scala.collection.mutable
27+
import scala.quoted.Scope
2728

2829
object PickledQuotes {
2930
import tpd._
@@ -32,25 +33,12 @@ object PickledQuotes {
3233
def pickleQuote(tree: Tree)(using Context): PickledQuote =
3334
if (ctx.reporter.hasErrors) Nil
3435
else {
35-
assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'{$x}` which should be optimized to `x`
36+
// FIXME re-enable
37+
// assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'{$x}` which should be optimized to `x`
3638
val pickled = pickle(tree)
3739
TastyString.pickle(pickled)
3840
}
3941

40-
/** Transform the expression into its fully spliced Tree */
41-
def quotedExprToTree[T](expr: quoted.Expr[T])(using Context): Tree = {
42-
val expr1 = expr.asInstanceOf[scala.internal.quoted.Expr[Tree]]
43-
QuoteContextImpl.checkScopeId(expr1.scopeId)
44-
healOwner(expr1.tree)
45-
}
46-
47-
/** Transform the expression into its fully spliced TypeTree */
48-
def quotedTypeToTree(tpe: quoted.Type[?])(using Context): Tree = {
49-
val tpe1 = tpe.asInstanceOf[scala.internal.quoted.Type[Tree]]
50-
QuoteContextImpl.checkScopeId(tpe1.scopeId)
51-
healOwner(tpe1.typeTree)
52-
}
53-
5442
/** Unpickle the tree contained in the TastyExpr */
5543
def unpickleExpr(tasty: PickledQuote, splices: PickledArgs)(using Context): Tree = {
5644
val tastyBytes = TastyString.unpickle(tasty)
@@ -77,13 +65,13 @@ object PickledQuotes {
7765
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match {
7866
case Hole(isTerm, idx, args) =>
7967
val reifiedArgs = args.map { arg =>
80-
if (arg.isTerm) (using qctx: QuoteContext) => new scala.internal.quoted.Expr(arg, QuoteContextImpl.scopeId)
81-
else new scala.internal.quoted.Type(arg, QuoteContextImpl.scopeId)
68+
if (arg.isTerm) (using scope: Scope) => arg
69+
else arg
8270
}
8371
if isTerm then
84-
val splice1 = splices(idx).asInstanceOf[Seq[Any] => QuoteContext ?=> quoted.Expr[?]]
85-
val quotedExpr = splice1(reifiedArgs)(using dotty.tools.dotc.quoted.QuoteContextImpl())
86-
val filled = PickledQuotes.quotedExprToTree(quotedExpr)
72+
val splice1 = splices(idx).asInstanceOf[Seq[Any] => scala.quoted.Scope ?=> Tree]
73+
val quotedExpr = splice1(reifiedArgs)(using dotty.tools.dotc.quoted.ScopeImpl())
74+
val filled = PickledQuotes.healOwner(quotedExpr)
8775

8876
// We need to make sure a hole is created with the source file of the surrounding context, even if
8977
// it filled with contents a different source file.
@@ -92,8 +80,8 @@ object PickledQuotes {
9280
else
9381
// Replaces type holes generated by ReifyQuotes (non-spliced types).
9482
// These are types defined in a quote and used at the same level in a nested quote.
95-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](reifiedArgs)
96-
PickledQuotes.quotedTypeToTree(quotedType)
83+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => Tree](reifiedArgs)
84+
PickledQuotes.healOwner(quotedType)
9785
case tree: Select =>
9886
// Retain selected members
9987
val qual = transform(tree.qualifier)
@@ -135,8 +123,8 @@ object PickledQuotes {
135123
assert(tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot))
136124
val tree = tdef.rhs match
137125
case TypeBoundsTree(_, Hole(_, idx, args), _) =>
138-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](args)
139-
PickledQuotes.quotedTypeToTree(quotedType)
126+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => Tree](args)
127+
PickledQuotes.healOwner(quotedType)
140128
case TypeBoundsTree(_, tpt, _) =>
141129
tpt
142130
(tdef.symbol, tree.tpe)

0 commit comments

Comments
 (0)