Skip to content

Commit 96379a7

Browse files
committed
Add scala.quoted.Scope
1 parent 539dd06 commit 96379a7

File tree

687 files changed

+3814
-4131
lines changed

Some content is hidden

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

687 files changed

+3814
-4131
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
@@ -908,7 +909,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
908909
* will return a type tree.
909910
*/
910911
def unapply(tree: tpd.Select)(using Context): Option[tpd.Tree] =
911-
if tree.symbol.isTypeSplice then Some(tree.qualifier) else None
912+
if tree.tpe.isTypeSplice || (tree.qualifier.tpe.widenTermRefExpr.typeSymbol == defn.ScopeTypeClass && tree.name == tpnme.spliceType) then Some(tree.qualifier)
913+
else None
912914
}
913915

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

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

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

795-
@tu lazy val LiftableModule: Symbol = requiredModule("scala.quoted.Liftable")
796-
@tu lazy val LiftableModule_BooleanIsLiftable: Symbol = LiftableModule.requiredMethod("BooleanIsLiftable")
797-
@tu lazy val LiftableModule_ByteIsLiftable: Symbol = LiftableModule.requiredMethod("ByteIsLiftable")
798-
@tu lazy val LiftableModule_ShortIsLiftable: Symbol = LiftableModule.requiredMethod("ShortIsLiftable")
799-
@tu lazy val LiftableModule_IntIsLiftable: Symbol = LiftableModule.requiredMethod("IntIsLiftable")
800-
@tu lazy val LiftableModule_LongIsLiftable: Symbol = LiftableModule.requiredMethod("LongIsLiftable")
801-
@tu lazy val LiftableModule_FloatIsLiftable: Symbol = LiftableModule.requiredMethod("FloatIsLiftable")
802-
@tu lazy val LiftableModule_DoubleIsLiftable: Symbol = LiftableModule.requiredMethod("DoubleIsLiftable")
803-
@tu lazy val LiftableModule_CharIsLiftable: Symbol = LiftableModule.requiredMethod("CharIsLiftable")
804-
@tu lazy val LiftableModule_StringIsLiftable: Symbol = LiftableModule.requiredMethod("StringIsLiftable")
793+
@tu lazy val ScopeClass: ClassSymbol = requiredClass("scala.quoted.Scope")
794+
@tu lazy val ScopeTypeModule: Symbol = ScopeClass.requiredMethod("Type")
795+
@tu lazy val ScopeTypeModule_apply: Symbol = ScopeTypeModule.requiredMethod(nme.apply)
796+
@tu lazy val ScopeExprClass: Symbol = ScopeClass.typeRef.select(tpnme.Expr).typeSymbol
797+
@tu lazy val ScopeTypeClass: Symbol = ScopeClass.typeRef.select(tpnme.Type).typeSymbol
798+
@tu lazy val Scope_Type_splice: Symbol = ScopeClass.typeRef.select(tpnme.Type).select(tpnme.spliceType).typeSymbol
805799

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

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

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

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
@@ -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/decompiler/DecompilationPrinter.scala

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

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

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,13 +15,14 @@ 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

1920
import dotty.tools.tasty.TastyString
2021

2122
import scala.reflect.ClassTag
2223

2324
import scala.internal.quoted.Unpickler._
24-
import scala.quoted.QuoteContext
25+
import scala.quoted.Scope
2526

2627
object PickledQuotes {
2728
import tpd._
@@ -30,25 +31,12 @@ object PickledQuotes {
3031
def pickleQuote(tree: Tree)(using Context): PickledQuote =
3132
if (ctx.reporter.hasErrors) Nil
3233
else {
33-
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`
3436
val pickled = pickle(tree)
3537
TastyString.pickle(pickled)
3638
}
3739

38-
/** Transform the expression into its fully spliced Tree */
39-
def quotedExprToTree[T](expr: quoted.Expr[T])(using Context): Tree = {
40-
val expr1 = expr.asInstanceOf[scala.internal.quoted.Expr[Tree]]
41-
QuoteContextImpl.checkScopeId(expr1.scopeId)
42-
healOwner(expr1.tree)
43-
}
44-
45-
/** Transform the expression into its fully spliced TypeTree */
46-
def quotedTypeToTree(tpe: quoted.Type[?])(using Context): Tree = {
47-
val tpe1 = tpe.asInstanceOf[scala.internal.quoted.Type[Tree]]
48-
QuoteContextImpl.checkScopeId(tpe1.scopeId)
49-
healOwner(tpe1.typeTree)
50-
}
51-
5240
/** Unpickle the tree contained in the TastyExpr */
5341
def unpickleExpr(tasty: PickledQuote, splices: PickledArgs)(using Context): Tree = {
5442
val tastyBytes = TastyString.unpickle(tasty)
@@ -75,13 +63,13 @@ object PickledQuotes {
7563
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match {
7664
case Hole(isTerm, idx, args) =>
7765
val reifiedArgs = args.map { arg =>
78-
if (arg.isTerm) (using qctx: QuoteContext) => new scala.internal.quoted.Expr(arg, QuoteContextImpl.scopeId)
79-
else new scala.internal.quoted.Type(arg, QuoteContextImpl.scopeId)
66+
if (arg.isTerm) (using scope: Scope) => arg
67+
else arg
8068
}
8169
if isTerm then
82-
val splice1 = splices(idx).asInstanceOf[Seq[Any] => QuoteContext ?=> quoted.Expr[?]]
83-
val quotedExpr = splice1(reifiedArgs)(using dotty.tools.dotc.quoted.QuoteContextImpl())
84-
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.ScopeImpl())
72+
val filled = PickledQuotes.healOwner(quotedExpr)
8573

8674
// We need to make sure a hole is created with the source file of the surrounding context, even if
8775
// it filled with contents a different source file.
@@ -90,8 +78,8 @@ object PickledQuotes {
9078
else
9179
// Replaces type holes generated by ReifyQuotes (non-spliced types).
9280
// These are types defined in a quote and used at the same level in a nested quote.
93-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](reifiedArgs)
94-
PickledQuotes.quotedTypeToTree(quotedType)
81+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => Tree](reifiedArgs)
82+
PickledQuotes.healOwner(quotedType)
9583
case tree: Select =>
9684
// Retain selected members
9785
val qual = transform(tree.qualifier)
@@ -133,8 +121,8 @@ object PickledQuotes {
133121
assert(tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot))
134122
val tree = tdef.rhs match
135123
case TypeBoundsTree(_, Hole(_, idx, args), _) =>
136-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](args)
137-
PickledQuotes.quotedTypeToTree(quotedType)
124+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => Tree](args)
125+
PickledQuotes.healOwner(quotedType)
138126
case TypeBoundsTree(_, tpt, _) =>
139127
tpt
140128
(tdef.symbol, tree.tpe)

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

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)