From c2d092dcbbb1ecf93c923c4e4271734a108b3530 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 30 Jul 2021 10:45:45 +0200 Subject: [PATCH] Make Hole a proper Tree in Trees This is a first step into making the Hole trees Ycheckable. To YCheck them we need an untyped version of the tree. --- .../src/dotty/tools/dotc/ast/TreeTypeMap.scala | 1 - compiler/src/dotty/tools/dotc/ast/Trees.scala | 12 +++++++++++- compiler/src/dotty/tools/dotc/ast/tpd.scala | 2 +- .../tools/dotc/core/tasty/PositionPickler.scala | 2 +- .../dotty/tools/dotc/core/tasty/TreePickler.scala | 14 ++------------ .../tools/dotc/core/tasty/TreeUnpickler.scala | 4 ++-- .../dotty/tools/dotc/printing/RefinedPrinter.scala | 4 ++++ .../dotty/tools/dotc/quoted/PickledQuotes.scala | 1 - .../src/dotty/tools/dotc/transform/Inlining.scala | 1 - .../dotty/tools/dotc/transform/PickleQuotes.scala | 1 - .../src/dotty/tools/dotc/transform/Staging.scala | 1 - .../tools/dotc/transform/TreeMapWithStages.scala | 1 - 12 files changed, 21 insertions(+), 23 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala index f80d126bc471..d38ce8ca6888 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -7,7 +7,6 @@ import Types._, Contexts._, Flags._ import Symbols._, Annotations._, Trees._, Symbols._, Constants.Constant import Decorators._ import dotty.tools.dotc.transform.SymUtils._ -import core.tasty.TreePickler.Hole /** A map that applies three functions and a substitution together to a tree and * makes sure they are coordinated so that the result is well-typed. The functions are diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 5bb3b4ccbcc9..5bdd18705051 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -16,7 +16,6 @@ import annotation.internal.sharable import annotation.unchecked.uncheckedVariance import annotation.constructorOnly import Decorators._ -import dotty.tools.dotc.core.tasty.TreePickler.Hole object Trees { @@ -980,6 +979,15 @@ object Trees { def genericEmptyValDef[T >: Untyped]: ValDef[T] = theEmptyValDef.asInstanceOf[ValDef[T]] def genericEmptyTree[T >: Untyped]: Thicket[T] = theEmptyTree.asInstanceOf[Thicket[T]] + /** Tree that replaces a splice in pickled quotes. + * It is only used when picking quotes (Will never be in a TASTy file). + */ + case class Hole[-T >: Untyped](isTermHole: Boolean, idx: Int, args: List[Tree[T]])(implicit @constructorOnly src: SourceFile) extends Tree[T] { + type ThisTree[-T >: Untyped] <: Hole[T] + override def isTerm: Boolean = isTermHole + override def isType: Boolean = !isTermHole + } + def flatten[T >: Untyped](trees: List[Tree[T]]): List[Tree[T]] = { def recur(buf: ListBuffer[Tree[T]], remaining: List[Tree[T]]): ListBuffer[Tree[T]] = remaining match { @@ -1104,6 +1112,8 @@ object Trees { type Annotated = Trees.Annotated[T] type Thicket = Trees.Thicket[T] + type Hole = Trees.Hole[T] + @sharable val EmptyTree: Thicket = genericEmptyTree @sharable val EmptyValDef: ValDef = genericEmptyValDef @sharable val ContextualEmptyTree: Thicket = new EmptyTree() // an empty tree marking a contextual closure diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index cb68717f36cb..0c12eff2a0ae 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -44,7 +44,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def Apply(fn: Tree, args: List[Tree])(using Context): Apply = fn match case Block(Nil, expr) => Apply(expr, args) - case _: RefTree | _: GenericApply | _: Inlined | _: tasty.TreePickler.Hole => + case _: RefTree | _: GenericApply | _: Inlined | _: Hole => ta.assignType(untpd.Apply(fn, args), fn, args) def TypeApply(fn: Tree, args: List[Tree])(using Context): TypeApply = fn match diff --git a/compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala index 7181687d2a99..ad0c051e1b7b 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala @@ -91,7 +91,7 @@ class PositionPickler( | _: Trees.PackageDef[?] // holes can change source files when filled, which means // they might lose their position - | _: TreePickler.Hole => true + | _: Trees.Hole[?] => true case _ => false } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 96b028fafde0..1707d85b21f8 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -22,21 +22,11 @@ import annotation.constructorOnly import collection.mutable import dotty.tools.tasty.TastyFormat.ASTsSection -object TreePickler { - - case class Hole(isTermHole: Boolean, idx: Int, args: List[tpd.Tree])(implicit @constructorOnly src: SourceFile) extends tpd.Tree { - override def isTerm: Boolean = isTermHole - override def isType: Boolean = !isTermHole - override def fallbackToText(printer: Printer): Text = - if isTermHole then s"{{{ $idx |" ~~ printer.toTextGlobal(tpe) ~~ "|" ~~ printer.toTextGlobal(args, ", ") ~~ "}}}" - else s"[[[ $idx |" ~~ printer.toTextGlobal(tpe) ~~ "|" ~~ printer.toTextGlobal(args, ", ") ~~ "]]]" - } -} class TreePickler(pickler: TastyPickler) { val buf: TreeBuffer = new TreeBuffer pickler.newSection(ASTsSection, buf) - import TreePickler._ + // import TreePickler._ import buf._ import pickler.nameBuffer.nameIndex import tpd._ @@ -411,7 +401,7 @@ class TreePickler(pickler: TastyPickler) { var ename = tree.symbol.targetName val selectFromQualifier = name.isTypeName - || qual.isInstanceOf[TreePickler.Hole] // holes have no symbol + || qual.isInstanceOf[Hole] // holes have no symbol || sig == Signature.NotAMethod // no overload resolution necessary || !tree.denot.symbol.exists // polymorphic function type || tree.denot.asSingleDenotation.isRefinedMethod // refined methods have no defining class symbol diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 2853052eb0b7..cf6fc142b8af 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1290,7 +1290,7 @@ class TreeUnpickler(reader: TastyReader, val idx = readNat() val tpe = readType() val args = until(end)(readTerm()) - TreePickler.Hole(true, idx, args).withType(tpe) + Hole(true, idx, args).withType(tpe) case _ => readPathTerm() } @@ -1326,7 +1326,7 @@ class TreeUnpickler(reader: TastyReader, val idx = readNat() val tpe = readType() val args = until(end)(readTerm()) - TreePickler.Hole(false, idx, args).withType(tpe) + Hole(false, idx, args).withType(tpe) case _ => if (isTypeTreeTag(nextByte)) readTerm() else { diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index edaa1a7a3dbb..0bf825a6baa0 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -699,6 +699,10 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { "Thicket {" ~~ toTextGlobal(trees, "\n") ~~ "}" case MacroTree(call) => keywordStr("macro ") ~ toTextGlobal(call) + case Hole(isTermHole, idx, args) => + val (prefix, postfix) = if isTermHole then ("{{{ ", " }}}") else ("[[[ ", " ]]]") + val argsText = toTextGlobal(args, ", ") + prefix ~~ idx.toString ~~ "|" ~~ argsText ~~ postfix case _ => tree.fallbackToText(this) } diff --git a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala index c1ab1298dfd2..dd8f45401188 100644 --- a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala @@ -11,7 +11,6 @@ import dotty.tools.dotc.core.NameKinds import dotty.tools.dotc.core.Mode import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types._ -import dotty.tools.dotc.core.tasty.TreePickler.Hole import dotty.tools.dotc.core.tasty.{ PositionPickler, TastyPickler, TastyPrinter } import dotty.tools.dotc.core.tasty.DottyUnpickler import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode diff --git a/compiler/src/dotty/tools/dotc/transform/Inlining.scala b/compiler/src/dotty/tools/dotc/transform/Inlining.scala index 7b6a45ce3cda..84557a6501c1 100644 --- a/compiler/src/dotty/tools/dotc/transform/Inlining.scala +++ b/compiler/src/dotty/tools/dotc/transform/Inlining.scala @@ -11,7 +11,6 @@ import Constants._ import ast.Trees._ import ast.{TreeTypeMap, untpd} import util.Spans._ -import tasty.TreePickler.Hole import SymUtils._ import NameKinds._ import dotty.tools.dotc.ast.tpd diff --git a/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala b/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala index c62293e9b06e..be081c695c2d 100644 --- a/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala @@ -11,7 +11,6 @@ import Constants._ import ast.Trees._ import ast.{TreeTypeMap, untpd} import util.Spans._ -import tasty.TreePickler.Hole import SymUtils._ import NameKinds._ import dotty.tools.dotc.ast.tpd diff --git a/compiler/src/dotty/tools/dotc/transform/Staging.scala b/compiler/src/dotty/tools/dotc/transform/Staging.scala index 936fc22c5d71..b00506c602ad 100644 --- a/compiler/src/dotty/tools/dotc/transform/Staging.scala +++ b/compiler/src/dotty/tools/dotc/transform/Staging.scala @@ -12,7 +12,6 @@ import dotty.tools.dotc.core.NameKinds._ import dotty.tools.dotc.core.StagingContext._ import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.core.tasty.TreePickler.Hole import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.quoted._ import dotty.tools.dotc.util.{SourceFile, SrcPos} diff --git a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala index c8019bf5deb8..c4a3ead114b0 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala @@ -13,7 +13,6 @@ import dotty.tools.dotc.core.Contexts._ import dotty.tools.dotc.core.StagingContext._ import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.core.tasty.TreePickler.Hole import dotty.tools.dotc.quoted._ import dotty.tools.dotc.util.Spans._ import dotty.tools.dotc.util.Property