From c79ab34c168df9ac0fcb540423929f417087f07f Mon Sep 17 00:00:00 2001 From: bishabosha Date: Sat, 30 Nov 2019 16:48:55 +0100 Subject: [PATCH 1/8] add experimental interface, disable scala2 compat --- build.sbt | 2 +- community-build/community-projects/ScalaPB | 2 +- community-build/community-projects/fastparse | 2 +- community-build/community-projects/os-lib | 2 +- community-build/community-projects/scalacheck | 2 +- community-build/community-projects/shapeless | 1 - community-build/community-projects/sourcecode | 2 +- community-build/community-projects/utest | 2 +- .../community-projects/xml-interpolator | 2 +- project/Build.scala | 12 +- .../tools/tasty/experimental/NameBuffer.scala | 106 +++ .../tools/tasty/experimental/Tasty.scala | 18 + .../tasty/experimental/TastyPickler.scala | 81 ++ .../tools/tasty/experimental/TreeBuffer.scala | 190 +++++ .../tasty/experimental/TreePickler.scala | 715 ++++++++++++++++++ .../experimental/UnpickleException.scala | 3 + .../experimental/bridge/AnnotationOps.scala | 15 + .../experimental/bridge/ConstantOps.scala | 35 + .../experimental/bridge/ContextOps.scala | 10 + .../tasty/experimental/bridge/Core.scala | 109 +++ .../tasty/experimental/bridge/FlagOps.scala | 62 ++ .../tasty/experimental/bridge/NameOps.scala | 49 ++ .../experimental/bridge/PositionOps.scala | 8 + .../experimental/bridge/PrintingOps.scala | 13 + .../experimental/bridge/SignatureOps.scala | 24 + .../tasty/experimental/bridge/StringOps.scala | 11 + .../tasty/experimental/bridge/SymbolOps.scala | 55 ++ .../experimental/bridge/TastyKernel.scala | 467 ++++++++++++ .../tasty/experimental/bridge/TreeOps.scala | 168 ++++ .../tasty/experimental/bridge/TypeOps.scala | 112 +++ .../experimental/function/IntToInt.scala | 5 + .../tasty/experimental/function/ToInt.scala | 5 + .../tools/tasty/experimental/util/Util.scala | 14 + 33 files changed, 2289 insertions(+), 15 deletions(-) delete mode 160000 community-build/community-projects/shapeless create mode 100644 tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/Tasty.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/TreePickler.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/UnpickleException.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/PrintingOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/function/IntToInt.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/function/ToInt.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/util/Util.scala diff --git a/build.sbt b/build.sbt index 54f8fe6bd63a..3f8d2490a530 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,7 @@ val `dotty-bench` = Build.`dotty-bench` val `dotty-bench-bootstrapped` = Build.`dotty-bench-bootstrapped` val `tasty-core` = Build.`tasty-core` val `tasty-core-bootstrapped` = Build.`tasty-core-bootstrapped` -val `tasty-core-scala2` = Build.`tasty-core-scala2` +// val `tasty-core-scala2` = Build.`tasty-core-scala2` val `dotty-tastydoc` = Build.`dotty-tastydoc` val `dotty-tastydoc-input` = Build.`dotty-tastydoc-input` val `dotty-bench-run` = Build.`dotty-bench-run` diff --git a/community-build/community-projects/ScalaPB b/community-build/community-projects/ScalaPB index 984eba1d17a9..2b2af046cc98 160000 --- a/community-build/community-projects/ScalaPB +++ b/community-build/community-projects/ScalaPB @@ -1 +1 @@ -Subproject commit 984eba1d17a9371e166fd76f89880590d8f5bfa5 +Subproject commit 2b2af046cc98c5fe440777f2b8258280919a5079 diff --git a/community-build/community-projects/fastparse b/community-build/community-projects/fastparse index c49998f74aa0..2b26ee9a89af 160000 --- a/community-build/community-projects/fastparse +++ b/community-build/community-projects/fastparse @@ -1 +1 @@ -Subproject commit c49998f74aa05f27720eab974f25c3ee780f3549 +Subproject commit 2b26ee9a89af1c033f9c6b6d731cee440adb342b diff --git a/community-build/community-projects/os-lib b/community-build/community-projects/os-lib index 9cb5d0eb4bf2..b29d68ffee5a 160000 --- a/community-build/community-projects/os-lib +++ b/community-build/community-projects/os-lib @@ -1 +1 @@ -Subproject commit 9cb5d0eb4bf20a5b4ef86a7bf55cc896719f887e +Subproject commit b29d68ffee5a6e0aedbfdd048d10059f250134e4 diff --git a/community-build/community-projects/scalacheck b/community-build/community-projects/scalacheck index 9c5fc6e36970..371113633e8b 160000 --- a/community-build/community-projects/scalacheck +++ b/community-build/community-projects/scalacheck @@ -1 +1 @@ -Subproject commit 9c5fc6e36970c704fb431f56eaaf4a3fea4b1f9c +Subproject commit 371113633e8b0ee140a4addb66526ae0e71e7118 diff --git a/community-build/community-projects/shapeless b/community-build/community-projects/shapeless deleted file mode 160000 index 63c5e0a4c57e..000000000000 --- a/community-build/community-projects/shapeless +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 63c5e0a4c57efbaf17699144b627db1639800e90 diff --git a/community-build/community-projects/sourcecode b/community-build/community-projects/sourcecode index db11447fd045..49c20bd80cb6 160000 --- a/community-build/community-projects/sourcecode +++ b/community-build/community-projects/sourcecode @@ -1 +1 @@ -Subproject commit db11447fd045125b84a69832b2b6c5f9cd3290de +Subproject commit 49c20bd80cb61a53c0b11e80b9946bbe513a4c0f diff --git a/community-build/community-projects/utest b/community-build/community-projects/utest index 7eac23c8aad1..4953683a23fe 160000 --- a/community-build/community-projects/utest +++ b/community-build/community-projects/utest @@ -1 +1 @@ -Subproject commit 7eac23c8aad186c724ddaee4d00030fbacb8a969 +Subproject commit 4953683a23fe8f60f8f25f061a7b3095f8ddbeac diff --git a/community-build/community-projects/xml-interpolator b/community-build/community-projects/xml-interpolator index f3185019a161..435d9e076531 160000 --- a/community-build/community-projects/xml-interpolator +++ b/community-build/community-projects/xml-interpolator @@ -1 +1 @@ -Subproject commit f3185019a16182a2fba20523ccfff6665436424a +Subproject commit 435d9e076531555ebc5bac8f196645a157bc6c11 diff --git a/project/Build.scala b/project/Build.scala index 97db49daf957..747e0c1c662f 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -782,15 +782,15 @@ object Build { ) lazy val tastyCoreSettings = Seq( - scalacOptions ~= { old => - val (language, other) = old.partition(_.startsWith("-language:")) - other :+ (language.headOption.map(_ + ",Scala2Compat").getOrElse("-language:Scala2Compat")) - } + // scalacOptions ~= { old => + // val (language, other) = old.partition(_.startsWith("-language:")) + // other :+ (language.headOption.map(_ + ",Scala2Compat").getOrElse("-language:Scala2Compat")) + // } ) lazy val `tasty-core` = project.in(file("tasty")).asTastyCore(NonBootstrapped) lazy val `tasty-core-bootstrapped`: Project = project.in(file("tasty")).asTastyCore(Bootstrapped) - lazy val `tasty-core-scala2`: Project = project.in(file("tasty")).asTastyCoreScala2 + // lazy val `tasty-core-scala2`: Project = project.in(file("tasty")).asTastyCoreScala2 def tastyCore(implicit mode: Mode): Project = mode match { case NonBootstrapped => `tasty-core` @@ -1348,7 +1348,7 @@ object Build { dependsOn(dottyLibrary). settings(tastyCoreSettings) - def asTastyCoreScala2: Project = project.settings(commonScala2Settings) + // def asTastyCoreScala2: Project = project.settings(commonScala2Settings) def asDottyDoc(implicit mode: Mode): Project = project.withCommonSettings. dependsOn(dottyCompiler, dottyCompiler % "test->test"). diff --git a/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala new file mode 100644 index 000000000000..9519aaf3da2c --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala @@ -0,0 +1,106 @@ +package dotty.tools.tasty.experimental + +import collection.mutable + +import dotty.tools.tasty._ + +import TastyBuffer._ +import scala.io.Codec + +class NameBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(10000) { + import tasty.{_, given} + import NameBuffer._ + + private val nameRefs = new mutable.LinkedHashMap[Name, NameRef] + + def nameIndex(name: Name): NameRef = { + val name1 = name.toTermName + nameRefs.get(name1) match { + case Some(ref) => + ref + case None => + name1 match { + case SignedName(original, Signature(params, result)) => + nameIndex(original) + nameIndex(result) + params.foreach { + case param: TypeName => + nameIndex(param) + case _ => + } + case AnyQualifiedName(prefix, name) => + nameIndex(prefix); nameIndex(name) + case AnyUniqueName(original, separator, num) => + nameIndex(separator.toTermName) + if (!original.isEmpty) nameIndex(original) + case DerivedName(original) => + nameIndex(original) + case _ => + } + val ref = NameRef(nameRefs.size) + nameRefs(name1) = ref + ref + } + } + + private def withLength(op: => Unit, lengthWidth: Int = 1): Unit = { + val lengthAddr = currentAddr + for (i <- 0 until lengthWidth) writeByte(0) + op + val length = currentAddr.index - lengthAddr.index - lengthWidth + putNat(lengthAddr, length, lengthWidth) + } + + def writeNameRef(ref: NameRef): Unit = writeNat(ref.index) + def writeNameRef(name: Name): Unit = writeNameRef(nameRefs(name.toTermName)) + + def writeParamSig(paramSig: Signature.ParamSig): Unit = { + val encodedValue = paramSig.foldInt( + paramSig => -paramSig, + paramSig => nameRefs(paramSig.toTermName).index + ) + writeInt(encodedValue) + } + + def pickleNameContents(name: Name): Unit = { + val tag = name.toTermName.tag + writeByte(tag) + name.toTermName match { + case name: SimpleName => + val bytes = name.toUTF8 + writeNat(bytes.length) + writeBytes(bytes, bytes.length) + case AnyQualifiedName(prefix, name) => + withLength { writeNameRef(prefix); writeNameRef(name) } + case AnyUniqueName(original, separator, num) => + withLength { + writeNameRef(separator.toTermName) + writeNat(num) + if (!original.isEmpty) writeNameRef(original) + } + case AnyNumberedName(original, num) => + withLength { writeNameRef(original); writeNat(num) } + case SignedName(original, Signature(paramsSig, result)) => + withLength( + { writeNameRef(original); writeNameRef(result); paramsSig.foreach(writeParamSig) }, + if ((paramsSig.length + 2) * maxIndexWidth <= maxNumInByte) 1 else 2) + case DerivedName(original) => + withLength { writeNameRef(original) } + } + } + + override def assemble(): Unit = { + var i = 0 + for ((name, ref) <- nameRefs) { + assert(ref.index == i) + i += 1 + pickleNameContents(name) + } + } +} + +object NameBuffer { + private val maxIndexWidth = 3 // allows name indices up to 2^21. + private val payloadBitsPerByte = 7 // determined by nat encoding in TastyBuffer + private val maxNumInByte = (1 << payloadBitsPerByte) - 1 +} diff --git a/tasty/src/dotty/tools/tasty/experimental/Tasty.scala b/tasty/src/dotty/tools/tasty/experimental/Tasty.scala new file mode 100644 index 000000000000..36eb8a7ab91c --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/Tasty.scala @@ -0,0 +1,18 @@ +package dotty.tools.tasty.experimental + +import bridge._ +import reflect.ClassTag + +trait Tasty extends Core + with NameOps + with SignatureOps + with TreeOps + with ConstantOps + with ContextOps + with TypeOps + with SymbolOps + with StringOps + with PrintingOps + with AnnotationOps + with FlagOps + with PositionOps diff --git a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala new file mode 100644 index 000000000000..cdc2518c4486 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala @@ -0,0 +1,81 @@ +package dotty.tools.tasty.experimental + +import collection.mutable + +import dotty.tools.tasty.{TastyFormat, TastyBuffer, TastyHash} +import TastyFormat._ +import TastyBuffer._ + +class TastyPickler[T <: Tasty](given val tasty: T) { self => + import tasty.{_, given} + + var _rootCls: ClassSymbol = _ + def rootCls: ClassSymbol = _rootCls + def rootCls_=(rootCls: ClassSymbol) = _rootCls = rootCls + + private val sections = mutable.ArrayBuffer.empty[(NameRef, TastyBuffer)] + + val nameBuffer = NameBuffer[tasty.type]() + + def newSection(name: String, buf: TastyBuffer): Unit = + sections += ((nameBuffer.nameIndex(name.toTermName), buf)) + + def assembleParts(): Array[Byte] = { + def lengthWithLength(buf: TastyBuffer) = + buf.length + natSize(buf.length) + + nameBuffer.assemble() + sections.foreach(_._2.assemble()) + + val nameBufferHash = TastyHash.pjwHash64(nameBuffer.bytes) + val treeSectionHash +: otherSectionHashes = sections.map(x => TastyHash.pjwHash64(x._2.bytes)) + + // Hash of name table and tree + val uuidLow: Long = nameBufferHash ^ treeSectionHash + // Hash of positions, comments and any additional section + val uuidHi: Long = otherSectionHashes.fold(0L)(_ ^ _) + + val headerBuffer = { + val buf = new TastyBuffer(header.length + 24) + for (ch <- header) buf.writeByte(ch.toByte.toInt) + buf.writeNat(MajorVersion) + buf.writeNat(MinorVersion) + buf.writeUncompressedLong(uuidLow) + buf.writeUncompressedLong(uuidHi) + buf + } + + val totalSize = + headerBuffer.length + + lengthWithLength(nameBuffer) + { + for ((nameRef, buf) <- sections) yield + natSize(nameRef.index) + lengthWithLength(buf) + }.sum + val all = new TastyBuffer(totalSize) + all.writeBytes(headerBuffer.bytes, headerBuffer.length) + all.writeNat(nameBuffer.length) + all.writeBytes(nameBuffer.bytes, nameBuffer.length) + for ((nameRef, buf) <- sections) { + all.writeNat(nameRef.index) + all.writeNat(buf.length) + all.writeBytes(buf.bytes, buf.length) + } + assert(all.length == totalSize && all.bytes.length == totalSize, s"totalSize = $totalSize, all.length = ${all.length}, all.bytes.length = ${all.bytes.length}") + all.bytes + } + + /** The address in the TASTY file of a given tree, or None if unknown. + * Note that trees are looked up by reference equality, + * so one can reliably use this function only directly after `pickler`. + */ + var addrOfTree: Tree => Addr = (_ => NoAddr) + + /** + * Addresses in TASTY file of symbols, stored by pickling. + * Note that trees are checked for reference equality, + * so one can reliably use this function only dirrectly after `pickler` + */ + var addrOfSym: Symbol => Option[Addr] = (_ => None) + + // val treePkl: TreePickler = new TreePickler(this) +} diff --git a/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala new file mode 100644 index 000000000000..e995f24ae471 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala @@ -0,0 +1,190 @@ +package dotty.tools.tasty.experimental + +import dotty.tools.tasty.util.Util.{dble} +import dotty.tools.tasty.TastyBuffer +import dotty.tools.tasty.TastyBuffer.{Addr, NoAddr, AddrWidth} + +import util.Util.bestFit + +class TreeBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(50000) { + import tasty.{_, given} + import Printers.pickling + + private final val ItemsOverOffsets = 2 + private val initialOffsetSize = bytes.length / (AddrWidth * ItemsOverOffsets) + private var offsets = new Array[Int](initialOffsetSize) + private var isRelative = new Array[Boolean](initialOffsetSize) + private var delta: Array[Int] = _ + private var numOffsets = 0 + + /** A map from trees to the address at which a tree is pickled. */ + private val treeAddrs = new java.util.IdentityHashMap[untpd.Tree, Addr | Null] + + def registerTreeAddr(tree: untpd.Tree): Addr = treeAddrs.get(tree) match { + case null => treeAddrs.put(tree, currentAddr); currentAddr + case addr: Addr => addr + } + + def addrOfTree(tree: Tree): Addr = treeAddrs.get(tree) match { + case null => NoAddr + case addr: Addr => addr + } + + private def offset(i: Int): Addr = Addr(offsets(i)) + + private def keepOffset(relative: Boolean): Unit = { + if (numOffsets == offsets.length) { + offsets = dble(offsets) + isRelative = dble(isRelative) + } + offsets(numOffsets) = length + isRelative(numOffsets) = relative + numOffsets += 1 + } + + /** Reserve space for a reference, to be adjusted later */ + def reserveRef(relative: Boolean): Addr = { + val addr = currentAddr + keepOffset(relative) + reserveAddr() + addr + } + + /** Write reference right adjusted into freshly reserved field. */ + def writeRef(target: Addr): Unit = { + keepOffset(relative = false) + fillAddr(reserveAddr(), target) + } + + /** Fill previously reserved field with a reference */ + def fillRef(at: Addr, target: Addr, relative: Boolean): Unit = { + val addr = if (relative) target.relativeTo(at) else target + fillAddr(at, addr) + } + + /** The amount by which the bytes at the given address are shifted under compression */ + def deltaAt(at: Addr): Int = { + val idx = bestFit(offsets, numOffsets, at.index - 1) + if (idx < 0) 0 else delta(idx) + } + + /** The address to which `x` is translated under compression */ + def adjusted(x: Addr): Addr = x - deltaAt(x) + + /** Compute all shift-deltas */ + private def computeDeltas() = { + delta = new Array[Int](numOffsets) + var lastDelta = 0 + var i = 0 + while (i < numOffsets) { + val off = offset(i) + val skippedOff = skipZeroes(off) + val skippedCount = skippedOff.index - off.index + assert(skippedCount < AddrWidth, s"unset field at position $off") + lastDelta += skippedCount + delta(i) = lastDelta + i += 1 + } + } + + /** The absolute or relative adjusted address at index `i` of `offsets` array*/ + private def adjustedOffset(i: Int): Addr = { + val at = offset(i) + val original = getAddr(at) + if (isRelative(i)) { + val start = skipNat(at) + val len1 = original + delta(i) - deltaAt(original + start.index) + val len2 = adjusted(original + start.index) - adjusted(start).index + assert(len1 == len2, + s"adjusting offset #$i: $at, original = $original, len1 = $len1, len2 = $len2") + len1 + } + else adjusted(original) + } + + /** Adjust all offsets according to previously computed deltas */ + private def adjustOffsets(): Unit = + for (i <- 0 until numOffsets) { + val corrected = adjustedOffset(i) + fillAddr(offset(i), corrected) + } + + /** Adjust deltas to also take account references that will shrink (and thereby + * generate additional zeroes that can be skipped) due to previously + * computed adjustments. + */ + private def adjustDeltas(): Int = { + val delta1 = new Array[Int](delta.length) + var lastDelta = 0 + var i = 0 + while (i < numOffsets) { + val corrected = adjustedOffset(i) + lastDelta += AddrWidth - TastyBuffer.natSize(corrected.index) + delta1(i) = lastDelta + i += 1 + } + val saved = + if (numOffsets == 0) 0 + else delta1(numOffsets - 1) - delta(numOffsets - 1) + delta = delta1 + saved + } + + /** Compress pickle buffer, shifting bytes to close all skipped zeroes. */ + private def compress(): Int = { + var lastDelta = 0 + var start = 0 + var i = 0 + var wasted = 0 + def shift(end: Int) = + System.arraycopy(bytes, start, bytes, start - lastDelta, end - start) + while (i < numOffsets) { + val next = offsets(i) + shift(next) + start = next + delta(i) - lastDelta + val pastZeroes = skipZeroes(Addr(next)).index + assert(pastZeroes >= start, s"something's wrong: eliminated non-zero") + wasted += (pastZeroes - start) + lastDelta = delta(i) + i += 1 + } + shift(length) + length -= lastDelta + wasted + } + + def adjustTreeAddrs(): Unit = { + val it = treeAddrs.keySet.iterator + while (it.hasNext) { + val tree = it.next + treeAddrs.get(tree) match { + case addr: Addr => treeAddrs.put(tree, adjusted(addr)) + case null => () + } + } + } + + /** Final assembly, involving the following steps: + * - compute deltas + * - adjust deltas until additional savings are < 1% of total + * - adjust offsets according to the adjusted deltas + * - shrink buffer, skipping zeroes. + */ + def compactify(): Unit = { + val origLength = length + computeDeltas() + //println(s"offsets: ${offsets.take(numOffsets).deep}") + //println(s"deltas: ${delta.take(numOffsets).deep}") + var saved = 0 + while ({ + saved = adjustDeltas() + pickling.println(s"adjusting deltas, saved = $saved") + saved > 0 && length / saved < 100 + }) + () + adjustOffsets() + adjustTreeAddrs() + val wasted = compress() + pickling.println(s"original length: $origLength, compressed to: $length, wasted: $wasted") // DEBUG, for now. + } +} diff --git a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala new file mode 100644 index 000000000000..fd26389f6ed5 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala @@ -0,0 +1,715 @@ +package dotty.tools.tasty.experimental + +import dotty.tools.tasty.TastyFormat._ +import dotty.tools.tasty.TastyBuffer._ + +import annotation.constructorOnly + +object TreePickler { + val sectionName = "ASTs" +} + +class TreePickler(given val tasty: Tasty)(pickler: TastyPickler[tasty.type]) { + import tasty.{_, given} + val buf = TreeBuffer[tasty.type]() + pickler.newSection(TreePickler.sectionName, buf) + import TreePickler._ + import buf._ + import pickler.nameBuffer.nameIndex + import Constants._ + import Symbols.{_,given} + + private val symRefs = Symbols.newMutableSymbolMap[Addr] + private val forwardSymRefs = Symbols.newMutableSymbolMap[List[Addr]] + private val pickledTypes = new java.util.IdentityHashMap[Type, Any] // Value type is really Addr, but that's not compatible with null + + private def withLength(op: => Unit) = { + val lengthAddr = reserveRef(relative = true) + op + fillRef(lengthAddr, currentAddr, relative = true) + } + + def addrOfSym(sym: Symbol): Option[Addr] = + symRefs.get(sym) + + def preRegister(tree: Tree)(implicit ctx: Context): Unit = tree match { + case tree: MemberDef => + if (!symRefs.contains(tree.symbol)) symRefs(tree.symbol) = NoAddr + case _ => + } + + def registerDef(sym: Symbol): Unit = { + symRefs(sym) = currentAddr + forwardSymRefs.get(sym) match { + case Some(refs) => + refs.foreach(fillRef(_, currentAddr, relative = false)) + forwardSymRefs -= sym + case None => + } + } + + def pickleName(name: Name): Unit = writeNat(nameIndex(name).index) + + private def pickleNameAndSig(name: Name, sig: Signature): Unit = + pickleName(if sig.isNotAMethod then name else SignedName(name.toTermName, sig)) + + private def pickleSymRef(sym: Symbol)(implicit ctx: Context) = symRefs.get(sym) match { + case Some(label) => + if (label != NoAddr) writeRef(label) else pickleForwardSymRef(sym) + case None => + // See pos/t1957.scala for an example where this can happen. + // I believe it's a bug in typer: the type of an implicit argument refers + // to a closure parameter outside the closure itself. TODO: track this down, so that we + // can eliminate this case. + ctx.log(i"pickling reference to as yet undefined $sym in ${sym.owner}", sym.sourcePos) + pickleForwardSymRef(sym) + } + + private def pickleForwardSymRef(sym: Symbol)(implicit ctx: Context) = { + val ref = reserveRef(relative = false) + assert(!sym.isPackage, sym) + forwardSymRefs(sym) = ref :: forwardSymRefs.getOrElse(sym, Nil) + } + + private def isLocallyDefined(sym: Symbol)(implicit ctx: Context) = + sym.isDefinedWithin(pickler.rootCls) // sym.topLevelClass.isLinkedWith(pickler.rootCls) + + def pickleConstant(c: Constant)(implicit ctx: Context): Unit = c.tag match { + case UnitTag => + writeByte(UNITconst) + case BooleanTag => + writeByte(if (c.booleanValue) TRUEconst else FALSEconst) + case ByteTag => + writeByte(BYTEconst) + writeInt(c.byteValue.toInt) + case ShortTag => + writeByte(SHORTconst) + writeInt(c.shortValue.toInt) + case CharTag => + writeByte(CHARconst) + writeNat(c.charValue.toInt) + case IntTag => + writeByte(INTconst) + writeInt(c.intValue) + case LongTag => + writeByte(LONGconst) + writeLongInt(c.longValue) + case FloatTag => + writeByte(FLOATconst) + writeInt(java.lang.Float.floatToRawIntBits(c.floatValue)) + case DoubleTag => + writeByte(DOUBLEconst) + writeLongInt(java.lang.Double.doubleToRawLongBits(c.doubleValue)) + case StringTag => + writeByte(STRINGconst) + pickleName(c.stringValue.toTermName) + case NullTag => + writeByte(NULLconst) + case ClazzTag => + writeByte(CLASSconst) + pickleType(c.typeValue) + case EnumTag => + writeByte(ENUMconst) + pickleType(c.symbolValue.termRef) + case _ => + } + + def pickleType(tpe0: Type, richTypes: Boolean = false)(implicit ctx: Context): Unit = { + val tpe = tpe0.stripTypeVar + try { + val prev = pickledTypes.get(tpe) + if (prev == null) { + pickledTypes.put(tpe, currentAddr) + pickleNewType(tpe, richTypes) + } + else { + writeByte(SHAREDtype) + writeRef(prev.asInstanceOf[Addr]) + } + } + catch { + case ex: AssertionError => + println(i"error when pickling type $tpe") + throw ex + } + } + + private def pickleNewType(tpe: Type, richTypes: Boolean)(implicit ctx: Context): Unit = tpe match { + case AppliedType(tycon, args) => + writeByte(APPLIEDtype) + withLength { pickleType(tycon); args.foreach(pickleType(_)) } + case tpe: ConstantType => + pickleConstant(tpe.value) + case tpe: NamedType => + val sym = tpe.symbol + def pickleExternalRef(sym: Symbol) = { + def pickleCore() = { + pickleNameAndSig(sym.name, tpe.signature) + pickleType(tpe.prefix) + } + val isShadowedRef = + sym.isClass && tpe.prefix.member(sym.name)/*.symbol*/ != sym + if (sym.isPrivate || isShadowedRef) { + writeByte(if (tpe.isType) TYPEREFin else TERMREFin) + withLength { + pickleCore() + pickleType(sym.owner.typeRef) + } + } + else { + writeByte(if (tpe.isType) TYPEREF else TERMREF) + pickleCore() + } + } + if (sym.isPackage) { + writeByte(if (tpe.isType) TYPEREFpkg else TERMREFpkg) + pickleName(sym.fullName) + } + else if (tpe.hasNoPrefix) { + writeByte(if (tpe.isType) TYPEREFdirect else TERMREFdirect) + pickleSymRef(sym) + } + else tpe.designator match { + case name: Name => + writeByte(if (tpe.isType) TYPEREF else TERMREF) + pickleName(name); pickleType(tpe.prefix) + case sym: Symbol => + if (isLocallyDefined(sym)) { + writeByte(if (tpe.isType) TYPEREFsymbol else TERMREFsymbol) + pickleSymRef(sym); pickleType(tpe.prefix) + } + else pickleExternalRef(sym) + } + case tpe: ThisType => + val cls = tpe.cls + if (cls.isPackage && !cls.isEffectiveRoot) { + writeByte(TERMREFpkg) + pickleName(cls.fullName) + } + else { + writeByte(THIS) + pickleType(tpe.tref) + } + case tpe: SuperType => + writeByte(SUPERtype) + withLength { pickleType(tpe.thistpe); pickleType(tpe.supertpe) } + case tpe: RecThis => + writeByte(RECthis) + val binderAddr = pickledTypes.get(tpe.binder) + assert(binderAddr != null, tpe.binder) + writeRef(binderAddr.asInstanceOf[Addr]) + case tpe: SkolemType => + pickleType(tpe.info) + case tpe: RefinedType => + writeByte(REFINEDtype) + withLength { + pickleName(tpe.refinedName) + pickleType(tpe.parent) + pickleType(tpe.refinedInfo, richTypes = true) + } + case tpe: RecType => + writeByte(RECtype) + pickleType(tpe.parent) + case tpe: TypeAlias => + writeByte(TYPEALIAS) + pickleType(tpe.alias, richTypes) + case tpe: TypeBounds => + writeByte(TYPEBOUNDS) + withLength { pickleType(tpe.lo, richTypes); pickleType(tpe.hi, richTypes) } + case tpe: AnnotatedType => + writeByte(ANNOTATEDtype) + withLength { pickleType(tpe.parent, richTypes); pickleTree(tpe.annot.tree) } + case tpe: AndType => + writeByte(ANDtype) + withLength { pickleType(tpe.tp1, richTypes); pickleType(tpe.tp2, richTypes) } + case tpe: OrType => + writeByte(ORtype) + withLength { pickleType(tpe.tp1, richTypes); pickleType(tpe.tp2, richTypes) } + case tpe: ExprType => + writeByte(BYNAMEtype) + pickleType(tpe.underlying) + case tpe: HKTypeLambda => + pickleMethodic(TYPELAMBDAtype, tpe) + case tpe: MatchType => + writeByte(MATCHtype) + withLength { + pickleType(tpe.bound) + pickleType(tpe.scrutinee) + tpe.cases.foreach(pickleType(_)) + } + case tpe: PolyType if richTypes => + pickleMethodic(POLYtype, tpe) + case tpe: MethodType if richTypes => + val tag = methodTypeTag( + isContextual = tpe.isContextualMethod, + isImplicit = tpe.isImplicitMethod && !tpe.isContextualMethod, + isErased = tpe.isErasedMethod) + pickleMethodic(tag, tpe) + case tpe: ParamRef => + assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe") + case tpe: LazyRef => + pickleType(tpe.ref) + } + + def pickleMethodic(tag: Int, tpe: LambdaType)(implicit ctx: Context): Unit = { + writeByte(tag) + withLength { + pickleType(tpe.resultType, richTypes = true) + tpe.paramNames.lazyZip(tpe.paramInfos).foreach { (name, tpe) => + pickleName(name); pickleType(tpe) + } + } + } + + def pickleParamRef(tpe: ParamRef)(implicit ctx: Context): Boolean = { + val binder = pickledTypes.get(tpe.binder) + val pickled = binder != null + if (pickled) { + writeByte(PARAMtype) + withLength { writeRef(binder.asInstanceOf[Addr]); writeNat(tpe.paramNum) } + } + pickled + } + + def pickleTpt(tpt: Tree)(implicit ctx: Context): Unit = + pickleTree(tpt) + + def pickleTreeUnlessEmpty(tree: Tree)(implicit ctx: Context): Unit = { + if (!tree.isEmpty) pickleTree(tree) + } + + def pickleDef(tag: Int, sym: Symbol, tpt: Tree, rhs: Tree = EmptyTree, pickleParams: => Unit = ())(implicit ctx: Context): Unit = { + assert(symRefs(sym) == NoAddr, sym) + registerDef(sym) + writeByte(tag) + withLength { + pickleName(sym.name) + pickleParams + tpt match { + case _: Template | _: Hole => pickleTree(tpt) + case _ if tpt.isType => pickleTpt(tpt) + } + pickleTreeUnlessEmpty(rhs) + pickleModifiers(sym) + } + } + + def pickleParam(tree: Tree)(implicit ctx: Context): Unit = { + registerTreeAddr(tree) + tree match { + case tree: ValDef => pickleDef(PARAM, tree.symbol, tree.tpt) + case tree: DefDef => pickleDef(PARAM, tree.symbol, tree.tpt, tree.rhs) + case tree: TypeDef => pickleDef(TYPEPARAM, tree.symbol, tree.rhs) + } + } + + def pickleParams(trees: List[Tree])(implicit ctx: Context): Unit = { + trees.foreach(preRegister) + trees.foreach(pickleParam) + } + + def pickleStats(stats: List[Tree])(implicit ctx: Context): Unit = { + stats.foreach(preRegister) + stats.foreach(stat => if (!stat.isEmpty) pickleTree(stat)) + } + + def pickleTree(tree: Tree)(implicit ctx: Context): Unit = { + val addr = registerTreeAddr(tree) + if (addr != currentAddr) { + writeByte(SHAREDterm) + writeRef(addr) + } + else + try tree match { + case Ident(name) => + tree.tpe match { + case tp: TermRef if name != nme.WILDCARD => + // wildcards are pattern bound, need to be preserved as ids. + pickleType(tp) + case tp => + writeByte(if (tree.isType) IDENTtpt else IDENT) + pickleName(name) + pickleType(tp) + } + case This(qual) => + if (qual.isEmpty) pickleType(tree.tpe) + else { + writeByte(QUALTHIS) + tree.tpe match { + case thistpe: ThisType => + pickleTree(qual.withType(thistpe.tref)) + case _ => + } + } + case Select(qual, name) => + name match { + case OuterSelectName(_, levels) => + writeByte(SELECTouter) + withLength { + writeNat(levels) + pickleTree(qual) + tree.tpe match { + case tpe: SkolemType => + pickleType(tpe.info) + case _ => + } + } + case _ => + writeByte(if (name.isTypeName) SELECTtpt else SELECT) + val sig = tree.tpe.signature + pickleNameAndSig(name, sig) + pickleTree(qual) + } + case Apply(fun, args) => + if (fun.symbol eq defn.throwMethod) { + writeByte(THROW) + pickleTree(args.head) + } + else { + writeByte(APPLY) + withLength { + pickleTree(fun) + args.foreach(pickleTree) + } + } + case TypeApply(fun, args) => + writeByte(TYPEAPPLY) + withLength { + pickleTree(fun) + args.foreach(pickleTpt) + } + case Literal(const1) => + pickleConstant { + tree.tpe match { + case tpe: ConstantType => tpe.value + case _ => const1 + } + } + case Super(qual, mix) => + writeByte(SUPER) + withLength { + pickleTree(qual); + if (!mix.isEmpty) { + tree.tpe match { + case tpe: SuperType => tpe.supertpe match { + case mixinType: TypeRef => + pickleTree(mix.withType(mixinType)) + case _ => + } + case _ => + } + } + } + case New(tpt) => + writeByte(NEW) + pickleTpt(tpt) + case Typed(expr, tpt) => + writeByte(TYPED) + withLength { pickleTree(expr); pickleTpt(tpt) } + case NamedArg(name, arg) => + writeByte(NAMEDARG) + pickleName(name) + pickleTree(arg) + case Assign(lhs, rhs) => + writeByte(ASSIGN) + withLength { pickleTree(lhs); pickleTree(rhs) } + case Block(stats, expr) => + writeByte(BLOCK) + stats.foreach(preRegister) + withLength { pickleTree(expr); stats.foreach(pickleTree) } + case tree @ If(cond, thenp, elsep) => + writeByte(IF) + withLength { + if (tree.isInline) writeByte(INLINE) + pickleTree(cond) + pickleTree(thenp) + pickleTree(elsep) + } + case Closure(env, meth, tpt) => + writeByte(LAMBDA) + assert(env.isEmpty) + withLength { + pickleTree(meth) + if (tpt.tpe.exists) pickleTpt(tpt) + } + case tree @ Match(selector, cases) => + writeByte(MATCH) + withLength { + if (tree.isInline) + if (selector.isEmpty) writeByte(IMPLICIT) + else { writeByte(INLINE); pickleTree(selector) } + else pickleTree(selector) + cases.foreach(pickleTree) + } + case CaseDef(pat, guard, rhs) => + writeByte(CASEDEF) + withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) } + case Return(expr, from) => + writeByte(RETURN) + withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) } + case WhileDo(cond, body) => + writeByte(WHILE) + withLength { pickleTree(cond); pickleTree(body) } + case Try(block, cases, finalizer) => + writeByte(TRY) + withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) } + case SeqLiteral(elems, elemtpt) => + writeByte(REPEATED) + withLength { pickleTree(elemtpt); elems.foreach(pickleTree) } + case Inlined(call, bindings, expansion) => + writeByte(INLINED) + bindings.foreach(preRegister) + withLength { + pickleTree(expansion) + if (!call.isEmpty) pickleTree(call) + bindings.foreach { b => + assert(b match { + case _:DefDef | _:ValDef => true + case _ => false + }) + pickleTree(b) + } + } + case Bind(name, body) => + registerDef(tree.symbol) + writeByte(BIND) + withLength { + pickleName(name); pickleType(tree.symbol.info); pickleTree(body) + } + case Alternative(alts) => + writeByte(ALTERNATIVE) + withLength { alts.foreach(pickleTree) } + case UnApply(fun, implicits, patterns) => + writeByte(UNAPPLY) + withLength { + pickleTree(fun) + for (implicitArg <- implicits) { + writeByte(IMPLICITarg) + pickleTree(implicitArg) + } + pickleType(tree.tpe) + patterns.foreach(pickleTree) + } + case tree: ValDef => + pickleDef(VALDEF, tree.symbol, tree.tpt, tree.rhs) + case tree: DefDef => + def pickleParamss(paramss: List[List[ValDef]]): Unit = paramss match + case Nil => + case params :: rest => + pickleParams(params) + if params.isEmpty || rest.nonEmpty then writeByte(PARAMEND) + pickleParamss(rest) + def pickleAllParams = + pickleParams(tree.tparams) + pickleParamss(tree.vparamss) + pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams) + case tree: TypeDef => + pickleDef(TYPEDEF, tree.symbol, tree.rhs) + case tree: Template => + registerDef(tree.symbol) + writeByte(TEMPLATE) + val (params, rest) = tree.decomposeBody + withLength { + pickleParams(params) + tree.parents.foreach(pickleTree) + tree.symbol.owner.info match { + case cinfo: ClassInfo => + if (!tree.self.isEmpty) { + writeByte(SELFDEF) + pickleName(tree.self.name) + if (!tree.self.tpt.isEmpty) pickleTree(tree.self.tpt) + else { + if (!tree.self.isEmpty) registerTreeAddr(tree.self) + pickleType { + cinfo.selfInfo match { + case Left(tp) => tp + case Right(sym) => sym.info + } + } + } + } + pickleStats(tree.constr :: rest) + case _ => + } + } + case Import(expr, selectors) => + writeByte(IMPORT) + withLength { + pickleTree(expr) + pickleSelectors(selectors) + } + case PackageDef(pid, stats) => + writeByte(PACKAGE) + withLength { pickleType(pid.tpe); pickleStats(stats) } + case tree: TypeTree => + pickleType(tree.tpe) + case SingletonTypeTree(ref) => + writeByte(SINGLETONtpt) + pickleTree(ref) + case RefinedTypeTree(parent, refinements) => + if (refinements.isEmpty) pickleTree(parent) + else { + val refineCls = refinements.head.symbol.owner.asClass + pickledTypes.put(refineCls.typeRef, currentAddr) + writeByte(REFINEDtpt) + refinements.foreach(preRegister) + withLength { pickleTree(parent); refinements.foreach(pickleTree) } + } + case AppliedTypeTree(tycon, args) => + writeByte(APPLIEDtpt) + withLength { pickleTree(tycon); args.foreach(pickleTree) } + case MatchTypeTree(bound, selector, cases) => + writeByte(MATCHtpt) + withLength { + if (!bound.isEmpty) pickleTree(bound) + pickleTree(selector) + cases.foreach(pickleTree) + } + case ByNameTypeTree(tp) => + writeByte(BYNAMEtpt) + pickleTree(tp) + case Annotated(tree, annot) => + writeByte(ANNOTATEDtpt) + withLength { pickleTree(tree); pickleTree(annot) } + case LambdaTypeTree(tparams, body) => + writeByte(LAMBDAtpt) + withLength { pickleParams(tparams); pickleTree(body) } + case TypeBoundsTree(lo, hi) => + writeByte(TYPEBOUNDStpt) + withLength { + pickleTree(lo); + if (hi ne lo) pickleTree(hi) + } + case Hole(idx, args) => + writeByte(HOLE) + withLength { + writeNat(idx) + args.foreach(pickleTree) + } + } + catch { + case ex: AssertionError => + println(i"error when pickling tree $tree") + throw ex + } + } + + def pickleSelectors(selectors: List[untpd.ImportSelector])(implicit ctx: Context): Unit = + import untpd.given + for sel <- selectors do + pickleSelector(IMPORTED, sel.imported) + sel.renamed match + case to @ Ident(_) => pickleSelector(RENAMED, to) + case _ => + sel.bound match { + case bound @ untpd.TypedSplice(tpt) => + registerTreeAddr(bound) + writeByte(BOUNDED) + pickleTree(tpt) + case _ => + } + + def pickleSelector(tag: Int, id: Ident)(implicit ctx: Context): Unit = { + registerTreeAddr(id) + writeByte(tag) + val Ident(name) = id + pickleName(name) + } + + def pickleModifiers(sym: Symbol)(implicit ctx: Context): Unit = { + import Flags._ + var flags = sym.flags + val privateWithin = sym.privateWithin + if (privateWithin.exists) { + writeByte(if (flags.is(Protected)) PROTECTEDqualified else PRIVATEqualified) + pickleType(privateWithin.typeRef) + flags = flags &~ Protected + } + if (flags.is(ParamAccessor) && sym.isTerm && !sym.isSetter) + flags = flags &~ ParamAccessor // we only generate a tag for parameter setters + pickleFlags(flags, sym.isTerm) + sym.annotations.foreach(pickleAnnotation(sym, _)) + } + + def pickleFlags(flags: FlagSet, isTerm: Boolean)(implicit ctx: Context): Unit = { + import Flags._ + def writeModTag(tag: Int) = { + assert(isModifierTag(tag)) + writeByte(tag) + } + if (flags.is(Private)) writeModTag(PRIVATE) + if (flags.is(Protected)) writeModTag(PROTECTED) + if (flags.is(Final, butNot = Module)) writeModTag(FINAL) + if (flags.is(Case)) writeModTag(CASE) + if (flags.is(Override)) writeModTag(OVERRIDE) + if (flags.is(Inline)) writeModTag(INLINE) + if (flags.is(InlineProxy)) writeModTag(INLINEPROXY) + if (flags.is(Macro)) writeModTag(MACRO) + if (flags.is(JavaStatic)) writeModTag(STATIC) + if (flags.is(Module)) writeModTag(OBJECT) + if (flags.is(Enum)) writeModTag(ENUM) + if (flags.is(Local)) writeModTag(LOCAL) + if (flags.is(Synthetic)) writeModTag(SYNTHETIC) + if (flags.is(Artifact)) writeModTag(ARTIFACT) + if (flags.is(Scala2x)) writeModTag(SCALA2X) + if (isTerm) { + if (flags.is(Implicit)) writeModTag(IMPLICIT) + if (flags.is(Given)) writeModTag(GIVEN) + if (flags.is(Erased)) writeModTag(ERASED) + if (flags.is(Lazy, butNot = Module)) writeModTag(LAZY) + if (flags.is(AbsOverride)) { writeModTag(ABSTRACT); writeModTag(OVERRIDE) } + if (flags.is(Mutable)) writeModTag(MUTABLE) + if (flags.is(Accessor)) writeModTag(FIELDaccessor) + if (flags.is(CaseAccessor)) writeModTag(CASEaccessor) + if (flags.is(DefaultParameterized)) writeModTag(DEFAULTparameterized) + if (flags.is(StableRealizable)) writeModTag(STABLE) + if (flags.is(Extension)) writeModTag(EXTENSION) + if (flags.is(ParamAccessor)) writeModTag(PARAMsetter) + if (flags.is(Exported)) writeModTag(EXPORTED) + assert(!(flags.is(Label))) + } + else { + if (flags.is(Sealed)) writeModTag(SEALED) + if (flags.is(Abstract)) writeModTag(ABSTRACT) + if (flags.is(Trait)) writeModTag(TRAIT) + if (flags.is(Covariant)) writeModTag(COVARIANT) + if (flags.is(Contravariant)) writeModTag(CONTRAVARIANT) + if (flags.is(Opaque)) writeModTag(OPAQUE) + if (flags.is(Open)) writeModTag(OPEN) + } + } + + private def isUnpicklable(owner: Symbol, ann: Annotation)(implicit ctx: Context) = ann match { + case Annotation.Child(sym) => sym.isInaccessibleChildOf(owner) + // If child annotation refers to a local class or enum value under + // a different toplevel class, it is impossible to pickle a reference to it. + // Such annotations will be reconstituted when unpickling the child class. + // See tests/pickling/i3149.scala + case _ => + ann.symbol == defn.BodyAnnot // inline bodies are reconstituted automatically when unpickling + } + + def pickleAnnotation(owner: Symbol, ann: Annotation)(implicit ctx: Context): Unit = { + if (!isUnpicklable(owner, ann)) { + writeByte(ANNOTATION) + withLength { pickleType(ann.symbol.typeRef); pickleTree(ann.tree) } + } + } + +// ---- main entry points --------------------------------------- + + def pickle(trees: List[Tree])(implicit ctx: Context): Unit = { + trees.foreach(tree => if (!tree.isEmpty) pickleTree(tree)) + def missing = forwardSymRefs.keysIterator.map(sym => sym.showLocated + "(line " + sym.sourcePos.line + ")").toList + assert(forwardSymRefs.isEmpty, i"unresolved symbols: $missing%, % when pickling ${ctx.source}") + } + + def compactify(): Unit = { + buf.compactify() + + def updateMapWithDeltas(mp: MutableSymbolMap[Addr]) = + for (key <- mp.keysIterator.toBuffer[Symbol]) mp(key) = adjusted(mp(key)) + + updateMapWithDeltas(symRefs) + } +} diff --git a/tasty/src/dotty/tools/tasty/experimental/UnpickleException.scala b/tasty/src/dotty/tools/tasty/experimental/UnpickleException.scala new file mode 100644 index 000000000000..4cd6d6d8da81 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/UnpickleException.scala @@ -0,0 +1,3 @@ +package dotty.tools.tasty.experimental + +class UnpickleException(msg: String) extends Exception(msg) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala new file mode 100644 index 000000000000..2db28a825993 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala @@ -0,0 +1,15 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait AnnotationOps extends Core with + + object Annotation with + + object Child with + + def unapply(annot: Annotation)(given Context): Option[Symbol] = internal.Annotation_Child_unapply(annot) + + given AnnotationOps: (annot: Annotation) with + def tree(given Context): Tree = internal.Annotation_tree(annot) + def symbol(given Context): Symbol = internal.Annotation_symbol(annot) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala new file mode 100644 index 000000000000..0e3cf5a8c7c0 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala @@ -0,0 +1,35 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait ConstantOps extends Core with + + object Constants with + final val NoTag = internal.Constants_NoTag + final val UnitTag = internal.Constants_UnitTag + final val BooleanTag = internal.Constants_BooleanTag + final val ByteTag = internal.Constants_ByteTag + final val ShortTag = internal.Constants_ShortTag + final val CharTag = internal.Constants_CharTag + final val IntTag = internal.Constants_IntTag + final val LongTag = internal.Constants_LongTag + final val FloatTag = internal.Constants_FloatTag + final val DoubleTag = internal.Constants_DoubleTag + final val StringTag = internal.Constants_StringTag + final val NullTag = internal.Constants_NullTag + final val ClazzTag = internal.Constants_ClazzTag + final val EnumTag = internal.Constants_EnumTag + + given ConstantOps: (c: Constant) with + def tag: Int = internal.Constant_tag(c) + def intValue: Int = internal.Constant_intValue(c) + def booleanValue: Boolean = internal.Constant_booleanValue(c) + def shortValue: Short = internal.Constant_shortValue(c) + def charValue: Char = internal.Constant_charValue(c) + def byteValue: Byte = internal.Constant_byteValue(c) + def longValue: Long = internal.Constant_longValue(c) + def floatValue: Float = internal.Constant_floatValue(c) + def doubleValue: Double = internal.Constant_doubleValue(c) + def stringValue: String = internal.Constant_stringValue(c) + def typeValue: Type = internal.Constant_typeValue(c) + def symbolValue: Symbol = internal.Constant_symbolValue(c) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala new file mode 100644 index 000000000000..1d7a70395c06 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala @@ -0,0 +1,10 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag +import java.nio.file.Path + +trait ContextOps extends Core with + + given ContextOps: (ctx: Context) with + def log(msg: => String, sourcePos: SourcePosition): Unit = internal.Context_log(ctx, msg, sourcePos) + def source: Path = internal.Context_source(ctx) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala new file mode 100644 index 000000000000..e36b20d8ea62 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala @@ -0,0 +1,109 @@ +package dotty.tools.tasty.experimental.bridge + +trait Core with + + private[tasty] val internal: TastyKernel + + type Context = internal.Context + + type Annotation = internal.Annotation + + type Designator = internal.Designator + + type Name = internal.Name + type SimpleName = internal.SimpleName + type DerivedName = internal.DerivedName + type TypeName = internal.TypeName + type TermName = internal.TermName + + type Signature = internal.Signature + + // type UntpdTree = internal.UntpdTree + // type TypedSplice = internal.TypedSplice + type Tree = internal.Tree + type MemberDef = internal.MemberDef + type Hole = internal.Hole + type Template = internal.Template + type ValOrDefDef = internal.ValOrDefDef + type TypeDef = internal.TypeDef + type ValDef = internal.ValDef + type DefDef = internal.DefDef + type RefTree = internal.RefTree + type Ident = internal.Ident + type Select = internal.Select + type This = internal.This + type Apply = internal.Apply + type TypeApply = internal.TypeApply + type Literal = internal.Literal + type Super = internal.Super + type New = internal.New + type Typed = internal.Typed + type NamedArg = internal.NamedArg + type Assign = internal.Assign + type Block = internal.Block + type If = internal.If + type Closure = internal.Closure + type Match = internal.Match + type CaseDef = internal.CaseDef + type Return = internal.Return + type WhileDo = internal.WhileDo + type Try = internal.Try + type SeqLiteral = internal.SeqLiteral + type Inlined = internal.Inlined + type Bind = internal.Bind + type Alternative = internal.Alternative + type UnApply = internal.UnApply + type Import = internal.Import + type PackageDef = internal.PackageDef + type TypeTree = internal.TypeTree + type SingletonTypeTree = internal.SingletonTypeTree + type RefinedTypeTree = internal.RefinedTypeTree + type AppliedTypeTree = internal.AppliedTypeTree + type MatchTypeTree = internal.MatchTypeTree + type ByNameTypeTree = internal.ByNameTypeTree + type Annotated = internal.Annotated + type LambdaTypeTree = internal.LambdaTypeTree + type TypeBoundsTree = internal.TypeBoundsTree + // type ImportSelector = internal.ImportSelector + + type Type = internal.Type + type AppliedType = internal.AppliedType + type ConstantType = internal.ConstantType + type NamedType = internal.NamedType + type ThisType = internal.ThisType + type SuperType = internal.SuperType + type BoundType = internal.BoundType + type RecThis = internal.RecThis + type ParamRef = internal.ParamRef + type RecType = internal.RecType + type TermRef = internal.TermRef + type TypeRef = internal.TypeRef + type SkolemType = internal.SkolemType + type RefinedType = internal.RefinedType + type TypeAlias = internal.TypeAlias + type TypeBounds = internal.TypeBounds + type AnnotatedType = internal.AnnotatedType + type AndOrType = internal.AndOrType + type AndType = internal.AndType + type OrType = internal.OrType + type ExprType = internal.ExprType + type TypeProxy = internal.TypeProxy + type MatchType = internal.MatchType + type PolyType = internal.PolyType + type LambdaType = internal.LambdaType + type HKTypeLambda = internal.HKTypeLambda + type MethodType = internal.MethodType + type LazyRef = internal.LazyRef + type ClassInfo = internal.ClassInfo + + type Symbol = internal.Symbol + type TermSymbol = internal.TermSymbol + type TypeSymbol = internal.TypeSymbol + type ClassSymbol = internal.ClassSymbol + + type FlagSet = internal.FlagSet + type Flag = internal.Flag + + type SourcePosition = internal.SourcePosition + + type Constant = internal.Constant diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala new file mode 100644 index 000000000000..c155536bc0c0 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala @@ -0,0 +1,62 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait FlagOps extends Core with + + object Flags with + val Protected: Flag = internal.Flags_Protected + val ParamAccessor: Flag = internal.Flags_ParamAccessor + val Private: Flag = internal.Flags_Private + val Final: Flag = internal.Flags_Final + val Case: Flag = internal.Flags_Case + val Override: Flag = internal.Flags_Override + val Inline: Flag = internal.Flags_Inline + val InlineProxy: Flag = internal.Flags_InlineProxy + val Macro: Flag = internal.Flags_Macro + val JavaStatic: Flag = internal.Flags_JavaStatic + val Module: Flag = internal.Flags_Module + val Enum: Flag = internal.Flags_Enum + val Local: Flag = internal.Flags_Local + val Synthetic: Flag = internal.Flags_Synthetic + val Artifact: Flag = internal.Flags_Artifact + val Scala2x: Flag = internal.Flags_Scala2x + val Implicit: Flag = internal.Flags_Implicit + val Given: Flag = internal.Flags_Given + val Erased: Flag = internal.Flags_Erased + val Lazy: Flag = internal.Flags_Lazy + val AbsOverride: Flag = internal.Flags_AbsOverride + val Mutable: Flag = internal.Flags_Mutable + val Accessor: Flag = internal.Flags_Accessor + val CaseAccessor: Flag = internal.Flags_CaseAccessor + val DefaultParameterized: Flag = internal.Flags_DefaultParameterized + val StableRealizable: Flag = internal.Flags_StableRealizable + val Extension: Flag = internal.Flags_Extension + val Exported: Flag = internal.Flags_Exported + val Label: Flag = internal.Flags_Label + val Sealed: Flag = internal.Flags_Sealed + val Abstract: Flag = internal.Flags_Abstract + val Trait: Flag = internal.Flags_Trait + val Covariant: Flag = internal.Flags_Covariant + val Contravariant: Flag = internal.Flags_Contravariant + val Opaque: Flag = internal.Flags_Opaque + val Open: Flag = internal.Flags_Open + end Flags + + given FlagSetOps: (flags: FlagSet) + def is(flag: Flag): Boolean = internal.FlagSet_is(flags, flag) + def is(flag: Flag, butNot: FlagSet): Boolean = internal.FlagSet_is(flags, flag, butNot) + def &~(flag: Flag): FlagSet = internal.FlagSet_&~(flags, flag) + + // given ClassTag[Tree] = internal.Tree_CT + // given ClassTag[MemberDef] = internal.MemberDef_CT + // given ClassTag[UntpdTree] = internal.UntpdTree_CT + // given ClassTag[Hole] = internal.Hole_CT + // given ClassTag[Template] = internal.Template_CT + + // given TreeOps: (tree: Tree) with + // def symbol(given Context): Symbol = internal.Tree_symbol(tree) + // def isEmpty: Boolean = internal.Tree_isEmpty(tree) + // def isType: Boolean = internal.Tree_isType(tree) + + // final val EmptyTree = internal.EmptyTree diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala new file mode 100644 index 000000000000..98ac0b610d29 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala @@ -0,0 +1,49 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait NameOps extends Core with + + given ClassTag[Name] = internal.Name_CT + given ClassTag[SimpleName] = internal.SimpleName_CT + given ClassTag[DerivedName] = internal.DerivedName_CT + given ClassTag[TypeName] = internal.TypeName_CT + given ClassTag[TermName] = internal.TermName_CT + + object nme { + val WILDCARD: TermName = internal.nme_WILDCARD + } + + object SignedName with + def unapply(name: DerivedName): Option[(TermName, Signature)] = internal.SignedName_unapply(name) + def apply(name: TermName, sig: Signature): TermName = internal.SignedName_apply(name, sig) + + object AnyQualifiedName with + def unapply(name: DerivedName): Option[(TermName, SimpleName)] = internal.AnyQualifiedName_unapply(name) + + /** An extractor for unique names of arbitrary kind */ + object AnyUniqueName with + def unapply(name: DerivedName): Option[(TermName, String, Int)] = internal.AnyUniqueName_unapply(name) + + object AnyNumberedName with + def unapply(name: DerivedName): Option[(TermName, Int)] = internal.AnyNumberedName_unapply(name) + + object DerivedName with + def unapply(name: DerivedName): Some[TermName] = internal.DerivedName_unapply(name) + + object OuterSelectName with + def unapply(name: DerivedName): Option[(TermName, Int)] = internal.OuterSelectName_unapply(name) + + + given NameOps: (name: Name) with + def toTermName: TermName = internal.Name_toTermName(name) + def isEmpty: Boolean = internal.Name_isEmpty(name) + def isTypeName: Boolean = internal.Name_isTypeName(name) + def isTermName: Boolean = !name.isTypeName + def length: Int = internal.Name_length(name) + + given TermNameOps: (name: TermName) with + def tag: Int = internal.TermName_tag(name) + + given SimpleNameOps: (name: SimpleName) with + def toUTF8: Array[Byte] = internal.SimpleName_toUTF8(name) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala new file mode 100644 index 000000000000..a2aa4904c523 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala @@ -0,0 +1,8 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait PositionOps extends Core with + + given SourcePosition: (pos: SourcePosition) with + def line: Int = internal.SourcePosition_line(pos) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/PrintingOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/PrintingOps.scala new file mode 100644 index 000000000000..983bb1106b21 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/PrintingOps.scala @@ -0,0 +1,13 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait PrintingOps extends Core with + + object Printers with + + class Printer with + def println(msg: => String): Unit = System.out.println(msg) + + val pickling = new Printer with + override def println(msg: => String): Unit = internal.pickling_println(msg) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala new file mode 100644 index 000000000000..76657950287d --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala @@ -0,0 +1,24 @@ +package dotty.tools.tasty.experimental.bridge + +import dotty.tools.tasty.experimental.function._ + +import reflect.ClassTag + +trait SignatureOps extends Core with + + given ClassTag[Signature] = internal.Signature_CT + + object Signature with + + type ParamSig = internal.Signature_ParamSig + + def unapply(signature: Signature): (List[ParamSig], TypeName) = internal.Signature_unapply(signature) + + given ParamSigOps: (paramSig: ParamSig) with + def fold[A](onInt: Int => A, onTypeName: TypeName => A): A = internal.Signature_ParamSig_fold(paramSig)(onInt, onTypeName) + def foldInt(onInt: IntToInt, onTypeName: ToInt[TypeName]): Int = internal.Signature_ParamSig_foldInt(paramSig)(onInt, onTypeName) + + end Signature + + given SignatureOps: (signature: Signature) with + def isNotAMethod: Boolean = internal.Signature_isNotAMethod(signature) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala new file mode 100644 index 000000000000..4189bf77f4e0 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala @@ -0,0 +1,11 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait StringOps extends Core with + + given StringOps: (string: String) with + def toTermName: TermName = internal.String_toTermName(string) + + given StringContextOps: (stringContext: StringContext) with + def i(args: => Any*): String = internal.StringContext_i(stringContext, args) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala new file mode 100644 index 000000000000..7e7b22e70822 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala @@ -0,0 +1,55 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait SymbolOps extends Core with + + given ClassTag[Symbol] = internal.Symbol_CT + given ClassTag[ClassSymbol] = internal.ClassSymbol_CT + + object defn with + def throwMethod(given Context): TermSymbol = internal.defn_throwMethod + def BodyAnnot(given Context): ClassSymbol = internal.defn_BodyAnnot + + object Symbols with + + type MutableSymbolMap[T] = internal.Symbols_MutableSymbolMap[T] + + def newMutableSymbolMap[T]: MutableSymbolMap[T] = internal.Symbols_newMutableSymbolMap[T] + + given MutableSymbolMapOps: [T](map: Symbols.MutableSymbolMap[T]) with + def get(sym: Symbol): Option[T] = internal.Symbols_MutableSymbolMap_get(map, sym) + def getOrElse[U >: T](sym: Symbol, default: => U): U = internal.Symbols_MutableSymbolMap_getOrElse(map, sym, default) + def contains(sym: Symbol): Boolean = internal.Symbols_MutableSymbolMap_contains(map, sym) + def update(sym: Symbol, value: T): Unit = internal.Symbols_MutableSymbolMap_update(map, sym, value) + def -=(sym: Symbol): Unit = internal.Symbols_MutableSymbolMap_-=(map, sym) + def apply(sym: Symbol): T = internal.Symbols_MutableSymbolMap_apply(map, sym) + def isEmpty: Boolean = internal.Symbols_MutableSymbolMap_isEmpty(map) + def keysIterator: Iterator[Symbol] = internal.Symbols_MutableSymbolMap_keysIterator(map) + end MutableSymbolMapOps + + end Symbols + + given SymbolOps: (sym: Symbol) with + def isPackage(given Context): Boolean = internal.Symbol_isPackage(sym) + def isPrivate(given Context): Boolean = internal.Symbol_isPrivate(sym) + def sourcePos(given Context): SourcePosition = internal.Symbol_sourcePos(sym) + def owner: Symbol = internal.Symbol_owner(sym) + def isDefinedWithin(outer: Symbol)(given Context): Boolean = internal.Symbol_isDefinedWithin(sym, outer) + def termRef(given Context): TermRef = internal.Symbol_termRef(sym) + def typeRef(given Context): TypeRef = internal.Symbol_typeRef(sym) + def name(given Context): sym.ThisName = internal.Symbol_name(sym) + def fullName(given Context): sym.ThisName = internal.Symbol_fullName(sym) + def isClass: Boolean = internal.Symbol_isClass(sym) + def isEffectiveRoot(given Context): Boolean = internal.Symbol_isEffectiveRoot(sym) + def flags(given Context): FlagSet = internal.Symbol_flags(sym) + def privateWithin(given Context): Symbol = internal.Symbol_privateWithin(sym) + def isTerm(given Context): Boolean = internal.Symbol_isTerm(sym) + def isSetter(given Context): Boolean = internal.Symbol_isSetter(sym) + def info(given Context): Type = internal.Symbol_info(sym) + def isInaccessibleChildOf(cls: Symbol)(given Context): Boolean = internal.Symbol_isInaccessibleChildOf(sym, cls) + def exists: Boolean = internal.Symbol_exists(sym) + def showLocated(given Context): String = internal.Symbol_showLocated(sym) + def annotations(given Context): List[Annotation] = internal.Symbol_annotations(sym) + def asClass: ClassSymbol = sym.asInstanceOf[ClassSymbol] + end SymbolOps diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala new file mode 100644 index 000000000000..606c38084450 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala @@ -0,0 +1,467 @@ +package dotty.tools.tasty.experimental.bridge + +import dotty.tools.tasty.experimental.function._ + +import reflect.ClassTag + +import java.nio.file.Path + +trait TastyKernel with + + type Context <: AnyRef + + type Designator <: AnyRef + + type Annotation <: AnyRef + + type Name <: Designator + type SimpleName <: TermName + type DerivedName <: TermName + type TypeName <: Name + type TermName <: Name + + val Name_CT: ClassTag[Name] + val SimpleName_CT: ClassTag[SimpleName] + val DerivedName_CT: ClassTag[DerivedName] + val TypeName_CT: ClassTag[TypeName] + val TermName_CT: ClassTag[TermName] + + type Signature <: AnyRef + + val Signature_CT: ClassTag[Signature] + + type Signature_ParamSig = Int | TypeName + + type untpd_Tree <: AnyRef + type untpd_ImportSelector <: untpd_Tree + type untpd_TypedSplice <: untpd_Tree + + type Tree <: untpd_Tree { type ThisTree <: Tree } + type MemberDef <: Tree + type Hole <: Tree + type Template <: Tree // DefTree + type ValOrDefDef <: Tree // DefTree + type TypeDef <: MemberDef + type ValDef <: ValOrDefDef + type DefDef <: ValOrDefDef + type RefTree <: Tree + type Ident <: RefTree + type This <: Tree // DenotingTree[T] with TermTree[T] + type Select <: RefTree + type Apply <: Tree // GenericApply -> TermTree + type TypeApply <: Tree // GenericApply -> TermTree + type Literal <: Tree // TermTree + type Super <: Tree // TermTree + type New <: Tree // TermTree + type Typed <: Tree // TermTree + type NamedArg <: Tree + type Assign <: Tree // TermTree + type Block <: Tree + type If <: Tree // TermTree + type Closure <: Tree // TermTree + type Match <: Tree // TermTree + type CaseDef <: Tree + type Return <: Tree // TermTree + type WhileDo <: Tree // TermTree + type Try <: Tree // TermTree + type SeqLiteral <: Tree // TermTree + type Inlined <: Tree + type Bind <: Tree // NameTree[T] with DefTree[T] with PatternTree[T] + type Alternative <: Tree // PatternTree + type UnApply <: Tree // PatternTree + type Import <: Tree // DenotingTree + type PackageDef <: Tree + type TypeTree <: Tree // DenotingTree[T] with TypTree[T] + type SingletonTypeTree <: Tree // DenotingTree[T] with TypTree[T] + type RefinedTypeTree <: Tree // TypTree[T] + type AppliedTypeTree <: Tree // TypTree[T] + type MatchTypeTree <: Tree // TypTree[T] + type ByNameTypeTree <: Tree // TypTree[T] + type Annotated <: Tree + type LambdaTypeTree <: Tree // TypTree[T] + type TypeBoundsTree <: Tree // TypTree[T] + + val untpd_Tree_CT: ClassTag[untpd_Tree] + val untpd_TypedSplice_CT: ClassTag[untpd_TypedSplice] + val Tree_CT: ClassTag[Tree] + val MemberDef_CT: ClassTag[MemberDef] + val Hole_CT: ClassTag[Hole] + val Template_CT: ClassTag[Template] + val ValOrDefDef_CT: ClassTag[ValOrDefDef] + val TypeDef_CT: ClassTag[TypeDef] + val ValDef_CT: ClassTag[ValDef] + val DefDef_CT: ClassTag[DefDef] + val Ident_CT: ClassTag[Ident] + val This_CT: ClassTag[This] + val Select_CT: ClassTag[Select] + val Apply_CT: ClassTag[Apply] + val TypeApply_CT: ClassTag[TypeApply] + val Literal_CT: ClassTag[Literal] + val Super_CT: ClassTag[Super] + val New_CT: ClassTag[New] + val Typed_CT: ClassTag[Typed] + val NamedArg_CT: ClassTag[NamedArg] + val Assign_CT: ClassTag[Assign] + val Block_CT: ClassTag[Block] + val If_CT: ClassTag[If] + val Closure_CT: ClassTag[Closure] + val Match_CT: ClassTag[Match] + val CaseDef_CT: ClassTag[CaseDef] + val Return_CT: ClassTag[Return] + val WhileDo_CT: ClassTag[WhileDo] + val Try_CT: ClassTag[Try] + val SeqLiteral_CT: ClassTag[SeqLiteral] + val Inlined_CT: ClassTag[Inlined] + val Bind_CT: ClassTag[Bind] + val Alternative_CT: ClassTag[Alternative] + val UnApply_CT: ClassTag[UnApply] + val Import_CT: ClassTag[Import] + val PackageDef_CT: ClassTag[PackageDef] + val TypeTree_CT: ClassTag[TypeTree] + val SingletonTypeTree_CT: ClassTag[SingletonTypeTree] + val RefinedTypeTree_CT: ClassTag[RefinedTypeTree] + val AppliedTypeTree_CT: ClassTag[AppliedTypeTree] + val MatchTypeTree_CT: ClassTag[MatchTypeTree] + val ByNameTypeTree_CT: ClassTag[ByNameTypeTree] + val Annotated_CT: ClassTag[Annotated] + val LambdaTypeTree_CT: ClassTag[LambdaTypeTree] + val TypeBoundsTree_CT: ClassTag[TypeBoundsTree] + + type Type <: AnyRef + type AppliedType <: Type // <: CachedProxyType with ValueType + type ConstantType <: Type // <: CachedProxyType with SingletonType + type ClassInfo <: Type // TypeType + type NamedType <: Type // <: CachedProxyType with SingletonType + type ThisType <: Type // SingletonType + type SuperType <: Type // SingletonType + type BoundType <: Type { type BT <: Type } + type RecThis <: BoundType { type BT = RecType } // ValueType + type ParamRef <: BoundType { type BT <: LambdaType } + type RecType <: Type // RefinedOrRecType with BindingType + type RefinedType <: Type + type SkolemType <: Type // SingletonType + type TypeBounds <: Type + type TypeAlias <: TypeBounds // AliasingBounds + type TermRef <: NamedType // SingletonType + type TypeRef <: NamedType // SingletonType + type AnnotatedType <: Type + type AndOrType <: Type + type AndType <: AndOrType + type OrType <: AndOrType + type TypeProxy <: Type + type ExprType <: TypeProxy // Methodic + type MatchType <: Type + type LambdaType <: Type { type ThisName <: Name; type PInfo <: Type } + type HKTypeLambda <: LambdaType // HKLambda with TypeLambda + type PolyType <: LambdaType // MethodOrPoly with TypeLambda + type MethodType <: LambdaType // MethodOrPoly with TermLambda + type LazyRef <: Type + + val Type_CT: ClassTag[Type] + val AppliedType_CT: ClassTag[AppliedType] + val ConstantType_CT: ClassTag[ConstantType] + val NamedType_CT: ClassTag[NamedType] + val ThisType_CT: ClassTag[ThisType] + val SuperType_CT: ClassTag[SuperType] + val RecThis_CT: ClassTag[RecThis] + val RecType_CT: ClassTag[RecType] + val TermRef_CT: ClassTag[TermRef] + val TypeRef_CT: ClassTag[TypeRef] + val ParamRef_CT: ClassTag[ParamRef] + val SkolemType_CT: ClassTag[SkolemType] + val RefinedType_CT: ClassTag[RefinedType] + val TypeAlias_CT: ClassTag[TypeAlias] + val TypeBounds_CT: ClassTag[TypeBounds] + val AnnotatedType_CT: ClassTag[AnnotatedType] + val AndType_CT: ClassTag[AndType] + val OrType_CT: ClassTag[OrType] + val MatchType_CT: ClassTag[MatchType] + val ExprType_CT: ClassTag[ExprType] + val HKTypeLambda_CT: ClassTag[HKTypeLambda] + val PolyType_CT: ClassTag[PolyType] + val MethodType_CT: ClassTag[MethodType] + val LazyRef_CT: ClassTag[LazyRef] + val ClassInfo_CT: ClassTag[ClassInfo] + + type Symbol <: Designator { type ThisName <: Name } + type TermSymbol <: Symbol { type ThisName = TermName } + type TypeSymbol <: Symbol { type ThisName = TypeName } + type ClassSymbol <: TypeSymbol + + type FlagSet <: AnyVal + type Flag <: FlagSet + + val Symbol_CT: ClassTag[Symbol] + val ClassSymbol_CT: ClassTag[ClassSymbol] + + type Symbols_MutableSymbolMap[T] <: AnyRef + + type SourcePosition <: AnyRef + + type Constant + + val Flags_Protected: Flag + val Flags_ParamAccessor: Flag + val Flags_Private: Flag + val Flags_Final: Flag + val Flags_Case: Flag + val Flags_Override: Flag + val Flags_Inline: Flag + val Flags_InlineProxy: Flag + val Flags_Macro: Flag + val Flags_JavaStatic: Flag + val Flags_Module: Flag + val Flags_Enum: Flag + val Flags_Local: Flag + val Flags_Synthetic: Flag + val Flags_Artifact: Flag + val Flags_Scala2x: Flag + val Flags_Implicit: Flag + val Flags_Given: Flag + val Flags_Erased: Flag + val Flags_Lazy: Flag + val Flags_AbsOverride: Flag + val Flags_Mutable: Flag + val Flags_Accessor: Flag + val Flags_CaseAccessor: Flag + val Flags_DefaultParameterized: Flag + val Flags_StableRealizable: Flag + val Flags_Extension: Flag + val Flags_Exported: Flag + val Flags_Label: Flag + val Flags_Sealed: Flag + val Flags_Abstract: Flag + val Flags_Trait: Flag + val Flags_Covariant: Flag + val Flags_Contravariant: Flag + val Flags_Opaque: Flag + val Flags_Open: Flag + + def FlagSet_is(flags: FlagSet, flag: Flag): Boolean + def FlagSet_is(flags: FlagSet, flag: Flag, butNot: FlagSet): Boolean + def FlagSet_&~(flags: FlagSet, flag: Flag): FlagSet + + final val Constants_NoTag = 0 + final val Constants_UnitTag = 1 + final val Constants_BooleanTag = 2 + final val Constants_ByteTag = 3 + final val Constants_ShortTag = 4 + final val Constants_CharTag = 5 + final val Constants_IntTag = 6 + final val Constants_LongTag = 7 + final val Constants_FloatTag = 8 + final val Constants_DoubleTag = 9 + final val Constants_StringTag = 10 + final val Constants_NullTag = 11 + final val Constants_ClazzTag = 12 + final val Constants_EnumTag = 13 + + def Context_log(ctx: Context, msg: => String, sourcePos: SourcePosition): Unit + def Context_source(ctx: Context): Path + + def Constant_tag(c: Constant): Int + def Constant_intValue(c: Constant): Int + def Constant_booleanValue(c: Constant): Boolean + def Constant_byteValue(c: Constant): Byte + def Constant_charValue(c: Constant): Char + def Constant_shortValue(c: Constant): Short + def Constant_longValue(c: Constant): Long + def Constant_doubleValue(c: Constant): Double + def Constant_floatValue(c: Constant): Float + def Constant_stringValue(c: Constant): String + def Constant_typeValue(c: Constant): Type + def Constant_symbolValue(c: Constant): Symbol + + def Symbols_MutableSymbolMap_get[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): Option[T] + def Symbols_MutableSymbolMap_getOrElse[U >: T, T](map: Symbols_MutableSymbolMap[T], sym: Symbol, default: => U): U + def Symbols_MutableSymbolMap_contains[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): Boolean + def Symbols_MutableSymbolMap_update[T](map: Symbols_MutableSymbolMap[T], sym: Symbol, value: T): Unit + def Symbols_MutableSymbolMap_-=[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): Unit + def Symbols_MutableSymbolMap_apply[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): T + def Symbols_MutableSymbolMap_keysIterator[T](map: Symbols_MutableSymbolMap[T]): Iterator[Symbol] + def Symbols_MutableSymbolMap_isEmpty[T](map: Symbols_MutableSymbolMap[T]): Boolean + def Symbols_newMutableSymbolMap[A]: Symbols_MutableSymbolMap[A] + + def Symbol_isPackage(sym: Symbol)(given Context): Boolean + def Symbol_isPrivate(sym: Symbol)(given Context): Boolean + def Symbol_sourcePos(sym: Symbol)(given Context): SourcePosition + def Symbol_owner(sym: Symbol): Symbol + def Symbol_isDefinedWithin(sym: Symbol, outer: Symbol)(given Context): Boolean + def Symbol_termRef(sym: Symbol)(given Context): TermRef + def Symbol_typeRef(sym: Symbol)(given Context): TypeRef + def Symbol_name(sym: Symbol)(given Context): sym.ThisName + def Symbol_fullName(sym: Symbol)(given Context): sym.ThisName + def Symbol_isClass(sym: Symbol): Boolean + def Symbol_exists(sym: Symbol): Boolean + def Symbol_isEffectiveRoot(sym: Symbol)(given Context): Boolean + def Symbol_flags(sym: Symbol)(given Context): FlagSet + def Symbol_privateWithin(sym: Symbol)(given Context): Symbol + def Symbol_isTerm(sym: Symbol)(given Context): Boolean + def Symbol_isSetter(sym: Symbol)(given Context): Boolean + def Symbol_info(sym: Symbol)(given Context): Type + def Symbol_showLocated(sym: Symbol)(given Context): String + def Symbol_annotations(sym: Symbol)(given Context): List[Annotation] + def Symbol_isInaccessibleChildOf(sym: Symbol, cls: Symbol)(given Context): Boolean + + def SourcePosition_line(pos: SourcePosition): Int + + def defn_throwMethod(given Context): TermSymbol + def defn_BodyAnnot(given Context): ClassSymbol + + def Name_toTermName(name: Name): TermName + def Name_isEmpty(name: Name): Boolean + def Name_isTypeName(name: Name): Boolean + def Name_length(name: Name): Int + + def Tree_symbol(tree: Tree)(given Context): Symbol + def Tree_withType(tree: Tree, tpe: Type)(given Context): tree.ThisTree + def Tree_isEmpty(tree: Tree): Boolean + def Tree_isType(tree: Tree): Boolean + def Tree_isInline(tree: Tree): Boolean + def Tree_tpe(tree: Tree): Type + val EmptyTree: Tree + + def TypedSplice_unapply(tree: untpd_TypedSplice): Some[Tree] + def Ident_unapply(tree: Ident): Some[Name] + def This_unapply(tree: This): Some[Ident] + def Select_unapply(tree: Select): (Tree, Name) + def Apply_unapply(tree: Apply): (Tree, List[Tree]) + def TypeApply_unapply(tree: TypeApply): (Tree, List[Tree]) + def Literal_unapply(tree: Literal): Some[Constant] + def Super_unapply(tree: Super): (Tree, Ident) + def New_unapply(tree: New): Some[Tree] + def Typed_unapply(tree: Typed): (Tree, Tree) + def NamedArg_unapply(tree: NamedArg): (Name, Tree) + def Assign_unapply(tree: Assign): (Tree, Tree) + def Block_unapply(tree: Block): (List[Tree], Tree) + def If_unapply(tree: If): (Tree, Tree, Tree) + def Closure_unapply(tree: Closure): (List[Tree], Tree, Tree) + def Match_unapply(tree: Match): (Tree, List[CaseDef]) + def CaseDef_unapply(tree: CaseDef): (Tree, Tree, Tree) + def Return_unapply(tree: Return): (Tree, Tree) + def WhileDo_unapply(tree: WhileDo): (Tree, Tree) + def Try_unapply(tree: Try): (Tree, List[CaseDef], Tree) + def SeqLiteral_unapply(tree: SeqLiteral): (List[Tree], Tree) + def Inlined_unapply(tree: Inlined): (Tree, List[MemberDef], Tree) + def Bind_unapply(tree: Bind): (Name, Tree) + def Alternative_unapply(tree: Alternative): Some[List[Tree]] + def UnApply_unapply(tree: UnApply): (Tree, List[Tree], List[Tree]) + def Import_unapply(tree: Import): (Tree, List[untpd_ImportSelector]) + def PackageDef_unapply(tree: PackageDef): (RefTree, List[Tree]) + def SingletonTypeTree_unapply(tree: SingletonTypeTree): Some[Tree] + def RefinedTypeTree_unapply(tree: RefinedTypeTree): (Tree, List[Tree]) + def AppliedTypeTree_unapply(tree: AppliedTypeTree): (Tree, List[Tree]) + def MatchTypeTree_unapply(tree: MatchTypeTree): (Tree, Tree, List[CaseDef]) + def ByNameTypeTree_unapply(tree: ByNameTypeTree): Some[Tree] + def Annotated_unapply(tree: Annotated): (Tree, Tree) + def LambdaTypeTree_unapply(tree: LambdaTypeTree): (List[TypeDef], Tree) + def TypeBoundsTree_unapply(tree: TypeBoundsTree): (Tree, Tree) + def Hole_unapply(tree: Hole): (Int, List[Tree]) + + def ValOrDefDef_name(tree: ValOrDefDef): TermName + def ValOrDefDef_tpt(tree: ValOrDefDef): Tree + def ValOrDefDef_rhs(tree: ValOrDefDef)(given Context): Tree + def DefDef_tparams(tree: DefDef): List[TypeDef] + def DefDef_vparamss(tree: DefDef): List[List[ValDef]] + def TypeDef_rhs(tree: TypeDef): Tree + + def ImportSelector_imported(tree: untpd_ImportSelector): Ident + def ImportSelector_renamed(tree: untpd_ImportSelector): Tree + def ImportSelector_bound(tree: untpd_ImportSelector): untpd_Tree + + def Template_decomposeBody(tree: Template)(given Context): (List[Tree], List[Tree]) + def Template_parents(tree: Template): List[Tree] + def Template_self(tree: Template): ValDef + def Template_constr(tree: Template): DefDef + + def Type_stripTypeVar(tpe: Type)(given Context): Type + def Type_member(tpe: Type, name: Name)(given Context): Symbol // Denotation in dotty + def Type_signature(tpe: Type)(given Context): Signature + def Type_isContextualMethod(tpe: Type): Boolean + def Type_isImplicitMethod(tpe: Type): Boolean + def Type_isErasedMethod(tpe: Type): Boolean + def Type_exists(tpe: Type): Boolean + + def AppliedType_unapply(tpe: AppliedType): (Type, List[Type]) + + def ConstantType_value(tpe: ConstantType): Constant + + def ThisType_cls(tpe: ThisType)(given Context): ClassSymbol + def ThisType_tref(tpe: ThisType): TypeRef + + def SuperType_thistpe(tpe: SuperType): Type + def SuperType_supertpe(tpe: SuperType): Type + + def BoundType_binder(tpe: BoundType): tpe.BT + + def ParamRef_paramNum(tpe: ParamRef): Int + + def RecType_parent(tpe: RecType): Type + + def RefinedType_parent(tpe: RefinedType): Type + def RefinedType_refinedName(tpe: RefinedType): Name + def RefinedType_refinedInfo(tpe: RefinedType): Type + + def SkolemType_info(tpe: SkolemType): Type + + def NamedType_symbol(tpe: NamedType)(given Context): Symbol + def NamedType_prefix(tpe: NamedType): Type + def NamedType_designator(tpe: NamedType): Designator + def NamedType_hasNoPrefix(tpe: Type): Boolean + def NamedType_isType(tpe: NamedType): Boolean + + def TypeAlias_alias(tpe: TypeAlias): Type + + def TypeBounds_hi(tpe: TypeBounds): Type + def TypeBounds_lo(tpe: TypeBounds): Type + + def AnnotatedType_parent(tpe: AnnotatedType): Type + def AnnotatedType_annot(tpe: AnnotatedType): Annotation + + def Annotation_tree(annot: Annotation)(given Context): Tree + def Annotation_symbol(annot: Annotation)(given Context): Symbol + def Annotation_Child_unapply(annot: Annotation)(given Context): Option[Symbol] + + def AndOrType_tp1(tpe: AndOrType): Type + def AndOrType_tp2(tpe: AndOrType): Type + + def TypeProxy_underlying(tpe: TypeProxy)(given Context): Type + + def LambdaType_resultType(tpe: LambdaType)(given Context): Type + def LambdaType_paramNames(tpe: LambdaType): List[tpe.ThisName] + def LambdaType_paramInfos(tpe: LambdaType): List[tpe.PInfo] + + def MatchType_bound(tpe: MatchType): Type + def MatchType_scrutinee(tpe: MatchType): Type + def MatchType_cases(tpe: MatchType): List[Type] + + def ClassInfo_selfInfo(tpe: ClassInfo): Either[Type, Symbol] + + def LazyRef_ref(tpe: LazyRef)(given Context): Type + + def TermName_tag(name: TermName): Int + + def SimpleName_toUTF8(name: SimpleName): Array[Byte] + + def String_toTermName(name: String): TermName + + def SignedName_unapply(name: DerivedName): Option[(TermName, Signature)] + def SignedName_apply(name: TermName, sig: Signature): TermName + + def AnyQualifiedName_unapply(name: DerivedName): Option[(TermName, SimpleName)] + def AnyUniqueName_unapply(name: DerivedName): Option[(TermName, String, Int)] + def AnyNumberedName_unapply(name: DerivedName): Option[(TermName, Int)] + def OuterSelectName_unapply(name: DerivedName): Option[(TermName, Int)] + def DerivedName_unapply(name: DerivedName): Some[TermName] + + val nme_WILDCARD: TermName + + def Signature_ParamSig_fold[A](paramSig: Signature_ParamSig)(onInt: Int => A, onTypeName: TypeName => A): A + def Signature_ParamSig_foldInt(paramSig: Signature_ParamSig)(onInt: IntToInt, onTypeName: ToInt[TypeName]): Int + def Signature_isNotAMethod(sig: Signature): Boolean + + def Signature_unapply(signature: Signature): (List[Signature_ParamSig], TypeName) + + def pickling_println(msg: => String): Unit + + def StringContext_i(stringContext: StringContext, args: Any*): String diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala new file mode 100644 index 000000000000..4917c8ebbb89 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala @@ -0,0 +1,168 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait TreeOps extends Core with + self => + + given ClassTag[Tree] = internal.Tree_CT + given ClassTag[MemberDef] = internal.MemberDef_CT + given ClassTag[Hole] = internal.Hole_CT + given ClassTag[Template] = internal.Template_CT + given ClassTag[ValOrDefDef] = internal.ValOrDefDef_CT + given ClassTag[TypeDef] = internal.TypeDef_CT + given ClassTag[ValDef] = internal.ValDef_CT + given ClassTag[DefDef] = internal.DefDef_CT + given ClassTag[Ident] = internal.Ident_CT + given ClassTag[This] = internal.This_CT + given ClassTag[Select] = internal.Select_CT + given ClassTag[Apply] = internal.Apply_CT + given ClassTag[TypeApply] = internal.TypeApply_CT + given ClassTag[Literal] = internal.Literal_CT + given ClassTag[Super] = internal.Super_CT + given ClassTag[New] = internal.New_CT + given ClassTag[Typed] = internal.Typed_CT + given ClassTag[NamedArg] = internal.NamedArg_CT + given ClassTag[Assign] = internal.Assign_CT + given ClassTag[Block] = internal.Block_CT + given ClassTag[If] = internal.If_CT + given ClassTag[Closure] = internal.Closure_CT + given ClassTag[Match] = internal.Match_CT + given ClassTag[CaseDef] = internal.CaseDef_CT + given ClassTag[Return] = internal.Return_CT + given ClassTag[WhileDo] = internal.WhileDo_CT + given ClassTag[Try] = internal.Try_CT + given ClassTag[SeqLiteral] = internal.SeqLiteral_CT + given ClassTag[Inlined] = internal.Inlined_CT + given ClassTag[Bind] = internal.Bind_CT + given ClassTag[Alternative] = internal.Alternative_CT + given ClassTag[UnApply] = internal.UnApply_CT + given ClassTag[Import] = internal.Import_CT + given ClassTag[PackageDef] = internal.PackageDef_CT + given ClassTag[TypeTree] = internal.TypeTree_CT + given ClassTag[SingletonTypeTree] = internal.SingletonTypeTree_CT + given ClassTag[RefinedTypeTree] = internal.RefinedTypeTree_CT + given ClassTag[AppliedTypeTree] = internal.AppliedTypeTree_CT + given ClassTag[MatchTypeTree] = internal.MatchTypeTree_CT + given ClassTag[ByNameTypeTree] = internal.ByNameTypeTree_CT + given ClassTag[Annotated] = internal.Annotated_CT + given ClassTag[LambdaTypeTree] = internal.LambdaTypeTree_CT + given ClassTag[TypeBoundsTree] = internal.TypeBoundsTree_CT + + object untpd with + + type Tree = internal.untpd_Tree + type TypedSplice = internal.untpd_TypedSplice + type ImportSelector = internal.untpd_ImportSelector + + given ClassTag[Tree] = internal.untpd_Tree_CT + given ClassTag[TypedSplice] = internal.untpd_TypedSplice_CT + + object TypedSplice with + def unapply(tree: TypedSplice): Some[self.Tree] = internal.TypedSplice_unapply(tree) + + given ImportSelectorOps: (tree: ImportSelector) with + def imported: Ident = internal.ImportSelector_imported(tree) + def renamed: self.Tree = internal.ImportSelector_renamed(tree) + def bound: Tree = internal.ImportSelector_bound(tree) + + end untpd + + object Ident with + def unapply(tree: Ident): Some[Name] = internal.Ident_unapply(tree) + object This with + def unapply(tree: This): Some[Ident] = internal.This_unapply(tree) + object Select with + def unapply(tree: Select): (Tree, Name) = internal.Select_unapply(tree) + object Apply with + def unapply(tree: Apply): (Tree, List[Tree]) = internal.Apply_unapply(tree) + object TypeApply with + def unapply(tree: TypeApply): (Tree, List[Tree]) = internal.TypeApply_unapply(tree) + object Literal with + def unapply(tree: Literal): Some[Constant] = internal.Literal_unapply(tree) + object Super with + def unapply(tree: Super): (Tree, Ident) = internal.Super_unapply(tree) + object New with + def unapply(tree: New): Some[Tree] = internal.New_unapply(tree) + object Typed with + def unapply(tree: Typed): (Tree, Tree) = internal.Typed_unapply(tree) + object NamedArg with + def unapply(tree: NamedArg): (Name, Tree) = internal.NamedArg_unapply(tree) + object Assign with + def unapply(tree: Assign): (Tree, Tree) = internal.Assign_unapply(tree) + object Block with + def unapply(tree: Block): (List[Tree], Tree) = internal.Block_unapply(tree) + object If with + def unapply(tree: If): (Tree, Tree, Tree) = internal.If_unapply(tree) + object Closure with + def unapply(tree: Closure): (List[Tree], Tree, Tree) = internal.Closure_unapply(tree) + object Match with + def unapply(tree: Match): (Tree, List[CaseDef]) = internal.Match_unapply(tree) + object CaseDef with + def unapply(tree: CaseDef): (Tree, Tree, Tree) = internal.CaseDef_unapply(tree) + object Return with + def unapply(tree: Return): (Tree, Tree) = internal.Return_unapply(tree) + object WhileDo with + def unapply(tree: WhileDo): (Tree, Tree) = internal.WhileDo_unapply(tree) + object Try with + def unapply(tree: Try): (Tree, List[CaseDef], Tree) = internal.Try_unapply(tree) + object SeqLiteral with + def unapply(tree: SeqLiteral): (List[Tree], Tree) = internal.SeqLiteral_unapply(tree) + object Inlined with + def unapply(tree: Inlined): (Tree, List[MemberDef], Tree) = internal.Inlined_unapply(tree) + object Bind with + def unapply(tree: Bind): (Name, Tree) = internal.Bind_unapply(tree) + object Alternative with + def unapply(tree: Alternative): Some[List[Tree]] = internal.Alternative_unapply(tree) + object UnApply with + def unapply(tree: UnApply): (Tree, List[Tree], List[Tree]) = internal.UnApply_unapply(tree) + object Import with + def unapply(tree: Import): (Tree, List[untpd.ImportSelector]) = internal.Import_unapply(tree) + object PackageDef with + def unapply(tree: PackageDef): (RefTree, List[Tree]) = internal.PackageDef_unapply(tree) + object SingletonTypeTree with + def unapply(tree: SingletonTypeTree): Some[Tree] = internal.SingletonTypeTree_unapply(tree) + object RefinedTypeTree with + def unapply(tree: RefinedTypeTree): (Tree, List[Tree]) = internal.RefinedTypeTree_unapply(tree) + object AppliedTypeTree with + def unapply(tree: AppliedTypeTree): (Tree, List[Tree]) = internal.AppliedTypeTree_unapply(tree) + object MatchTypeTree with + def unapply(tree: MatchTypeTree): (Tree, Tree, List[CaseDef]) = internal.MatchTypeTree_unapply(tree) + object ByNameTypeTree with + def unapply(tree: ByNameTypeTree): Some[Tree] = internal.ByNameTypeTree_unapply(tree) + object Annotated with + def unapply(tree: Annotated): (Tree, Tree) = internal.Annotated_unapply(tree) + object LambdaTypeTree with + def unapply(tree: LambdaTypeTree): (List[TypeDef], Tree) = internal.LambdaTypeTree_unapply(tree) + object TypeBoundsTree with + def unapply(tree: TypeBoundsTree): (Tree, Tree) = internal.TypeBoundsTree_unapply(tree) + object Hole with + def unapply(tree: Hole): (Int, List[Tree]) = internal.Hole_unapply(tree) + + given TreeOps: (tree: Tree) with + def symbol(given Context): Symbol = internal.Tree_symbol(tree) + def isEmpty: Boolean = internal.Tree_isEmpty(tree) + def isType: Boolean = internal.Tree_isType(tree) + def withType(tpe: Type)(given Context): tree.ThisTree = internal.Tree_withType(tree, tpe) + def isInline: Boolean = internal.Tree_isInline(tree) + def tpe: Type = internal.Tree_tpe(tree) + + given ValOrDefDefOps: (tree: ValOrDefDef) with + def name: TermName = internal.ValOrDefDef_name(tree) + def tpt: Tree = internal.ValOrDefDef_tpt(tree) + def rhs(given Context): Tree = internal.ValOrDefDef_rhs(tree) + + given DefDefOps: (tree: DefDef) with + def tparams: List[TypeDef] = internal.DefDef_tparams(tree) + def vparamss: List[List[ValDef]] = internal.DefDef_vparamss(tree) + + given TypeDefOps: (tree: TypeDef) with + def rhs: Tree = internal.TypeDef_rhs(tree) + + given TemplateOps: (tree: Template) with + def decomposeBody(given Context): (List[Tree], List[Tree]) = internal.Template_decomposeBody(tree) + def parents: List[Tree] = internal.Template_parents(tree) + def self: ValDef = internal.Template_self(tree) + def constr: DefDef = internal.Template_constr(tree) + + final val EmptyTree = internal.EmptyTree diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala new file mode 100644 index 000000000000..ffb0c73c11fb --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala @@ -0,0 +1,112 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait TypeOps extends Core with + + given ClassTag[Type] = internal.Type_CT + given ClassTag[AppliedType] = internal.AppliedType_CT + given ClassTag[ConstantType] = internal.ConstantType_CT + given ClassTag[NamedType] = internal.NamedType_CT + given ClassTag[ThisType] = internal.ThisType_CT + given ClassTag[SuperType] = internal.SuperType_CT + given ClassTag[RecThis] = internal.RecThis_CT + given ClassTag[RecType] = internal.RecType_CT + given ClassTag[ParamRef] = internal.ParamRef_CT + given ClassTag[SkolemType] = internal.SkolemType_CT + given ClassTag[RefinedType] = internal.RefinedType_CT + given ClassTag[TypeAlias] = internal.TypeAlias_CT + given ClassTag[TypeBounds] = internal.TypeBounds_CT + given ClassTag[AnnotatedType] = internal.AnnotatedType_CT + given ClassTag[AndType] = internal.AndType_CT + given ClassTag[OrType] = internal.OrType_CT + given ClassTag[MatchType] = internal.MatchType_CT + given ClassTag[ExprType] = internal.ExprType_CT + given ClassTag[HKTypeLambda] = internal.HKTypeLambda_CT + given ClassTag[PolyType] = internal.PolyType_CT + given ClassTag[MethodType] = internal.MethodType_CT + given ClassTag[TermRef] = internal.TermRef_CT + given ClassTag[TypeRef] = internal.TypeRef_CT + given ClassTag[LazyRef] = internal.LazyRef_CT + given ClassTag[ClassInfo] = internal.ClassInfo_CT + + object AppliedType with + def unapply(tpe: AppliedType): (Type, List[Type]) = internal.AppliedType_unapply(tpe) + + given TypeOps: (tpe: Type) with + def stripTypeVar(given Context): Type = internal.Type_stripTypeVar(tpe) + def signature(given Context): Signature = internal.Type_signature(tpe) + def member(name: Name)(given Context): Symbol = internal.Type_member(tpe, name) + def isContextualMethod: Boolean = internal.Type_isContextualMethod(tpe) + def isImplicitMethod: Boolean = internal.Type_isImplicitMethod(tpe) + def isErasedMethod: Boolean = internal.Type_isErasedMethod(tpe) + def exists: Boolean = internal.Type_exists(tpe) + + given ConstantTypeOps: (tpe: ConstantType) with + def value: Constant = internal.ConstantType_value(tpe) + + given SuperTypeOps: (tpe: SuperType) with + def thistpe: Type = internal.SuperType_thistpe(tpe) + def supertpe: Type = internal.SuperType_supertpe(tpe) + + given ThisTypeOps: (tpe: ThisType) with + def cls(given Context): ClassSymbol = internal.ThisType_cls(tpe) + def tref: TypeRef = internal.ThisType_tref(tpe) + + given SkolemTypeOps: (tpe: SkolemType) with + def info: Type = internal.SkolemType_info(tpe) + + given BoundTypeOps: (tpe: BoundType) with + def binder: tpe.BT = internal.BoundType_binder(tpe) + + given ParamRefOps: (tpe: ParamRef) with + def paramNum: Int = internal.ParamRef_paramNum(tpe) + + given RecTypeOps: (tpe: RecType) with + def parent: Type = internal.RecType_parent(tpe) + + given RefinedTypeOps: (tpe: RefinedType) with + def parent: Type = internal.RefinedType_parent(tpe) + def refinedInfo: Type = internal.RefinedType_refinedInfo(tpe) + def refinedName: Name = internal.RefinedType_refinedName(tpe) + + given TypeBoundsOps: (tpe: TypeBounds) with + def hi: Type = internal.TypeBounds_hi(tpe) + def lo: Type = internal.TypeBounds_lo(tpe) + + given TypeAliasOps: (tpe: TypeAlias) with + def alias: Type = internal.TypeAlias_alias(tpe) + + given NamedTypeOps: (tpe: NamedType) with + def symbol(given Context): Symbol = internal.NamedType_symbol(tpe) + def prefix: Type = internal.NamedType_prefix(tpe) + def designator: Designator = internal.NamedType_designator(tpe) + def hasNoPrefix: Boolean = internal.NamedType_hasNoPrefix(tpe) + def isType: Boolean = internal.NamedType_isType(tpe) + + given AnnotatedTypeOps: (tpe: AnnotatedType) with + def parent: Type = internal.AnnotatedType_parent(tpe) + def annot: Annotation = internal.AnnotatedType_annot(tpe) + + given AndOrTypeOps: (tpe: AndOrType) with + def tp1: Type = internal.AndOrType_tp1(tpe) + def tp2: Type = internal.AndOrType_tp2(tpe) + + given TypeProxyOps: (tpe: TypeProxy) with + def underlying(given Context): Type = internal.TypeProxy_underlying(tpe) + + given MatchTypeOps: (tpe: MatchType) with + def bound: Type = internal.MatchType_bound(tpe) + def scrutinee: Type = internal.MatchType_scrutinee(tpe) + def cases: List[Type] = internal.MatchType_cases(tpe) + + given LambdaTypeOps: (tpe: LambdaType) with + def resultType(given Context): Type = internal.LambdaType_resultType(tpe) + def paramNames: List[tpe.ThisName] = internal.LambdaType_paramNames(tpe) + def paramInfos: List[tpe.PInfo] = internal.LambdaType_paramInfos(tpe) + + given LazyRefOps: (tpe: LazyRef) with + def ref(given Context): Type = internal.LazyRef_ref(tpe) + + given ClassInfoOps: (tpe: ClassInfo) with + def selfInfo: Either[Type, Symbol] = internal.ClassInfo_selfInfo(tpe) diff --git a/tasty/src/dotty/tools/tasty/experimental/function/IntToInt.scala b/tasty/src/dotty/tools/tasty/experimental/function/IntToInt.scala new file mode 100644 index 000000000000..a7c0e7046936 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/function/IntToInt.scala @@ -0,0 +1,5 @@ +package dotty.tools.tasty.experimental.function + + @FunctionalInterface + trait IntToInt with + def apply(int: Int): Int diff --git a/tasty/src/dotty/tools/tasty/experimental/function/ToInt.scala b/tasty/src/dotty/tools/tasty/experimental/function/ToInt.scala new file mode 100644 index 000000000000..c20541a56da4 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/function/ToInt.scala @@ -0,0 +1,5 @@ +package dotty.tools.tasty.experimental.function + + @FunctionalInterface + trait ToInt[A] with + def apply(a: A): Int diff --git a/tasty/src/dotty/tools/tasty/experimental/util/Util.scala b/tasty/src/dotty/tools/tasty/experimental/util/Util.scala new file mode 100644 index 000000000000..89a35bb10e68 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/util/Util.scala @@ -0,0 +1,14 @@ +package dotty.tools.tasty.experimental.util + +object Util with + def bestFit(candidates: Array[Int], length: Int, x: Int, hint: Int = -1): Int = { + def recur(lo: Int, hi: Int, mid: Int): Int = + if (x < candidates(mid)) + recur(lo, mid - 1, (lo + mid - 1) / 2) + else if (mid + 1 < length && x >= candidates(mid + 1)) + recur(mid + 1, hi, (mid + 1 + hi) / 2) + else mid + val initMid = if (0 <= hint && hint < length) hint else length / 2 + if (length == 0 || x < candidates(0)) -1 + else recur(0, length, initMid) + } From 06e714e671b4e866660474822f44e25da976eef7 Mon Sep 17 00:00:00 2001 From: bishabosha Date: Sat, 30 Nov 2019 19:48:57 +0100 Subject: [PATCH 2/8] abstract comment and position picklers --- .../dotc/core/quoted/PickledQuotes.scala | 3 +- .../tools/dotc/core/tasty/NameBuffer.scala | 114 -- .../tools/dotc/core/tasty/TastyPickler.scala | 82 - .../tools/dotc/core/tasty/TreeBuffer.scala | 192 --- .../tools/dotc/core/tasty/TreePickler.scala | 1376 ++++++++--------- .../dotty/tools/dotc/transform/Pickler.scala | 4 +- .../tasty/experimental}/CommentPickler.scala | 22 +- .../tasty/experimental}/PositionPickler.scala | 58 +- .../tools/tasty/experimental/Tasty.scala | 2 + .../tasty/experimental/TastyPickler.scala | 10 +- .../tasty/experimental/TreePickler.scala | 6 +- .../experimental/bridge/AnnotationOps.scala | 2 + .../experimental/bridge/CommentOps.scala | 9 + .../experimental/bridge/ContextOps.scala | 8 +- .../tasty/experimental/bridge/Core.scala | 14 +- .../experimental/bridge/PositionOps.scala | 21 +- .../experimental/bridge/SourceFileOps.scala | 12 + .../experimental/bridge/TastyKernel.scala | 61 +- .../tasty/experimental/bridge/TreeOps.scala | 140 +- 19 files changed, 982 insertions(+), 1154 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala delete mode 100644 compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala delete mode 100644 compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala rename {compiler/src/dotty/tools/dotc/core/tasty => tasty/src/dotty/tools/tasty/experimental}/CommentPickler.scala (53%) rename {compiler/src/dotty/tools/dotc/core/tasty => tasty/src/dotty/tools/tasty/experimental}/PositionPickler.scala (64%) create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala create mode 100644 tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 73dc082bfe00..0c566c674744 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -12,11 +12,12 @@ 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.{ PositionPickler, TastyPrinter } import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode import dotty.tools.dotc.quoted.QuoteContext import dotty.tools.dotc.tastyreflect.{ReflectionImpl, TastyTreeExpr, TreeType} +import dotty.tools.tasty.experimental.TastyPickler import dotty.tools.tasty.TastyString import scala.internal.quoted._ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala b/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala deleted file mode 100644 index 63b724b051f8..000000000000 --- a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala +++ /dev/null @@ -1,114 +0,0 @@ -package dotty.tools -package dotc -package core -package tasty - -import dotty.tools.tasty.TastyBuffer -import TastyBuffer._ - -import collection.mutable -import Names.{Name, chrs, SimpleName, DerivedName, TypeName} -import NameKinds._ -import Decorators._ -import scala.io.Codec - -class NameBuffer extends TastyBuffer(10000) { - import NameBuffer._ - - private val nameRefs = new mutable.LinkedHashMap[Name, NameRef] - - def nameIndex(name: Name): NameRef = { - val name1 = name.toTermName - nameRefs.get(name1) match { - case Some(ref) => - ref - case None => - name1 match { - case SignedName(original, Signature(params, result)) => - nameIndex(original) - nameIndex(result) - params.foreach { - case param: TypeName => - nameIndex(param) - case _ => - } - case AnyQualifiedName(prefix, name) => - nameIndex(prefix); nameIndex(name) - case AnyUniqueName(original, separator, num) => - nameIndex(separator.toTermName) - if (!original.isEmpty) nameIndex(original) - case DerivedName(original, _) => - nameIndex(original) - case _ => - } - val ref = NameRef(nameRefs.size) - nameRefs(name1) = ref - ref - } - } - - private def withLength(op: => Unit, lengthWidth: Int = 1): Unit = { - val lengthAddr = currentAddr - for (i <- 0 until lengthWidth) writeByte(0) - op - val length = currentAddr.index - lengthAddr.index - lengthWidth - putNat(lengthAddr, length, lengthWidth) - } - - def writeNameRef(ref: NameRef): Unit = writeNat(ref.index) - def writeNameRef(name: Name): Unit = writeNameRef(nameRefs(name.toTermName)) - - def writeParamSig(paramSig: Signature.ParamSig): Unit ={ - val encodedValue = paramSig match { - case paramSig: TypeName => - nameRefs(paramSig.toTermName).index - case paramSig: Int => - -paramSig - } - writeInt(encodedValue) - } - - def pickleNameContents(name: Name): Unit = { - val tag = name.toTermName.info.kind.tag - writeByte(tag) - name.toTermName match { - case name: SimpleName => - val bytes = - if (name.length == 0) new Array[Byte](0) - else Codec.toUTF8(chrs, name.start, name.length) - writeNat(bytes.length) - writeBytes(bytes, bytes.length) - case AnyQualifiedName(prefix, name) => - withLength { writeNameRef(prefix); writeNameRef(name) } - case AnyUniqueName(original, separator, num) => - withLength { - writeNameRef(separator.toTermName) - writeNat(num) - if (!original.isEmpty) writeNameRef(original) - } - case AnyNumberedName(original, num) => - withLength { writeNameRef(original); writeNat(num) } - case SignedName(original, Signature(paramsSig, result)) => - withLength( - { writeNameRef(original); writeNameRef(result); paramsSig.foreach(writeParamSig) }, - if ((paramsSig.length + 2) * maxIndexWidth <= maxNumInByte) 1 else 2) - case DerivedName(original, _) => - withLength { writeNameRef(original) } - } - } - - override def assemble(): Unit = { - var i = 0 - for ((name, ref) <- nameRefs) { - assert(ref.index == i) - i += 1 - pickleNameContents(name) - } - } -} - -object NameBuffer { - private val maxIndexWidth = 3 // allows name indices up to 2^21. - private val payloadBitsPerByte = 7 // determined by nat encoding in TastyBuffer - private val maxNumInByte = (1 << payloadBitsPerByte) - 1 -} diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala deleted file mode 100644 index 3ae6cb79510d..000000000000 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala +++ /dev/null @@ -1,82 +0,0 @@ -package dotty.tools -package dotc -package core -package tasty - -import dotty.tools.tasty.{TastyBuffer, TastyFormat, TastyHash} -import TastyFormat._ -import TastyBuffer._ - -import collection.mutable -import core.Symbols.{Symbol, ClassSymbol} -import ast.tpd -import Decorators._ - -class TastyPickler(val rootCls: ClassSymbol) { - - private val sections = new mutable.ArrayBuffer[(NameRef, TastyBuffer)] - - val nameBuffer: NameBuffer = new NameBuffer - - def newSection(name: String, buf: TastyBuffer): Unit = - sections += ((nameBuffer.nameIndex(name.toTermName), buf)) - - def assembleParts(): Array[Byte] = { - def lengthWithLength(buf: TastyBuffer) = - buf.length + natSize(buf.length) - - nameBuffer.assemble() - sections.foreach(_._2.assemble()) - - val nameBufferHash = TastyHash.pjwHash64(nameBuffer.bytes) - val treeSectionHash +: otherSectionHashes = sections.map(x => TastyHash.pjwHash64(x._2.bytes)) - - // Hash of name table and tree - val uuidLow: Long = nameBufferHash ^ treeSectionHash - // Hash of positions, comments and any additional section - val uuidHi: Long = otherSectionHashes.fold(0L)(_ ^ _) - - val headerBuffer = { - val buf = new TastyBuffer(header.length + 24) - for (ch <- header) buf.writeByte(ch.toByte) - buf.writeNat(MajorVersion) - buf.writeNat(MinorVersion) - buf.writeUncompressedLong(uuidLow) - buf.writeUncompressedLong(uuidHi) - buf - } - - val totalSize = - headerBuffer.length + - lengthWithLength(nameBuffer) + { - for ((nameRef, buf) <- sections) yield - natSize(nameRef.index) + lengthWithLength(buf) - }.sum - val all = new TastyBuffer(totalSize) - all.writeBytes(headerBuffer.bytes, headerBuffer.length) - all.writeNat(nameBuffer.length) - all.writeBytes(nameBuffer.bytes, nameBuffer.length) - for ((nameRef, buf) <- sections) { - all.writeNat(nameRef.index) - all.writeNat(buf.length) - all.writeBytes(buf.bytes, buf.length) - } - assert(all.length == totalSize && all.bytes.length == totalSize, s"totalSize = $totalSize, all.length = ${all.length}, all.bytes.length = ${all.bytes.length}") - all.bytes - } - - /** The address in the TASTY file of a given tree, or None if unknown. - * Note that trees are looked up by reference equality, - * so one can reliably use this function only directly after `pickler`. - */ - var addrOfTree: tpd.Tree => Addr = (_ => NoAddr) - - /** - * Addresses in TASTY file of symbols, stored by pickling. - * Note that trees are checked for reference equality, - * so one can reliably use this function only dirrectly after `pickler` - */ - var addrOfSym: Symbol => Option[Addr] = (_ => None) - - val treePkl: TreePickler = new TreePickler(this) -} diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala deleted file mode 100644 index 345dde2aad75..000000000000 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala +++ /dev/null @@ -1,192 +0,0 @@ -package dotty.tools -package dotc -package core -package tasty - -import dotty.tools.tasty.util.Util.dble -import dotty.tools.tasty.TastyBuffer -import TastyBuffer.{Addr, NoAddr, AddrWidth} - -import util.Util.bestFit -import config.Printers.pickling -import ast.untpd.Tree - -class TreeBuffer extends TastyBuffer(50000) { - - private final val ItemsOverOffsets = 2 - private val initialOffsetSize = bytes.length / (AddrWidth * ItemsOverOffsets) - private var offsets = new Array[Int](initialOffsetSize) - private var isRelative = new Array[Boolean](initialOffsetSize) - private var delta: Array[Int] = _ - private var numOffsets = 0 - - /** A map from trees to the address at which a tree is pickled. */ - private val treeAddrs = new java.util.IdentityHashMap[Tree, Any] // really: Addr | Null - - def registerTreeAddr(tree: Tree): Addr = treeAddrs.get(tree) match { - case null => treeAddrs.put(tree, currentAddr); currentAddr - case addr: Addr => addr - } - - def addrOfTree(tree: Tree): Addr = treeAddrs.get(tree) match { - case null => NoAddr - case addr: Addr => addr - } - - private def offset(i: Int): Addr = Addr(offsets(i)) - - private def keepOffset(relative: Boolean): Unit = { - if (numOffsets == offsets.length) { - offsets = dble(offsets) - isRelative = dble(isRelative) - } - offsets(numOffsets) = length - isRelative(numOffsets) = relative - numOffsets += 1 - } - - /** Reserve space for a reference, to be adjusted later */ - def reserveRef(relative: Boolean): Addr = { - val addr = currentAddr - keepOffset(relative) - reserveAddr() - addr - } - - /** Write reference right adjusted into freshly reserved field. */ - def writeRef(target: Addr): Unit = { - keepOffset(relative = false) - fillAddr(reserveAddr(), target) - } - - /** Fill previously reserved field with a reference */ - def fillRef(at: Addr, target: Addr, relative: Boolean): Unit = { - val addr = if (relative) target.relativeTo(at) else target - fillAddr(at, addr) - } - - /** The amount by which the bytes at the given address are shifted under compression */ - def deltaAt(at: Addr): Int = { - val idx = bestFit(offsets, numOffsets, at.index - 1) - if (idx < 0) 0 else delta(idx) - } - - /** The address to which `x` is translated under compression */ - def adjusted(x: Addr): Addr = x - deltaAt(x) - - /** Compute all shift-deltas */ - private def computeDeltas() = { - delta = new Array[Int](numOffsets) - var lastDelta = 0 - var i = 0 - while (i < numOffsets) { - val off = offset(i) - val skippedOff = skipZeroes(off) - val skippedCount = skippedOff.index - off.index - assert(skippedCount < AddrWidth, s"unset field at position $off") - lastDelta += skippedCount - delta(i) = lastDelta - i += 1 - } - } - - /** The absolute or relative adjusted address at index `i` of `offsets` array*/ - private def adjustedOffset(i: Int): Addr = { - val at = offset(i) - val original = getAddr(at) - if (isRelative(i)) { - val start = skipNat(at) - val len1 = original + delta(i) - deltaAt(original + start.index) - val len2 = adjusted(original + start.index) - adjusted(start).index - assert(len1 == len2, - s"adjusting offset #$i: $at, original = $original, len1 = $len1, len2 = $len2") - len1 - } - else adjusted(original) - } - - /** Adjust all offsets according to previously computed deltas */ - private def adjustOffsets(): Unit = - for (i <- 0 until numOffsets) { - val corrected = adjustedOffset(i) - fillAddr(offset(i), corrected) - } - - /** Adjust deltas to also take account references that will shrink (and thereby - * generate additional zeroes that can be skipped) due to previously - * computed adjustments. - */ - private def adjustDeltas(): Int = { - val delta1 = new Array[Int](delta.length) - var lastDelta = 0 - var i = 0 - while (i < numOffsets) { - val corrected = adjustedOffset(i) - lastDelta += AddrWidth - TastyBuffer.natSize(corrected.index) - delta1(i) = lastDelta - i += 1 - } - val saved = - if (numOffsets == 0) 0 - else delta1(numOffsets - 1) - delta(numOffsets - 1) - delta = delta1 - saved - } - - /** Compress pickle buffer, shifting bytes to close all skipped zeroes. */ - private def compress(): Int = { - var lastDelta = 0 - var start = 0 - var i = 0 - var wasted = 0 - def shift(end: Int) = - System.arraycopy(bytes, start, bytes, start - lastDelta, end - start) - while (i < numOffsets) { - val next = offsets(i) - shift(next) - start = next + delta(i) - lastDelta - val pastZeroes = skipZeroes(Addr(next)).index - assert(pastZeroes >= start, s"something's wrong: eliminated non-zero") - wasted += (pastZeroes - start) - lastDelta = delta(i) - i += 1 - } - shift(length) - length -= lastDelta - wasted - } - - def adjustTreeAddrs(): Unit = { - val it = treeAddrs.keySet.iterator - while (it.hasNext) { - val tree = it.next - treeAddrs.get(tree) match { - case addr: Addr => treeAddrs.put(tree, adjusted(addr)) - } - } - } - - /** Final assembly, involving the following steps: - * - compute deltas - * - adjust deltas until additional savings are < 1% of total - * - adjust offsets according to the adjusted deltas - * - shrink buffer, skipping zeroes. - */ - def compactify(): Unit = { - val origLength = length - computeDeltas() - //println(s"offsets: ${offsets.take(numOffsets).deep}") - //println(s"deltas: ${delta.take(numOffsets).deep}") - var saved = 0 - while ({ - saved = adjustDeltas() - pickling.println(s"adjusting deltas, saved = $saved") - saved > 0 && length / saved < 100 - }) - () - adjustOffsets() - adjustTreeAddrs() - val wasted = compress() - pickling.println(s"original length: $origLength, compressed to: $length, wasted: $wasted") // DEBUG, for now. - } -} diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index f4edb6c0057b..899b240320c9 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -3,16 +3,8 @@ package dotc package core package tasty -import dotty.tools.tasty.TastyFormat._ -import dotty.tools.tasty.TastyBuffer._ - import ast.Trees._ -import ast.{untpd, tpd} -import Contexts._, Symbols._, Types._, Names._, Constants._, Decorators._, Annotations._, Flags._ -import typer.Inliner -import NameKinds._ -import StdNames.nme -import transform.SymUtils._ +import ast.{ untpd, tpd } import printing.Printer import printing.Texts._ import util.SourceFile @@ -30,686 +22,686 @@ object TreePickler { } } -class TreePickler(pickler: TastyPickler) { - val buf: TreeBuffer = new TreeBuffer - pickler.newSection(TreePickler.sectionName, buf) - import TreePickler._ - import buf._ - import pickler.nameBuffer.nameIndex - import tpd._ - - private val symRefs = Symbols.newMutableSymbolMap[Addr] - private val forwardSymRefs = Symbols.newMutableSymbolMap[List[Addr]] - private val pickledTypes = new java.util.IdentityHashMap[Type, Any] // Value type is really Addr, but that's not compatible with null - - private def withLength(op: => Unit) = { - val lengthAddr = reserveRef(relative = true) - op - fillRef(lengthAddr, currentAddr, relative = true) - } - - def addrOfSym(sym: Symbol): Option[Addr] = - symRefs.get(sym) - - def preRegister(tree: Tree)(implicit ctx: Context): Unit = tree match { - case tree: MemberDef => - if (!symRefs.contains(tree.symbol)) symRefs(tree.symbol) = NoAddr - case _ => - } - - def registerDef(sym: Symbol): Unit = { - symRefs(sym) = currentAddr - forwardSymRefs.get(sym) match { - case Some(refs) => - refs.foreach(fillRef(_, currentAddr, relative = false)) - forwardSymRefs -= sym - case None => - } - } - - def pickleName(name: Name): Unit = writeNat(nameIndex(name).index) - - private def pickleNameAndSig(name: Name, sig: Signature): Unit = - pickleName( - if (sig eq Signature.NotAMethod) name - else SignedName(name.toTermName, sig)) - - private def pickleSymRef(sym: Symbol)(implicit ctx: Context) = symRefs.get(sym) match { - case Some(label) => - if (label != NoAddr) writeRef(label) else pickleForwardSymRef(sym) - case None => - // See pos/t1957.scala for an example where this can happen. - // I believe it's a bug in typer: the type of an implicit argument refers - // to a closure parameter outside the closure itself. TODO: track this down, so that we - // can eliminate this case. - ctx.log(i"pickling reference to as yet undefined $sym in ${sym.owner}", sym.sourcePos) - pickleForwardSymRef(sym) - } - - private def pickleForwardSymRef(sym: Symbol)(implicit ctx: Context) = { - val ref = reserveRef(relative = false) - assert(!sym.is(Flags.Package), sym) - forwardSymRefs(sym) = ref :: forwardSymRefs.getOrElse(sym, Nil) - } - - private def isLocallyDefined(sym: Symbol)(implicit ctx: Context) = - sym.topLevelClass.isLinkedWith(pickler.rootCls) - - def pickleConstant(c: Constant)(implicit ctx: Context): Unit = c.tag match { - case UnitTag => - writeByte(UNITconst) - case BooleanTag => - writeByte(if (c.booleanValue) TRUEconst else FALSEconst) - case ByteTag => - writeByte(BYTEconst) - writeInt(c.byteValue) - case ShortTag => - writeByte(SHORTconst) - writeInt(c.shortValue) - case CharTag => - writeByte(CHARconst) - writeNat(c.charValue) - case IntTag => - writeByte(INTconst) - writeInt(c.intValue) - case LongTag => - writeByte(LONGconst) - writeLongInt(c.longValue) - case FloatTag => - writeByte(FLOATconst) - writeInt(java.lang.Float.floatToRawIntBits(c.floatValue)) - case DoubleTag => - writeByte(DOUBLEconst) - writeLongInt(java.lang.Double.doubleToRawLongBits(c.doubleValue)) - case StringTag => - writeByte(STRINGconst) - pickleName(c.stringValue.toTermName) - case NullTag => - writeByte(NULLconst) - case ClazzTag => - writeByte(CLASSconst) - pickleType(c.typeValue) - case EnumTag => - writeByte(ENUMconst) - pickleType(c.symbolValue.termRef) - } - - def pickleType(tpe0: Type, richTypes: Boolean = false)(implicit ctx: Context): Unit = { - val tpe = tpe0.stripTypeVar - try { - val prev = pickledTypes.get(tpe) - if (prev == null) { - pickledTypes.put(tpe, currentAddr) - pickleNewType(tpe, richTypes) - } - else { - writeByte(SHAREDtype) - writeRef(prev.asInstanceOf[Addr]) - } - } - catch { - case ex: AssertionError => - println(i"error when pickling type $tpe") - throw ex - } - } - - private def pickleNewType(tpe: Type, richTypes: Boolean)(implicit ctx: Context): Unit = tpe match { - case AppliedType(tycon, args) => - writeByte(APPLIEDtype) - withLength { pickleType(tycon); args.foreach(pickleType(_)) } - case ConstantType(value) => - pickleConstant(value) - case tpe: NamedType => - val sym = tpe.symbol - def pickleExternalRef(sym: Symbol) = { - def pickleCore() = { - pickleNameAndSig(sym.name, tpe.signature) - pickleType(tpe.prefix) - } - val isShadowedRef = - sym.isClass && tpe.prefix.member(sym.name).symbol != sym - if (sym.is(Flags.Private) || isShadowedRef) { - writeByte(if (tpe.isType) TYPEREFin else TERMREFin) - withLength { - pickleCore() - pickleType(sym.owner.typeRef) - } - } - else { - writeByte(if (tpe.isType) TYPEREF else TERMREF) - pickleCore() - } - } - if (sym.is(Flags.Package)) { - writeByte(if (tpe.isType) TYPEREFpkg else TERMREFpkg) - pickleName(sym.fullName) - } - else if (tpe.prefix == NoPrefix) { - writeByte(if (tpe.isType) TYPEREFdirect else TERMREFdirect) - pickleSymRef(sym) - } - else tpe.designator match { - case name: Name => - writeByte(if (tpe.isType) TYPEREF else TERMREF) - pickleName(name); pickleType(tpe.prefix) - case sym: Symbol => - if (isLocallyDefined(sym)) { - writeByte(if (tpe.isType) TYPEREFsymbol else TERMREFsymbol) - pickleSymRef(sym); pickleType(tpe.prefix) - } - else pickleExternalRef(sym) - } - case tpe: ThisType => - if (tpe.cls.is(Flags.Package) && !tpe.cls.isEffectiveRoot) { - writeByte(TERMREFpkg) - pickleName(tpe.cls.fullName) - } - else { - writeByte(THIS) - pickleType(tpe.tref) - } - case tpe: SuperType => - writeByte(SUPERtype) - withLength { pickleType(tpe.thistpe); pickleType(tpe.supertpe) } - case tpe: RecThis => - writeByte(RECthis) - val binderAddr = pickledTypes.get(tpe.binder) - assert(binderAddr != null, tpe.binder) - writeRef(binderAddr.asInstanceOf[Addr]) - case tpe: SkolemType => - pickleType(tpe.info) - case tpe: RefinedType => - writeByte(REFINEDtype) - withLength { - pickleName(tpe.refinedName) - pickleType(tpe.parent) - pickleType(tpe.refinedInfo, richTypes = true) - } - case tpe: RecType => - writeByte(RECtype) - pickleType(tpe.parent) - case tpe: TypeAlias => - writeByte(TYPEALIAS) - pickleType(tpe.alias, richTypes) - case tpe: TypeBounds => - writeByte(TYPEBOUNDS) - withLength { pickleType(tpe.lo, richTypes); pickleType(tpe.hi, richTypes) } - case tpe: AnnotatedType => - writeByte(ANNOTATEDtype) - withLength { pickleType(tpe.parent, richTypes); pickleTree(tpe.annot.tree) } - case tpe: AndType => - writeByte(ANDtype) - withLength { pickleType(tpe.tp1, richTypes); pickleType(tpe.tp2, richTypes) } - case tpe: OrType => - writeByte(ORtype) - withLength { pickleType(tpe.tp1, richTypes); pickleType(tpe.tp2, richTypes) } - case tpe: ExprType => - writeByte(BYNAMEtype) - pickleType(tpe.underlying) - case tpe: HKTypeLambda => - pickleMethodic(TYPELAMBDAtype, tpe) - case tpe: MatchType => - writeByte(MATCHtype) - withLength { - pickleType(tpe.bound) - pickleType(tpe.scrutinee) - tpe.cases.foreach(pickleType(_)) - } - case tpe: PolyType if richTypes => - pickleMethodic(POLYtype, tpe) - case tpe: MethodType if richTypes => - val tag = methodTypeTag( - isContextual = tpe.isContextualMethod, - isImplicit = tpe.isImplicitMethod && !tpe.isContextualMethod, - isErased = tpe.isErasedMethod) - pickleMethodic(tag, tpe) - case tpe: ParamRef => - assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe") - case tpe: LazyRef => - pickleType(tpe.ref) - } - - def pickleMethodic(tag: Int, tpe: LambdaType)(implicit ctx: Context): Unit = { - writeByte(tag) - withLength { - pickleType(tpe.resultType, richTypes = true) - tpe.paramNames.lazyZip(tpe.paramInfos).foreach { (name, tpe) => - pickleName(name); pickleType(tpe) - } - } - } - - def pickleParamRef(tpe: ParamRef)(implicit ctx: Context): Boolean = { - val binder = pickledTypes.get(tpe.binder) - val pickled = binder != null - if (pickled) { - writeByte(PARAMtype) - withLength { writeRef(binder.asInstanceOf[Addr]); writeNat(tpe.paramNum) } - } - pickled - } - - def pickleTpt(tpt: Tree)(implicit ctx: Context): Unit = - pickleTree(tpt) - - def pickleTreeUnlessEmpty(tree: Tree)(implicit ctx: Context): Unit = { - if (!tree.isEmpty) pickleTree(tree) - } - - def pickleDef(tag: Int, sym: Symbol, tpt: Tree, rhs: Tree = EmptyTree, pickleParams: => Unit = ())(implicit ctx: Context): Unit = { - assert(symRefs(sym) == NoAddr, sym) - registerDef(sym) - writeByte(tag) - withLength { - pickleName(sym.name) - pickleParams - tpt match { - case _: Template | _: Hole => pickleTree(tpt) - case _ if tpt.isType => pickleTpt(tpt) - } - pickleTreeUnlessEmpty(rhs) - pickleModifiers(sym) - } - } - - def pickleParam(tree: Tree)(implicit ctx: Context): Unit = { - registerTreeAddr(tree) - tree match { - case tree: ValDef => pickleDef(PARAM, tree.symbol, tree.tpt) - case tree: DefDef => pickleDef(PARAM, tree.symbol, tree.tpt, tree.rhs) - case tree: TypeDef => pickleDef(TYPEPARAM, tree.symbol, tree.rhs) - } - } - - def pickleParams(trees: List[Tree])(implicit ctx: Context): Unit = { - trees.foreach(preRegister) - trees.foreach(pickleParam) - } - - def pickleStats(stats: List[Tree])(implicit ctx: Context): Unit = { - stats.foreach(preRegister) - stats.foreach(stat => if (!stat.isEmpty) pickleTree(stat)) - } - - def pickleTree(tree: Tree)(implicit ctx: Context): Unit = { - val addr = registerTreeAddr(tree) - if (addr != currentAddr) { - writeByte(SHAREDterm) - writeRef(addr) - } - else - try tree match { - case Ident(name) => - tree.tpe match { - case tp: TermRef if name != nme.WILDCARD => - // wildcards are pattern bound, need to be preserved as ids. - pickleType(tp) - case tp => - writeByte(if (tree.isType) IDENTtpt else IDENT) - pickleName(name) - pickleType(tp) - } - case This(qual) => - if (qual.isEmpty) pickleType(tree.tpe) - else { - writeByte(QUALTHIS) - val ThisType(tref) = tree.tpe - pickleTree(qual.withType(tref)) - } - case Select(qual, name) => - name match { - case OuterSelectName(_, levels) => - writeByte(SELECTouter) - withLength { - writeNat(levels) - pickleTree(qual) - val SkolemType(tp) = tree.tpe - pickleType(tp) - } - case _ => - writeByte(if (name.isTypeName) SELECTtpt else SELECT) - val sig = tree.tpe.signature - pickleNameAndSig(name, sig) - pickleTree(qual) - } - case Apply(fun, args) => - if (fun.symbol eq defn.throwMethod) { - writeByte(THROW) - pickleTree(args.head) - } - else { - writeByte(APPLY) - withLength { - pickleTree(fun) - args.foreach(pickleTree) - } - } - case TypeApply(fun, args) => - writeByte(TYPEAPPLY) - withLength { - pickleTree(fun) - args.foreach(pickleTpt) - } - case Literal(const1) => - pickleConstant { - tree.tpe match { - case ConstantType(const2) => const2 - case _ => const1 - } - } - case Super(qual, mix) => - writeByte(SUPER) - withLength { - pickleTree(qual); - if (!mix.isEmpty) { - val SuperType(_, mixinType: TypeRef) = tree.tpe - pickleTree(mix.withType(mixinType)) - } - } - case New(tpt) => - writeByte(NEW) - pickleTpt(tpt) - case Typed(expr, tpt) => - writeByte(TYPED) - withLength { pickleTree(expr); pickleTpt(tpt) } - case NamedArg(name, arg) => - writeByte(NAMEDARG) - pickleName(name) - pickleTree(arg) - case Assign(lhs, rhs) => - writeByte(ASSIGN) - withLength { pickleTree(lhs); pickleTree(rhs) } - case Block(stats, expr) => - writeByte(BLOCK) - stats.foreach(preRegister) - withLength { pickleTree(expr); stats.foreach(pickleTree) } - case tree @ If(cond, thenp, elsep) => - writeByte(IF) - withLength { - if (tree.isInline) writeByte(INLINE) - pickleTree(cond) - pickleTree(thenp) - pickleTree(elsep) - } - case Closure(env, meth, tpt) => - writeByte(LAMBDA) - assert(env.isEmpty) - withLength { - pickleTree(meth) - if (tpt.tpe.exists) pickleTpt(tpt) - } - case tree @ Match(selector, cases) => - writeByte(MATCH) - withLength { - if (tree.isInline) - if (selector.isEmpty) writeByte(IMPLICIT) - else { writeByte(INLINE); pickleTree(selector) } - else pickleTree(selector) - tree.cases.foreach(pickleTree) - } - case CaseDef(pat, guard, rhs) => - writeByte(CASEDEF) - withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) } - case Return(expr, from) => - writeByte(RETURN) - withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) } - case WhileDo(cond, body) => - writeByte(WHILE) - withLength { pickleTree(cond); pickleTree(body) } - case Try(block, cases, finalizer) => - writeByte(TRY) - withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) } - case SeqLiteral(elems, elemtpt) => - writeByte(REPEATED) - withLength { pickleTree(elemtpt); elems.foreach(pickleTree) } - case Inlined(call, bindings, expansion) => - writeByte(INLINED) - bindings.foreach(preRegister) - withLength { - pickleTree(expansion) - if (!call.isEmpty) pickleTree(call) - bindings.foreach { b => - assert(b.isInstanceOf[DefDef] || b.isInstanceOf[ValDef]) - pickleTree(b) - } - } - case Bind(name, body) => - registerDef(tree.symbol) - writeByte(BIND) - withLength { - pickleName(name); pickleType(tree.symbol.info); pickleTree(body) - } - case Alternative(alts) => - writeByte(ALTERNATIVE) - withLength { alts.foreach(pickleTree) } - case UnApply(fun, implicits, patterns) => - writeByte(UNAPPLY) - withLength { - pickleTree(fun) - for (implicitArg <- implicits) { - writeByte(IMPLICITarg) - pickleTree(implicitArg) - } - pickleType(tree.tpe) - patterns.foreach(pickleTree) - } - case tree: ValDef => - pickleDef(VALDEF, tree.symbol, tree.tpt, tree.rhs) - case tree: DefDef => - def pickleParamss(paramss: List[List[ValDef]]): Unit = paramss match - case Nil => - case params :: rest => - pickleParams(params) - if params.isEmpty || rest.nonEmpty then writeByte(PARAMEND) - pickleParamss(rest) - def pickleAllParams = - pickleParams(tree.tparams) - pickleParamss(tree.vparamss) - pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams) - case tree: TypeDef => - pickleDef(TYPEDEF, tree.symbol, tree.rhs) - case tree: Template => - registerDef(tree.symbol) - writeByte(TEMPLATE) - val (params, rest) = decomposeTemplateBody(tree.body) - withLength { - pickleParams(params) - tree.parents.foreach(pickleTree) - val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info - if (!tree.self.isEmpty) { - writeByte(SELFDEF) - pickleName(tree.self.name) - - if (!tree.self.tpt.isEmpty) pickleTree(tree.self.tpt) - else { - if (!tree.self.isEmpty) registerTreeAddr(tree.self) - pickleType { - selfInfo match { - case sym: Symbol => sym.info - case tp: Type => tp - } - } - } - } - pickleStats(tree.constr :: rest) - } - case Import(expr, selectors) => - writeByte(IMPORT) - withLength { - pickleTree(expr) - pickleSelectors(selectors) - } - case PackageDef(pid, stats) => - writeByte(PACKAGE) - withLength { pickleType(pid.tpe); pickleStats(stats) } - case tree: TypeTree => - pickleType(tree.tpe) - case SingletonTypeTree(ref) => - writeByte(SINGLETONtpt) - pickleTree(ref) - case RefinedTypeTree(parent, refinements) => - if (refinements.isEmpty) pickleTree(parent) - else { - val refineCls = refinements.head.symbol.owner.asClass - registerDef(refineCls) - pickledTypes.put(refineCls.typeRef, currentAddr) - writeByte(REFINEDtpt) - refinements.foreach(preRegister) - withLength { pickleTree(parent); refinements.foreach(pickleTree) } - } - case AppliedTypeTree(tycon, args) => - writeByte(APPLIEDtpt) - withLength { pickleTree(tycon); args.foreach(pickleTree) } - case MatchTypeTree(bound, selector, cases) => - writeByte(MATCHtpt) - withLength { - if (!bound.isEmpty) pickleTree(bound) - pickleTree(selector) - cases.foreach(pickleTree) - } - case ByNameTypeTree(tp) => - writeByte(BYNAMEtpt) - pickleTree(tp) - case Annotated(tree, annot) => - writeByte(ANNOTATEDtpt) - withLength { pickleTree(tree); pickleTree(annot) } - case LambdaTypeTree(tparams, body) => - writeByte(LAMBDAtpt) - withLength { pickleParams(tparams); pickleTree(body) } - case TypeBoundsTree(lo, hi) => - writeByte(TYPEBOUNDStpt) - withLength { - pickleTree(lo); - if (hi ne lo) pickleTree(hi) - } - case Hole(_, idx, args) => - writeByte(HOLE) - withLength { - writeNat(idx) - args.foreach(pickleTree) - } - } - catch { - case ex: AssertionError => - println(i"error when pickling tree $tree") - throw ex - } - } - - def pickleSelectors(selectors: List[untpd.ImportSelector])(implicit ctx: Context): Unit = - for sel <- selectors do - pickleSelector(IMPORTED, sel.imported) - sel.renamed match - case to @ Ident(_) => pickleSelector(RENAMED, to) - case _ => - sel.bound match - case bound @ untpd.TypedSplice(tpt) => - registerTreeAddr(bound) - writeByte(BOUNDED) - pickleTree(tpt) - case _ => - - def pickleSelector(tag: Int, id: untpd.Ident)(implicit ctx: Context): Unit = { - registerTreeAddr(id) - writeByte(tag) - pickleName(id.name) - } - - def pickleModifiers(sym: Symbol)(implicit ctx: Context): Unit = { - import Flags._ - var flags = sym.flags - val privateWithin = sym.privateWithin - if (privateWithin.exists) { - writeByte(if (flags.is(Protected)) PROTECTEDqualified else PRIVATEqualified) - pickleType(privateWithin.typeRef) - flags = flags &~ Protected - } - if (flags.is(ParamAccessor) && sym.isTerm && !sym.isSetter) - flags = flags &~ ParamAccessor // we only generate a tag for parameter setters - pickleFlags(flags, sym.isTerm) - sym.annotations.foreach(pickleAnnotation(sym, _)) - } - - def pickleFlags(flags: FlagSet, isTerm: Boolean)(implicit ctx: Context): Unit = { - import Flags._ - def writeModTag(tag: Int) = { - assert(isModifierTag(tag)) - writeByte(tag) - } - if (flags.is(Private)) writeModTag(PRIVATE) - if (flags.is(Protected)) writeModTag(PROTECTED) - if (flags.is(Final, butNot = Module)) writeModTag(FINAL) - if (flags.is(Case)) writeModTag(CASE) - if (flags.is(Override)) writeModTag(OVERRIDE) - if (flags.is(Inline)) writeModTag(INLINE) - if (flags.is(InlineProxy)) writeModTag(INLINEPROXY) - if (flags.is(Macro)) writeModTag(MACRO) - if (flags.is(JavaStatic)) writeModTag(STATIC) - if (flags.is(Module)) writeModTag(OBJECT) - if (flags.is(Enum)) writeModTag(ENUM) - if (flags.is(Local)) writeModTag(LOCAL) - if (flags.is(Synthetic)) writeModTag(SYNTHETIC) - if (flags.is(Artifact)) writeModTag(ARTIFACT) - if (flags.is(Scala2x)) writeModTag(SCALA2X) - if (isTerm) { - if (flags.is(Implicit)) writeModTag(IMPLICIT) - if (flags.is(Given)) writeModTag(GIVEN) - if (flags.is(Erased)) writeModTag(ERASED) - if (flags.is(Lazy, butNot = Module)) writeModTag(LAZY) - if (flags.is(AbsOverride)) { writeModTag(ABSTRACT); writeModTag(OVERRIDE) } - if (flags.is(Mutable)) writeModTag(MUTABLE) - if (flags.is(Accessor)) writeModTag(FIELDaccessor) - if (flags.is(CaseAccessor)) writeModTag(CASEaccessor) - if (flags.is(DefaultParameterized)) writeModTag(DEFAULTparameterized) - if (flags.is(StableRealizable)) writeModTag(STABLE) - if (flags.is(Extension)) writeModTag(EXTENSION) - if (flags.is(ParamAccessor)) writeModTag(PARAMsetter) - if (flags.is(Exported)) writeModTag(EXPORTED) - assert(!(flags.is(Label))) - } - else { - if (flags.is(Sealed)) writeModTag(SEALED) - if (flags.is(Abstract)) writeModTag(ABSTRACT) - if (flags.is(Trait)) writeModTag(TRAIT) - if (flags.is(Covariant)) writeModTag(COVARIANT) - if (flags.is(Contravariant)) writeModTag(CONTRAVARIANT) - if (flags.is(Opaque)) writeModTag(OPAQUE) - if (flags.is(Open)) writeModTag(OPEN) - } - } - - private def isUnpicklable(owner: Symbol, ann: Annotation)(implicit ctx: Context) = ann match { - case Annotation.Child(sym) => sym.isInaccessibleChildOf(owner) - // If child annotation refers to a local class or enum value under - // a different toplevel class, it is impossible to pickle a reference to it. - // Such annotations will be reconstituted when unpickling the child class. - // See tests/pickling/i3149.scala - case _ => - ann.symbol == defn.BodyAnnot // inline bodies are reconstituted automatically when unpickling - } - - def pickleAnnotation(owner: Symbol, ann: Annotation)(implicit ctx: Context): Unit = { - if (!isUnpicklable(owner, ann)) { - writeByte(ANNOTATION) - withLength { pickleType(ann.symbol.typeRef); pickleTree(ann.tree) } - } - } - -// ---- main entry points --------------------------------------- - - def pickle(trees: List[Tree])(implicit ctx: Context): Unit = { - trees.foreach(tree => if (!tree.isEmpty) pickleTree(tree)) - def missing = forwardSymRefs.keysIterator.map(sym => sym.showLocated + "(line " + sym.sourcePos.line + ")").toList - assert(forwardSymRefs.isEmpty, i"unresolved symbols: $missing%, % when pickling ${ctx.source}") - } - - def compactify(): Unit = { - buf.compactify() - - def updateMapWithDeltas(mp: MutableSymbolMap[Addr]) = - for (key <- mp.keysIterator.toBuffer[Symbol]) mp(key) = adjusted(mp(key)) - - updateMapWithDeltas(symRefs) - } -} +// class TreePickler(pickler: TastyPickler) { +// val buf: TreeBuffer = new TreeBuffer +// pickler.newSection(TreePickler.sectionName, buf) +// import TreePickler._ +// import buf._ +// import pickler.nameBuffer.nameIndex +// import tpd._ + +// private val symRefs = Symbols.newMutableSymbolMap[Addr] +// private val forwardSymRefs = Symbols.newMutableSymbolMap[List[Addr]] +// private val pickledTypes = new java.util.IdentityHashMap[Type, Any] // Value type is really Addr, but that's not compatible with null + +// private def withLength(op: => Unit) = { +// val lengthAddr = reserveRef(relative = true) +// op +// fillRef(lengthAddr, currentAddr, relative = true) +// } + +// def addrOfSym(sym: Symbol): Option[Addr] = +// symRefs.get(sym) + +// def preRegister(tree: Tree)(implicit ctx: Context): Unit = tree match { +// case tree: MemberDef => +// if (!symRefs.contains(tree.symbol)) symRefs(tree.symbol) = NoAddr +// case _ => +// } + +// def registerDef(sym: Symbol): Unit = { +// symRefs(sym) = currentAddr +// forwardSymRefs.get(sym) match { +// case Some(refs) => +// refs.foreach(fillRef(_, currentAddr, relative = false)) +// forwardSymRefs -= sym +// case None => +// } +// } + +// def pickleName(name: Name): Unit = writeNat(nameIndex(name).index) + +// private def pickleNameAndSig(name: Name, sig: Signature): Unit = +// pickleName( +// if (sig eq Signature.NotAMethod) name +// else SignedName(name.toTermName, sig)) + +// private def pickleSymRef(sym: Symbol)(implicit ctx: Context) = symRefs.get(sym) match { +// case Some(label) => +// if (label != NoAddr) writeRef(label) else pickleForwardSymRef(sym) +// case None => +// // See pos/t1957.scala for an example where this can happen. +// // I believe it's a bug in typer: the type of an implicit argument refers +// // to a closure parameter outside the closure itself. TODO: track this down, so that we +// // can eliminate this case. +// ctx.log(i"pickling reference to as yet undefined $sym in ${sym.owner}", sym.sourcePos) +// pickleForwardSymRef(sym) +// } + +// private def pickleForwardSymRef(sym: Symbol)(implicit ctx: Context) = { +// val ref = reserveRef(relative = false) +// assert(!sym.is(Flags.Package), sym) +// forwardSymRefs(sym) = ref :: forwardSymRefs.getOrElse(sym, Nil) +// } + +// private def isLocallyDefined(sym: Symbol)(implicit ctx: Context) = +// sym.topLevelClass.isLinkedWith(pickler.rootCls) + +// def pickleConstant(c: Constant)(implicit ctx: Context): Unit = c.tag match { +// case UnitTag => +// writeByte(UNITconst) +// case BooleanTag => +// writeByte(if (c.booleanValue) TRUEconst else FALSEconst) +// case ByteTag => +// writeByte(BYTEconst) +// writeInt(c.byteValue) +// case ShortTag => +// writeByte(SHORTconst) +// writeInt(c.shortValue) +// case CharTag => +// writeByte(CHARconst) +// writeNat(c.charValue) +// case IntTag => +// writeByte(INTconst) +// writeInt(c.intValue) +// case LongTag => +// writeByte(LONGconst) +// writeLongInt(c.longValue) +// case FloatTag => +// writeByte(FLOATconst) +// writeInt(java.lang.Float.floatToRawIntBits(c.floatValue)) +// case DoubleTag => +// writeByte(DOUBLEconst) +// writeLongInt(java.lang.Double.doubleToRawLongBits(c.doubleValue)) +// case StringTag => +// writeByte(STRINGconst) +// pickleName(c.stringValue.toTermName) +// case NullTag => +// writeByte(NULLconst) +// case ClazzTag => +// writeByte(CLASSconst) +// pickleType(c.typeValue) +// case EnumTag => +// writeByte(ENUMconst) +// pickleType(c.symbolValue.termRef) +// } + +// def pickleType(tpe0: Type, richTypes: Boolean = false)(implicit ctx: Context): Unit = { +// val tpe = tpe0.stripTypeVar +// try { +// val prev = pickledTypes.get(tpe) +// if (prev == null) { +// pickledTypes.put(tpe, currentAddr) +// pickleNewType(tpe, richTypes) +// } +// else { +// writeByte(SHAREDtype) +// writeRef(prev.asInstanceOf[Addr]) +// } +// } +// catch { +// case ex: AssertionError => +// println(i"error when pickling type $tpe") +// throw ex +// } +// } + +// private def pickleNewType(tpe: Type, richTypes: Boolean)(implicit ctx: Context): Unit = tpe match { +// case AppliedType(tycon, args) => +// writeByte(APPLIEDtype) +// withLength { pickleType(tycon); args.foreach(pickleType(_)) } +// case ConstantType(value) => +// pickleConstant(value) +// case tpe: NamedType => +// val sym = tpe.symbol +// def pickleExternalRef(sym: Symbol) = { +// def pickleCore() = { +// pickleNameAndSig(sym.name, tpe.signature) +// pickleType(tpe.prefix) +// } +// val isShadowedRef = +// sym.isClass && tpe.prefix.member(sym.name).symbol != sym +// if (sym.is(Flags.Private) || isShadowedRef) { +// writeByte(if (tpe.isType) TYPEREFin else TERMREFin) +// withLength { +// pickleCore() +// pickleType(sym.owner.typeRef) +// } +// } +// else { +// writeByte(if (tpe.isType) TYPEREF else TERMREF) +// pickleCore() +// } +// } +// if (sym.is(Flags.Package)) { +// writeByte(if (tpe.isType) TYPEREFpkg else TERMREFpkg) +// pickleName(sym.fullName) +// } +// else if (tpe.prefix == NoPrefix) { +// writeByte(if (tpe.isType) TYPEREFdirect else TERMREFdirect) +// pickleSymRef(sym) +// } +// else tpe.designator match { +// case name: Name => +// writeByte(if (tpe.isType) TYPEREF else TERMREF) +// pickleName(name); pickleType(tpe.prefix) +// case sym: Symbol => +// if (isLocallyDefined(sym)) { +// writeByte(if (tpe.isType) TYPEREFsymbol else TERMREFsymbol) +// pickleSymRef(sym); pickleType(tpe.prefix) +// } +// else pickleExternalRef(sym) +// } +// case tpe: ThisType => +// if (tpe.cls.is(Flags.Package) && !tpe.cls.isEffectiveRoot) { +// writeByte(TERMREFpkg) +// pickleName(tpe.cls.fullName) +// } +// else { +// writeByte(THIS) +// pickleType(tpe.tref) +// } +// case tpe: SuperType => +// writeByte(SUPERtype) +// withLength { pickleType(tpe.thistpe); pickleType(tpe.supertpe) } +// case tpe: RecThis => +// writeByte(RECthis) +// val binderAddr = pickledTypes.get(tpe.binder) +// assert(binderAddr != null, tpe.binder) +// writeRef(binderAddr.asInstanceOf[Addr]) +// case tpe: SkolemType => +// pickleType(tpe.info) +// case tpe: RefinedType => +// writeByte(REFINEDtype) +// withLength { +// pickleName(tpe.refinedName) +// pickleType(tpe.parent) +// pickleType(tpe.refinedInfo, richTypes = true) +// } +// case tpe: RecType => +// writeByte(RECtype) +// pickleType(tpe.parent) +// case tpe: TypeAlias => +// writeByte(TYPEALIAS) +// pickleType(tpe.alias, richTypes) +// case tpe: TypeBounds => +// writeByte(TYPEBOUNDS) +// withLength { pickleType(tpe.lo, richTypes); pickleType(tpe.hi, richTypes) } +// case tpe: AnnotatedType => +// writeByte(ANNOTATEDtype) +// withLength { pickleType(tpe.parent, richTypes); pickleTree(tpe.annot.tree) } +// case tpe: AndType => +// writeByte(ANDtype) +// withLength { pickleType(tpe.tp1, richTypes); pickleType(tpe.tp2, richTypes) } +// case tpe: OrType => +// writeByte(ORtype) +// withLength { pickleType(tpe.tp1, richTypes); pickleType(tpe.tp2, richTypes) } +// case tpe: ExprType => +// writeByte(BYNAMEtype) +// pickleType(tpe.underlying) +// case tpe: HKTypeLambda => +// pickleMethodic(TYPELAMBDAtype, tpe) +// case tpe: MatchType => +// writeByte(MATCHtype) +// withLength { +// pickleType(tpe.bound) +// pickleType(tpe.scrutinee) +// tpe.cases.foreach(pickleType(_)) +// } +// case tpe: PolyType if richTypes => +// pickleMethodic(POLYtype, tpe) +// case tpe: MethodType if richTypes => +// val tag = methodTypeTag( +// isContextual = tpe.isContextualMethod, +// isImplicit = tpe.isImplicitMethod && !tpe.isContextualMethod, +// isErased = tpe.isErasedMethod) +// pickleMethodic(tag, tpe) +// case tpe: ParamRef => +// assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe") +// case tpe: LazyRef => +// pickleType(tpe.ref) +// } + +// def pickleMethodic(tag: Int, tpe: LambdaType)(implicit ctx: Context): Unit = { +// writeByte(tag) +// withLength { +// pickleType(tpe.resultType, richTypes = true) +// tpe.paramNames.lazyZip(tpe.paramInfos).foreach { (name, tpe) => +// pickleName(name); pickleType(tpe) +// } +// } +// } + +// def pickleParamRef(tpe: ParamRef)(implicit ctx: Context): Boolean = { +// val binder = pickledTypes.get(tpe.binder) +// val pickled = binder != null +// if (pickled) { +// writeByte(PARAMtype) +// withLength { writeRef(binder.asInstanceOf[Addr]); writeNat(tpe.paramNum) } +// } +// pickled +// } + +// def pickleTpt(tpt: Tree)(implicit ctx: Context): Unit = +// pickleTree(tpt) + +// def pickleTreeUnlessEmpty(tree: Tree)(implicit ctx: Context): Unit = { +// if (!tree.isEmpty) pickleTree(tree) +// } + +// def pickleDef(tag: Int, sym: Symbol, tpt: Tree, rhs: Tree = EmptyTree, pickleParams: => Unit = ())(implicit ctx: Context): Unit = { +// assert(symRefs(sym) == NoAddr, sym) +// registerDef(sym) +// writeByte(tag) +// withLength { +// pickleName(sym.name) +// pickleParams +// tpt match { +// case _: Template | _: Hole => pickleTree(tpt) +// case _ if tpt.isType => pickleTpt(tpt) +// } +// pickleTreeUnlessEmpty(rhs) +// pickleModifiers(sym) +// } +// } + +// def pickleParam(tree: Tree)(implicit ctx: Context): Unit = { +// registerTreeAddr(tree) +// tree match { +// case tree: ValDef => pickleDef(PARAM, tree.symbol, tree.tpt) +// case tree: DefDef => pickleDef(PARAM, tree.symbol, tree.tpt, tree.rhs) +// case tree: TypeDef => pickleDef(TYPEPARAM, tree.symbol, tree.rhs) +// } +// } + +// def pickleParams(trees: List[Tree])(implicit ctx: Context): Unit = { +// trees.foreach(preRegister) +// trees.foreach(pickleParam) +// } + +// def pickleStats(stats: List[Tree])(implicit ctx: Context): Unit = { +// stats.foreach(preRegister) +// stats.foreach(stat => if (!stat.isEmpty) pickleTree(stat)) +// } + +// def pickleTree(tree: Tree)(implicit ctx: Context): Unit = { +// val addr = registerTreeAddr(tree) +// if (addr != currentAddr) { +// writeByte(SHAREDterm) +// writeRef(addr) +// } +// else +// try tree match { +// case Ident(name) => +// tree.tpe match { +// case tp: TermRef if name != nme.WILDCARD => +// // wildcards are pattern bound, need to be preserved as ids. +// pickleType(tp) +// case tp => +// writeByte(if (tree.isType) IDENTtpt else IDENT) +// pickleName(name) +// pickleType(tp) +// } +// case This(qual) => +// if (qual.isEmpty) pickleType(tree.tpe) +// else { +// writeByte(QUALTHIS) +// val ThisType(tref) = tree.tpe +// pickleTree(qual.withType(tref)) +// } +// case Select(qual, name) => +// name match { +// case OuterSelectName(_, levels) => +// writeByte(SELECTouter) +// withLength { +// writeNat(levels) +// pickleTree(qual) +// val SkolemType(tp) = tree.tpe +// pickleType(tp) +// } +// case _ => +// writeByte(if (name.isTypeName) SELECTtpt else SELECT) +// val sig = tree.tpe.signature +// pickleNameAndSig(name, sig) +// pickleTree(qual) +// } +// case Apply(fun, args) => +// if (fun.symbol eq defn.throwMethod) { +// writeByte(THROW) +// pickleTree(args.head) +// } +// else { +// writeByte(APPLY) +// withLength { +// pickleTree(fun) +// args.foreach(pickleTree) +// } +// } +// case TypeApply(fun, args) => +// writeByte(TYPEAPPLY) +// withLength { +// pickleTree(fun) +// args.foreach(pickleTpt) +// } +// case Literal(const1) => +// pickleConstant { +// tree.tpe match { +// case ConstantType(const2) => const2 +// case _ => const1 +// } +// } +// case Super(qual, mix) => +// writeByte(SUPER) +// withLength { +// pickleTree(qual); +// if (!mix.isEmpty) { +// val SuperType(_, mixinType: TypeRef) = tree.tpe +// pickleTree(mix.withType(mixinType)) +// } +// } +// case New(tpt) => +// writeByte(NEW) +// pickleTpt(tpt) +// case Typed(expr, tpt) => +// writeByte(TYPED) +// withLength { pickleTree(expr); pickleTpt(tpt) } +// case NamedArg(name, arg) => +// writeByte(NAMEDARG) +// pickleName(name) +// pickleTree(arg) +// case Assign(lhs, rhs) => +// writeByte(ASSIGN) +// withLength { pickleTree(lhs); pickleTree(rhs) } +// case Block(stats, expr) => +// writeByte(BLOCK) +// stats.foreach(preRegister) +// withLength { pickleTree(expr); stats.foreach(pickleTree) } +// case tree @ If(cond, thenp, elsep) => +// writeByte(IF) +// withLength { +// if (tree.isInline) writeByte(INLINE) +// pickleTree(cond) +// pickleTree(thenp) +// pickleTree(elsep) +// } +// case Closure(env, meth, tpt) => +// writeByte(LAMBDA) +// assert(env.isEmpty) +// withLength { +// pickleTree(meth) +// if (tpt.tpe.exists) pickleTpt(tpt) +// } +// case tree @ Match(selector, cases) => +// writeByte(MATCH) +// withLength { +// if (tree.isInline) +// if (selector.isEmpty) writeByte(IMPLICIT) +// else { writeByte(INLINE); pickleTree(selector) } +// else pickleTree(selector) +// tree.cases.foreach(pickleTree) +// } +// case CaseDef(pat, guard, rhs) => +// writeByte(CASEDEF) +// withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) } +// case Return(expr, from) => +// writeByte(RETURN) +// withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) } +// case WhileDo(cond, body) => +// writeByte(WHILE) +// withLength { pickleTree(cond); pickleTree(body) } +// case Try(block, cases, finalizer) => +// writeByte(TRY) +// withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) } +// case SeqLiteral(elems, elemtpt) => +// writeByte(REPEATED) +// withLength { pickleTree(elemtpt); elems.foreach(pickleTree) } +// case Inlined(call, bindings, expansion) => +// writeByte(INLINED) +// bindings.foreach(preRegister) +// withLength { +// pickleTree(expansion) +// if (!call.isEmpty) pickleTree(call) +// bindings.foreach { b => +// assert(b.isInstanceOf[DefDef] || b.isInstanceOf[ValDef]) +// pickleTree(b) +// } +// } +// case Bind(name, body) => +// registerDef(tree.symbol) +// writeByte(BIND) +// withLength { +// pickleName(name); pickleType(tree.symbol.info); pickleTree(body) +// } +// case Alternative(alts) => +// writeByte(ALTERNATIVE) +// withLength { alts.foreach(pickleTree) } +// case UnApply(fun, implicits, patterns) => +// writeByte(UNAPPLY) +// withLength { +// pickleTree(fun) +// for (implicitArg <- implicits) { +// writeByte(IMPLICITarg) +// pickleTree(implicitArg) +// } +// pickleType(tree.tpe) +// patterns.foreach(pickleTree) +// } +// case tree: ValDef => +// pickleDef(VALDEF, tree.symbol, tree.tpt, tree.rhs) +// case tree: DefDef => +// def pickleParamss(paramss: List[List[ValDef]]): Unit = paramss match +// case Nil => +// case params :: rest => +// pickleParams(params) +// if params.isEmpty || rest.nonEmpty then writeByte(PARAMEND) +// pickleParamss(rest) +// def pickleAllParams = +// pickleParams(tree.tparams) +// pickleParamss(tree.vparamss) +// pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams) +// case tree: TypeDef => +// pickleDef(TYPEDEF, tree.symbol, tree.rhs) +// case tree: Template => +// registerDef(tree.symbol) +// writeByte(TEMPLATE) +// val (params, rest) = decomposeTemplateBody(tree.body) +// withLength { +// pickleParams(params) +// tree.parents.foreach(pickleTree) +// val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info +// if (!tree.self.isEmpty) { +// writeByte(SELFDEF) +// pickleName(tree.self.name) + +// if (!tree.self.tpt.isEmpty) pickleTree(tree.self.tpt) +// else { +// if (!tree.self.isEmpty) registerTreeAddr(tree.self) +// pickleType { +// selfInfo match { +// case sym: Symbol => sym.info +// case tp: Type => tp +// } +// } +// } +// } +// pickleStats(tree.constr :: rest) +// } +// case Import(expr, selectors) => +// writeByte(IMPORT) +// withLength { +// pickleTree(expr) +// pickleSelectors(selectors) +// } +// case PackageDef(pid, stats) => +// writeByte(PACKAGE) +// withLength { pickleType(pid.tpe); pickleStats(stats) } +// case tree: TypeTree => +// pickleType(tree.tpe) +// case SingletonTypeTree(ref) => +// writeByte(SINGLETONtpt) +// pickleTree(ref) +// case RefinedTypeTree(parent, refinements) => +// if (refinements.isEmpty) pickleTree(parent) +// else { +// val refineCls = refinements.head.symbol.owner.asClass +// registerDef(refineCls) +// pickledTypes.put(refineCls.typeRef, currentAddr) +// writeByte(REFINEDtpt) +// refinements.foreach(preRegister) +// withLength { pickleTree(parent); refinements.foreach(pickleTree) } +// } +// case AppliedTypeTree(tycon, args) => +// writeByte(APPLIEDtpt) +// withLength { pickleTree(tycon); args.foreach(pickleTree) } +// case MatchTypeTree(bound, selector, cases) => +// writeByte(MATCHtpt) +// withLength { +// if (!bound.isEmpty) pickleTree(bound) +// pickleTree(selector) +// cases.foreach(pickleTree) +// } +// case ByNameTypeTree(tp) => +// writeByte(BYNAMEtpt) +// pickleTree(tp) +// case Annotated(tree, annot) => +// writeByte(ANNOTATEDtpt) +// withLength { pickleTree(tree); pickleTree(annot) } +// case LambdaTypeTree(tparams, body) => +// writeByte(LAMBDAtpt) +// withLength { pickleParams(tparams); pickleTree(body) } +// case TypeBoundsTree(lo, hi) => +// writeByte(TYPEBOUNDStpt) +// withLength { +// pickleTree(lo); +// if (hi ne lo) pickleTree(hi) +// } +// case Hole(_, idx, args) => +// writeByte(HOLE) +// withLength { +// writeNat(idx) +// args.foreach(pickleTree) +// } +// } +// catch { +// case ex: AssertionError => +// println(i"error when pickling tree $tree") +// throw ex +// } +// } + +// def pickleSelectors(selectors: List[untpd.ImportSelector])(implicit ctx: Context): Unit = +// for sel <- selectors do +// pickleSelector(IMPORTED, sel.imported) +// sel.renamed match +// case to @ Ident(_) => pickleSelector(RENAMED, to) +// case _ => +// sel.bound match +// case bound @ untpd.TypedSplice(tpt) => +// registerTreeAddr(bound) +// writeByte(BOUNDED) +// pickleTree(tpt) +// case _ => + +// def pickleSelector(tag: Int, id: untpd.Ident)(implicit ctx: Context): Unit = { +// registerTreeAddr(id) +// writeByte(tag) +// pickleName(id.name) +// } + +// def pickleModifiers(sym: Symbol)(implicit ctx: Context): Unit = { +// import Flags._ +// var flags = sym.flags +// val privateWithin = sym.privateWithin +// if (privateWithin.exists) { +// writeByte(if (flags.is(Protected)) PROTECTEDqualified else PRIVATEqualified) +// pickleType(privateWithin.typeRef) +// flags = flags &~ Protected +// } +// if (flags.is(ParamAccessor) && sym.isTerm && !sym.isSetter) +// flags = flags &~ ParamAccessor // we only generate a tag for parameter setters +// pickleFlags(flags, sym.isTerm) +// sym.annotations.foreach(pickleAnnotation(sym, _)) +// } + +// def pickleFlags(flags: FlagSet, isTerm: Boolean)(implicit ctx: Context): Unit = { +// import Flags._ +// def writeModTag(tag: Int) = { +// assert(isModifierTag(tag)) +// writeByte(tag) +// } +// if (flags.is(Private)) writeModTag(PRIVATE) +// if (flags.is(Protected)) writeModTag(PROTECTED) +// if (flags.is(Final, butNot = Module)) writeModTag(FINAL) +// if (flags.is(Case)) writeModTag(CASE) +// if (flags.is(Override)) writeModTag(OVERRIDE) +// if (flags.is(Inline)) writeModTag(INLINE) +// if (flags.is(InlineProxy)) writeModTag(INLINEPROXY) +// if (flags.is(Macro)) writeModTag(MACRO) +// if (flags.is(JavaStatic)) writeModTag(STATIC) +// if (flags.is(Module)) writeModTag(OBJECT) +// if (flags.is(Enum)) writeModTag(ENUM) +// if (flags.is(Local)) writeModTag(LOCAL) +// if (flags.is(Synthetic)) writeModTag(SYNTHETIC) +// if (flags.is(Artifact)) writeModTag(ARTIFACT) +// if (flags.is(Scala2x)) writeModTag(SCALA2X) +// if (isTerm) { +// if (flags.is(Implicit)) writeModTag(IMPLICIT) +// if (flags.is(Given)) writeModTag(GIVEN) +// if (flags.is(Erased)) writeModTag(ERASED) +// if (flags.is(Lazy, butNot = Module)) writeModTag(LAZY) +// if (flags.is(AbsOverride)) { writeModTag(ABSTRACT); writeModTag(OVERRIDE) } +// if (flags.is(Mutable)) writeModTag(MUTABLE) +// if (flags.is(Accessor)) writeModTag(FIELDaccessor) +// if (flags.is(CaseAccessor)) writeModTag(CASEaccessor) +// if (flags.is(DefaultParameterized)) writeModTag(DEFAULTparameterized) +// if (flags.is(StableRealizable)) writeModTag(STABLE) +// if (flags.is(Extension)) writeModTag(EXTENSION) +// if (flags.is(ParamAccessor)) writeModTag(PARAMsetter) +// if (flags.is(Exported)) writeModTag(EXPORTED) +// assert(!(flags.is(Label))) +// } +// else { +// if (flags.is(Sealed)) writeModTag(SEALED) +// if (flags.is(Abstract)) writeModTag(ABSTRACT) +// if (flags.is(Trait)) writeModTag(TRAIT) +// if (flags.is(Covariant)) writeModTag(COVARIANT) +// if (flags.is(Contravariant)) writeModTag(CONTRAVARIANT) +// if (flags.is(Opaque)) writeModTag(OPAQUE) +// if (flags.is(Open)) writeModTag(OPEN) +// } +// } + +// private def isUnpicklable(owner: Symbol, ann: Annotation)(implicit ctx: Context) = ann match { +// case Annotation.Child(sym) => sym.isInaccessibleChildOf(owner) +// // If child annotation refers to a local class or enum value under +// // a different toplevel class, it is impossible to pickle a reference to it. +// // Such annotations will be reconstituted when unpickling the child class. +// // See tests/pickling/i3149.scala +// case _ => +// ann.symbol == defn.BodyAnnot // inline bodies are reconstituted automatically when unpickling +// } + +// def pickleAnnotation(owner: Symbol, ann: Annotation)(implicit ctx: Context): Unit = { +// if (!isUnpicklable(owner, ann)) { +// writeByte(ANNOTATION) +// withLength { pickleType(ann.symbol.typeRef); pickleTree(ann.tree) } +// } +// } + +// // ---- main entry points --------------------------------------- + +// def pickle(trees: List[Tree])(implicit ctx: Context): Unit = { +// trees.foreach(tree => if (!tree.isEmpty) pickleTree(tree)) +// def missing = forwardSymRefs.keysIterator.map(sym => sym.showLocated + "(line " + sym.sourcePos.line + ")").toList +// assert(forwardSymRefs.isEmpty, i"unresolved symbols: $missing%, % when pickling ${ctx.source}") +// } + +// def compactify(): Unit = { +// buf.compactify() + +// def updateMapWithDeltas(mp: MutableSymbolMap[Addr]) = +// for (key <- mp.keysIterator.toBuffer[Symbol]) mp(key) = adjusted(mp(key)) + +// updateMapWithDeltas(symRefs) +// } +// } diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index d536acd76f56..1306ef80ab5e 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -4,7 +4,6 @@ package transform import core._ import Contexts.Context import Decorators._ -import tasty._ import config.Printers.{noPrinter, pickling} import java.io.PrintStream import Periods._ @@ -14,6 +13,9 @@ import Flags.Module import reporting.ThrowingReporter import collection.mutable +import dotty.tools.tasty._ +import experimental._ + object Pickler { val name: String = "pickler" } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/CommentPickler.scala b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala similarity index 53% rename from compiler/src/dotty/tools/dotc/core/tasty/CommentPickler.scala rename to tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala index 1b57588f45a8..297c4de94b29 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/CommentPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala @@ -1,21 +1,19 @@ -package dotty.tools.dotc.core.tasty - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Comments.{Comment, CommentsContext, ContextDocstrings} -import dotty.tools.dotc.core.Contexts.Context +package dotty.tools.tasty.experimental import dotty.tools.tasty.TastyBuffer import TastyBuffer.{Addr, NoAddr} import java.nio.charset.Charset -class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr)(implicit ctx: Context) { +class CommentPickler(val pickler: TastyPickler)(addrOfTree: pickler.tasty.Tree => Addr)(implicit ctx: pickler.tasty.Context) { + import pickler.tasty.{_, given} private val buf = new TastyBuffer(5000) pickler.newSection("Comments", buf) - def pickleComment(root: tpd.Tree): Unit = { - assert(ctx.docCtx.isDefined, "Trying to pickle comments, but there's no `docCtx`.") - new Traverser(ctx.docCtx.get).traverse(root) + def pickleComment(root: Tree): Unit = { + val docCtx = ctx.docCtx + assert(docCtx.isDefined, "Trying to pickle comments, but there's no `docCtx`.") + new Traverser(docCtx.get).traverse(root) } def pickleComment(addr: Addr, comment: Option[Comment]): Unit = comment match { @@ -30,10 +28,10 @@ class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr)(implic () } - private class Traverser(docCtx: ContextDocstrings) extends tpd.TreeTraverser { - override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = + private class Traverser(docCtx: ContextDocstrings) extends TreeTraverser { + override def traverse(tree: Tree)(implicit ctx: Context): Unit = tree match { - case md: tpd.MemberDef => + case md: MemberDef => val comment = docCtx.docstring(md.symbol) pickleComment(addrOfTree(md), comment) traverseChildren(md) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala similarity index 64% rename from compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala rename to tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala index 8a7095b21dd3..0b2491d86e04 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala @@ -1,25 +1,15 @@ -package dotty.tools -package dotc -package core -package tasty +package dotty.tools.tasty.experimental import dotty.tools.tasty.TastyFormat.SOURCE import dotty.tools.tasty.TastyBuffer import TastyBuffer._ -import ast._ -import ast.Trees._ -import ast.Trees.WithLazyField -import util.{SourceFile, NoSource} -import core._ -import Contexts._, Symbols._, Annotations._, Decorators._ import collection.mutable -import util.Spans._ -class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) { +class PositionPickler(val pickler: TastyPickler)(addrOfTree: pickler.tasty.untpd.Tree => Addr) { + import pickler.tasty.{_,given} val buf: TastyBuffer = new TastyBuffer(5000) pickler.newSection("Positions", buf) - import ast.tpd._ private val pickledIndices = new mutable.BitSet @@ -30,7 +20,7 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) { def picklePositions(roots: List[Tree])(implicit ctx: Context): Unit = { var lastIndex = 0 - var lastSpan = Span(0, 0) + var lastSpan = Span.empty def pickleDeltas(index: Int, span: Span) = { val addrDelta = index - lastIndex val startDelta = span.start - lastSpan.start @@ -50,26 +40,24 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) { buf.writeInt(pickler.nameBuffer.nameIndex(source.path.toTermName).index) } - /** True if x's position shouldn't be reconstructed automatically from its initial span - */ - def alwaysNeedsPos(x: Positioned) = x match { - case - // initialSpan is inaccurate for trees with lazy field - _: WithLazyField[?] + // def alwaysNeedsPos(x: Positioned) = x match { + // case + // // initialSpan is inaccurate for trees with lazy field + // _: WithLazyField[?] - // A symbol is created before the corresponding tree is unpickled, - // and its position cannot be changed afterwards. - // so we cannot use the tree initialSpan to set the symbol position. - // Instead, we always pickle the position of definitions. - | _: Trees.DefTree[?] + // // A symbol is created before the corresponding tree is unpickled, + // // and its position cannot be changed afterwards. + // // so we cannot use the tree initialSpan to set the symbol position. + // // Instead, we always pickle the position of definitions. + // | _: Trees.DefTree[?] - // package defs might be split into several Tasty files - | _: Trees.PackageDef[?] - // holes can change source files when filled, which means - // they might lose their position - | _: TreePickler.Hole => true - case _ => false - } + // // package defs might be split into several Tasty files + // | _: Trees.PackageDef[?] + // // holes can change source files when filled, which means + // // they might lose their position + // | _: TreePickler.Hole => true + // case _ => false + // } def traverse(x: Any, current: SourceFile): Unit = x match { case x: untpd.Tree => @@ -84,12 +72,12 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) { pickleSource(x.source) } else if (!pickledIndices.contains(addr.index) && - (x.span.toSynthetic != x.envelope(x.source) || alwaysNeedsPos(x))) + (x.span.toSynthetic != x.envelope(x.source) || x.alwaysNeedsPos)) pickleDeltas(addr.index, x.span) } } x match { - case x: untpd.MemberDef @unchecked => traverse(x.symbol.annotations, x.source) + case x: untpd.MemberDef => traverse(x.symbol.annotations, x.source) case _ => } val limit = x.productArity @@ -106,6 +94,6 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) { case _ => } for (root <- roots) - traverse(root, NoSource) + traverse(root, SourceFile.noSource) } } diff --git a/tasty/src/dotty/tools/tasty/experimental/Tasty.scala b/tasty/src/dotty/tools/tasty/experimental/Tasty.scala index 36eb8a7ab91c..45f14a78038b 100644 --- a/tasty/src/dotty/tools/tasty/experimental/Tasty.scala +++ b/tasty/src/dotty/tools/tasty/experimental/Tasty.scala @@ -16,3 +16,5 @@ trait Tasty extends Core with AnnotationOps with FlagOps with PositionOps + with SourceFileOps + with CommentOps diff --git a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala index cdc2518c4486..aff7361aac0a 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala @@ -6,16 +6,12 @@ import dotty.tools.tasty.{TastyFormat, TastyBuffer, TastyHash} import TastyFormat._ import TastyBuffer._ -class TastyPickler[T <: Tasty](given val tasty: T) { self => +class TastyPickler(val tasty: Tasty)(val rootCls: tasty.ClassSymbol) { self => import tasty.{_, given} - var _rootCls: ClassSymbol = _ - def rootCls: ClassSymbol = _rootCls - def rootCls_=(rootCls: ClassSymbol) = _rootCls = rootCls - private val sections = mutable.ArrayBuffer.empty[(NameRef, TastyBuffer)] - val nameBuffer = NameBuffer[tasty.type]() + val nameBuffer = NameBuffer[tasty.type](given tasty) def newSection(name: String, buf: TastyBuffer): Unit = sections += ((nameBuffer.nameIndex(name.toTermName), buf)) @@ -77,5 +73,5 @@ class TastyPickler[T <: Tasty](given val tasty: T) { self => */ var addrOfSym: Symbol => Option[Addr] = (_ => None) - // val treePkl: TreePickler = new TreePickler(this) + val treePkl = new TreePickler(self) } diff --git a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala index fd26389f6ed5..159afa72c82b 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala @@ -9,9 +9,9 @@ object TreePickler { val sectionName = "ASTs" } -class TreePickler(given val tasty: Tasty)(pickler: TastyPickler[tasty.type]) { - import tasty.{_, given} - val buf = TreeBuffer[tasty.type]() +class TreePickler(val pickler: TastyPickler) { + import pickler.tasty.{_, given} + val buf = TreeBuffer[pickler.tasty.type](given pickler.tasty) pickler.newSection(TreePickler.sectionName, buf) import TreePickler._ import buf._ diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala index 2db28a825993..81a2350c326f 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala @@ -4,6 +4,8 @@ import reflect.ClassTag trait AnnotationOps extends Core with + given ClassTag[Annotation] = internal.Annotation_CT + object Annotation with object Child with diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala new file mode 100644 index 000000000000..b9ffc735e095 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala @@ -0,0 +1,9 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait CommentOps extends Core with + + given CommentOps: (comment: Comment) with + def raw: String = internal.Comment_raw(comment) + def span: Span = internal.Comment_span(comment) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala index 1d7a70395c06..499b4e4bf948 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala @@ -7,4 +7,10 @@ trait ContextOps extends Core with given ContextOps: (ctx: Context) with def log(msg: => String, sourcePos: SourcePosition): Unit = internal.Context_log(ctx, msg, sourcePos) - def source: Path = internal.Context_source(ctx) + def source: SourceFile = internal.Context_source(ctx) + def docCtx: Option[ContextDocstrings] = internal.Context_docCtx(ctx) + def withOwner(owner: Symbol): Context = internal.Context_withOwner(ctx, owner) + def withSource(source: SourceFile): Context = internal.Context_withSource(ctx, source) + + given ContextDocstringsOps: (ctx: ContextDocstrings) with + def docstring(sym: Symbol): Option[Comment] = internal.ContextDocstrings_docString(ctx, sym) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala index e36b20d8ea62..086948c4e47b 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala @@ -6,6 +6,8 @@ trait Core with type Context = internal.Context + type SourceFile = internal.SourceFile + type Annotation = internal.Annotation type Designator = internal.Designator @@ -18,8 +20,8 @@ trait Core with type Signature = internal.Signature - // type UntpdTree = internal.UntpdTree - // type TypedSplice = internal.TypedSplice + type Positioned = internal.Positioned + type Tree = internal.Tree type MemberDef = internal.MemberDef type Hole = internal.Hole @@ -45,6 +47,7 @@ trait Core with type Closure = internal.Closure type Match = internal.Match type CaseDef = internal.CaseDef + type Labeled = internal.Labeled type Return = internal.Return type WhileDo = internal.WhileDo type Try = internal.Try @@ -64,7 +67,7 @@ trait Core with type Annotated = internal.Annotated type LambdaTypeTree = internal.LambdaTypeTree type TypeBoundsTree = internal.TypeBoundsTree - // type ImportSelector = internal.ImportSelector + type Thicket = internal.Thicket type Type = internal.Type type AppliedType = internal.AppliedType @@ -105,5 +108,10 @@ trait Core with type Flag = internal.Flag type SourcePosition = internal.SourcePosition + type Span = internal.Span type Constant = internal.Constant + + type ContextDocstrings = internal.ContextDocstrings + + type Comment = internal.Comment diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala index a2aa4904c523..1ea4aae5db50 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala @@ -4,5 +4,24 @@ import reflect.ClassTag trait PositionOps extends Core with - given SourcePosition: (pos: SourcePosition) with + given PositionedOps: (positioned: Positioned) with + + /** True if x's position shouldn't be reconstructed automatically from its initial span + */ + def alwaysNeedsPos: Boolean = internal.Positioned_alwaysNeedsPos(positioned) + + given SourcePositionOps: (pos: SourcePosition) with def line: Int = internal.SourcePosition_line(pos) + + object Span with + val empty: Span = internal.Span_empty + val noSpan: Span = internal.Span_noSpan + + given SpanOps: (span: Span) with + def coords: Long = internal.Span_coords(span) + def isSynthetic: Boolean = internal.Span_isSynthetic(span) + def toSynthetic: Span = internal.Span_toSynthetic(span) + def start: Int = internal.Span_start(span) + def end: Int = internal.Span_end(span) + def pointDelta: Int = internal.Span_pointDelta(span) + def exists: Boolean = internal.Span_exists(span) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala new file mode 100644 index 000000000000..5eaa9c38ad43 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala @@ -0,0 +1,12 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait SourceFileOps extends Core with + + object SourceFile with + val noSource: SourceFile = internal.SourceFile_noSource + + given SourceFileOps: (source: SourceFile) with + def path: String = internal.SourceFile_path(source) + def exists: Boolean = internal.SourceFile_exists(source) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala index 606c38084450..e41ad2a4256d 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala @@ -10,9 +10,12 @@ trait TastyKernel with type Context <: AnyRef + type SourceFile <: AnyRef + type Designator <: AnyRef type Annotation <: AnyRef + val Annotation_CT: ClassTag[Annotation] type Name <: Designator type SimpleName <: TermName @@ -32,9 +35,12 @@ trait TastyKernel with type Signature_ParamSig = Int | TypeName - type untpd_Tree <: AnyRef + type Positioned <: AnyRef + + type untpd_Tree <: Product with Positioned type untpd_ImportSelector <: untpd_Tree type untpd_TypedSplice <: untpd_Tree + type untpd_MemberDef <: untpd_Tree type Tree <: untpd_Tree { type ThisTree <: Tree } type MemberDef <: Tree @@ -61,12 +67,13 @@ trait TastyKernel with type Closure <: Tree // TermTree type Match <: Tree // TermTree type CaseDef <: Tree + type Labeled <: Tree // NameTree type Return <: Tree // TermTree type WhileDo <: Tree // TermTree type Try <: Tree // TermTree type SeqLiteral <: Tree // TermTree type Inlined <: Tree - type Bind <: Tree // NameTree[T] with DefTree[T] with PatternTree[T] + type Bind <: Tree // NameTree with DefTree with PatternTree type Alternative <: Tree // PatternTree type UnApply <: Tree // PatternTree type Import <: Tree // DenotingTree @@ -80,9 +87,12 @@ trait TastyKernel with type Annotated <: Tree type LambdaTypeTree <: Tree // TypTree[T] type TypeBoundsTree <: Tree // TypTree[T] + type Thicket <: Tree val untpd_Tree_CT: ClassTag[untpd_Tree] val untpd_TypedSplice_CT: ClassTag[untpd_TypedSplice] + val untpd_MemberDef_CT: ClassTag[untpd_MemberDef] + val Tree_CT: ClassTag[Tree] val MemberDef_CT: ClassTag[MemberDef] val Hole_CT: ClassTag[Hole] @@ -107,6 +117,7 @@ trait TastyKernel with val Closure_CT: ClassTag[Closure] val Match_CT: ClassTag[Match] val CaseDef_CT: ClassTag[CaseDef] + val Labeled_CT: ClassTag[Labeled] val Return_CT: ClassTag[Return] val WhileDo_CT: ClassTag[WhileDo] val Try_CT: ClassTag[Try] @@ -126,6 +137,7 @@ trait TastyKernel with val Annotated_CT: ClassTag[Annotated] val LambdaTypeTree_CT: ClassTag[LambdaTypeTree] val TypeBoundsTree_CT: ClassTag[TypeBoundsTree] + val Thicket_CT: ClassTag[Thicket] type Type <: AnyRef type AppliedType <: Type // <: CachedProxyType with ValueType @@ -197,8 +209,13 @@ trait TastyKernel with type Symbols_MutableSymbolMap[T] <: AnyRef type SourcePosition <: AnyRef + type Span <: AnyVal - type Constant + type ContextDocstrings <: AnyRef + + type Comment <: AnyRef + + type Constant <: AnyVal val Flags_Protected: Flag val Flags_ParamAccessor: Flag @@ -257,7 +274,12 @@ trait TastyKernel with final val Constants_EnumTag = 13 def Context_log(ctx: Context, msg: => String, sourcePos: SourcePosition): Unit - def Context_source(ctx: Context): Path + def Context_source(ctx: Context): SourceFile + def Context_docCtx(ctx: Context): Option[ContextDocstrings] + def Context_withOwner(ctx: Context, owner: Symbol): Context + def Context_withSource(ctx: Context, source: SourceFile): Context + + def ContextDocstrings_docString(ctx: ContextDocstrings, sym: Symbol): Option[Comment] def Constant_tag(c: Constant): Int def Constant_intValue(c: Constant): Int @@ -303,8 +325,22 @@ trait TastyKernel with def Symbol_annotations(sym: Symbol)(given Context): List[Annotation] def Symbol_isInaccessibleChildOf(sym: Symbol, cls: Symbol)(given Context): Boolean + def SourceFile_path(source: SourceFile): String + def SourceFile_exists(source: SourceFile): Boolean + val SourceFile_noSource: SourceFile + def SourcePosition_line(pos: SourcePosition): Int + val Span_empty: Span + val Span_noSpan: Span + def Span_start(span: Span): Int + def Span_end(span: Span): Int + def Span_isSynthetic(span: Span): Boolean + def Span_toSynthetic(span: Span): Span + def Span_pointDelta(span: Span): Int + def Span_coords(span: Span): Long + def Span_exists(span: Span): Boolean + def defn_throwMethod(given Context): TermSymbol def defn_BodyAnnot(given Context): ClassSymbol @@ -313,7 +349,13 @@ trait TastyKernel with def Name_isTypeName(name: Name): Boolean def Name_length(name: Name): Int - def Tree_symbol(tree: Tree)(given Context): Symbol + def Positioned_alwaysNeedsPos(positioned: Positioned): Boolean + + def untpd_Tree_span(tree: untpd_Tree): Span + def untpd_Tree_source(tree: untpd_Tree): SourceFile + def untpd_Tree_envelope(tree: untpd_Tree, src: SourceFile, startSpan: Span): Span + def untpd_Tree_symbol(tree: untpd_Tree)(given Context): Symbol + def Tree_withType(tree: Tree, tpe: Type)(given Context): tree.ThisTree def Tree_isEmpty(tree: Tree): Boolean def Tree_isType(tree: Tree): Boolean @@ -321,6 +363,8 @@ trait TastyKernel with def Tree_tpe(tree: Tree): Type val EmptyTree: Tree + def inlineContext(tree: Tree)(implicit ctx: Context): Context + def TypedSplice_unapply(tree: untpd_TypedSplice): Some[Tree] def Ident_unapply(tree: Ident): Some[Name] def This_unapply(tree: This): Some[Ident] @@ -338,6 +382,7 @@ trait TastyKernel with def Closure_unapply(tree: Closure): (List[Tree], Tree, Tree) def Match_unapply(tree: Match): (Tree, List[CaseDef]) def CaseDef_unapply(tree: CaseDef): (Tree, Tree, Tree) + def Labeled_unapply(tree: Labeled): (Bind, Tree) def Return_unapply(tree: Return): (Tree, Tree) def WhileDo_unapply(tree: WhileDo): (Tree, Tree) def Try_unapply(tree: Try): (Tree, List[CaseDef], Tree) @@ -357,6 +402,7 @@ trait TastyKernel with def LambdaTypeTree_unapply(tree: LambdaTypeTree): (List[TypeDef], Tree) def TypeBoundsTree_unapply(tree: TypeBoundsTree): (Tree, Tree) def Hole_unapply(tree: Hole): (Int, List[Tree]) + def Thicket_unapply(tree: Thicket): Some[List[Tree]] def ValOrDefDef_name(tree: ValOrDefDef): TermName def ValOrDefDef_tpt(tree: ValOrDefDef): Tree @@ -372,6 +418,8 @@ trait TastyKernel with def Template_decomposeBody(tree: Template)(given Context): (List[Tree], List[Tree]) def Template_parents(tree: Template): List[Tree] def Template_self(tree: Template): ValDef + def Template_body(tree: Template): List[Tree] + def Template_derived(tree: Template): List[untpd_Tree] def Template_constr(tree: Template): DefDef def Type_stripTypeVar(tpe: Type)(given Context): Type @@ -465,3 +513,6 @@ trait TastyKernel with def pickling_println(msg: => String): Unit def StringContext_i(stringContext: StringContext, args: Any*): String + + def Comment_raw(comment: Comment): String + def Comment_span(comment: Comment): Span diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala index 4917c8ebbb89..ef4ba052e65b 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala @@ -3,7 +3,7 @@ package dotty.tools.tasty.experimental.bridge import reflect.ClassTag trait TreeOps extends Core with - self => + self: PositionOps with ContextOps with SourceFileOps with SymbolOps => given ClassTag[Tree] = internal.Tree_CT given ClassTag[MemberDef] = internal.MemberDef_CT @@ -29,6 +29,7 @@ trait TreeOps extends Core with given ClassTag[Closure] = internal.Closure_CT given ClassTag[Match] = internal.Match_CT given ClassTag[CaseDef] = internal.CaseDef_CT + given ClassTag[Labeled] = internal.Labeled_CT given ClassTag[Return] = internal.Return_CT given ClassTag[WhileDo] = internal.WhileDo_CT given ClassTag[Try] = internal.Try_CT @@ -48,15 +49,18 @@ trait TreeOps extends Core with given ClassTag[Annotated] = internal.Annotated_CT given ClassTag[LambdaTypeTree] = internal.LambdaTypeTree_CT given ClassTag[TypeBoundsTree] = internal.TypeBoundsTree_CT + given ClassTag[Thicket] = internal.Thicket_CT + + given untpdTree: ClassTag[untpd.Tree] = internal.untpd_Tree_CT + given untpdTypedSplice: ClassTag[untpd.TypedSplice] = internal.untpd_TypedSplice_CT + given untpdMemberDef: ClassTag[untpd.MemberDef] = internal.untpd_MemberDef_CT object untpd with type Tree = internal.untpd_Tree type TypedSplice = internal.untpd_TypedSplice type ImportSelector = internal.untpd_ImportSelector - - given ClassTag[Tree] = internal.untpd_Tree_CT - given ClassTag[TypedSplice] = internal.untpd_TypedSplice_CT + type MemberDef = internal.untpd_MemberDef object TypedSplice with def unapply(tree: TypedSplice): Some[self.Tree] = internal.TypedSplice_unapply(tree) @@ -100,6 +104,8 @@ trait TreeOps extends Core with def unapply(tree: Match): (Tree, List[CaseDef]) = internal.Match_unapply(tree) object CaseDef with def unapply(tree: CaseDef): (Tree, Tree, Tree) = internal.CaseDef_unapply(tree) + object Labeled with + def unapply(tree: Labeled): (Bind, Tree) = internal.Labeled_unapply(tree) object Return with def unapply(tree: Return): (Tree, Tree) = internal.Return_unapply(tree) object WhileDo with @@ -138,9 +144,16 @@ trait TreeOps extends Core with def unapply(tree: TypeBoundsTree): (Tree, Tree) = internal.TypeBoundsTree_unapply(tree) object Hole with def unapply(tree: Hole): (Int, List[Tree]) = internal.Hole_unapply(tree) + object Thicket with + def unapply(tree: Thicket): Some[List[Tree]] = internal.Thicket_unapply(tree) + + given untpdTreeOps: (tree: untpd.Tree) with + def symbol(given Context): Symbol = internal.untpd_Tree_symbol(tree) + def span: Span = internal.untpd_Tree_span(tree) + def source: SourceFile = internal.untpd_Tree_source(tree) + def envelope(src: SourceFile, startSpan: Span = Span.noSpan): Span = internal.untpd_Tree_envelope(tree, src, startSpan) given TreeOps: (tree: Tree) with - def symbol(given Context): Symbol = internal.Tree_symbol(tree) def isEmpty: Boolean = internal.Tree_isEmpty(tree) def isType: Boolean = internal.Tree_isType(tree) def withType(tpe: Type)(given Context): tree.ThisTree = internal.Tree_withType(tree, tpe) @@ -164,5 +177,122 @@ trait TreeOps extends Core with def parents: List[Tree] = internal.Template_parents(tree) def self: ValDef = internal.Template_self(tree) def constr: DefDef = internal.Template_constr(tree) + def body: List[Tree] = internal.Template_body(tree) + def derived: List[untpd.Tree] = internal.Template_derived(tree) final val EmptyTree = internal.EmptyTree + + def inlineContext(tree: Tree)(implicit ctx: Context): Context = internal.inlineContext(tree) + + abstract class TreeAccumulator[X] { self => + def apply(x: X, tree: Tree)(implicit ctx: Context): X + + def apply(x: X, trees: Traversable[Tree])(implicit ctx: Context): X = + trees.foldLeft(x)(apply) + + def foldOver(x: X, tree: Tree)(implicit ctx: Context): X = + if (tree.source != ctx.source && tree.source.exists) + foldOver(x, tree)(ctx.withSource(tree.source)) + else { + def localCtx = + if (/*tree.hasType && -- Tree is biased to tpd.Tree */ tree.symbol.exists) ctx.withOwner(tree.symbol) else ctx + tree match { + case Ident(name) => + x + case Select(qualifier, name) => + this(x, qualifier) + case This(qual) => + x + case Super(qual, mix) => + this(x, qual) + case Apply(fun, args) => + this(this(x, fun), args) + case TypeApply(fun, args) => + this(this(x, fun), args) + case Literal(const) => + x + case New(tpt) => + this(x, tpt) + case Typed(expr, tpt) => + this(this(x, expr), tpt) + case NamedArg(name, arg) => + this(x, arg) + case Assign(lhs, rhs) => + this(this(x, lhs), rhs) + case Block(stats, expr) => + this(this(x, stats), expr) + case If(cond, thenp, elsep) => + this(this(this(x, cond), thenp), elsep) + case Closure(env, meth, tpt) => + this(this(this(x, env), meth), tpt) + case Match(selector, cases) => + this(this(x, selector), cases) + case CaseDef(pat, guard, body) => + this(this(this(x, pat), guard), body) + case Labeled(bind, expr) => + this(this(x, bind), expr) + case Return(expr, from) => + this(this(x, expr), from) + case WhileDo(cond, body) => + this(this(x, cond), body) + case Try(block, handler, finalizer) => + this(this(this(x, block), handler), finalizer) + case SeqLiteral(elems, elemtpt) => + this(this(x, elems), elemtpt) + case Inlined(call, bindings, expansion) => + this(this(x, bindings), expansion)(inlineContext(call)) + case _: TypeTree => + x + case SingletonTypeTree(ref) => + this(x, ref) + case RefinedTypeTree(tpt, refinements) => + this(this(x, tpt), refinements) + case AppliedTypeTree(tpt, args) => + this(this(x, tpt), args) + case LambdaTypeTree(tparams, body) => + implicit val ctx = localCtx + this(this(x, tparams), body) + case MatchTypeTree(bound, selector, cases) => + this(this(this(x, bound), selector), cases) + case ByNameTypeTree(result) => + this(x, result) + case TypeBoundsTree(lo, hi) => + this(this(x, lo), hi) + case Bind(name, body) => + this(x, body) + case Alternative(trees) => + this(x, trees) + case UnApply(fun, implicits, patterns) => + this(this(this(x, fun), implicits), patterns) + case tree: ValDef => + implicit val ctx = localCtx + this(this(x, tree.tpt), tree.rhs) + case tree: DefDef => + implicit val ctx = localCtx + this(this(tree.vparamss.foldLeft(this(x, tree.tparams))(apply), tree.tpt), tree.rhs) + case tree: TypeDef => + implicit val ctx = localCtx + this(x, tree.rhs) + case tree: Template if tree.derived.isEmpty => + this(this(this(this(x, tree.constr), tree.parents), tree.self), tree.body) + case Import(expr, _) => + this(x, expr) + case PackageDef(pid, stats) => + this(this(x, pid), stats)(localCtx) + case Annotated(arg, annot) => + this(this(x, arg), annot) + case Thicket(ts) => + this(x, ts) + case Hole(_, args) => + this(x, args) + case _ => + x + } + } + } + + abstract class TreeTraverser extends TreeAccumulator[Unit] { + def traverse(tree: Tree)(implicit ctx: Context): Unit + def apply(x: Unit, tree: Tree)(implicit ctx: Context): Unit = traverse(tree) + protected def traverseChildren(tree: Tree)(implicit ctx: Context): Unit = foldOver((), tree) + } From 04be04324d2992b5d045aaa5c600c3741ec6b2a8 Mon Sep 17 00:00:00 2001 From: bishabosha Date: Sat, 30 Nov 2019 23:26:47 +0100 Subject: [PATCH 3/8] Implement TastyKernel for Dotty --- .../dotc/core/quoted/PickledQuotes.scala | 33 +- .../core/tasty/experimental/DottyKernel.scala | 806 ++++++++++++++++++ .../dotty/tools/dotc/transform/Pickler.scala | 125 +-- .../tasty/experimental/PositionPickler.scala | 19 - .../tasty/experimental/TreePickler.scala | 6 +- .../experimental/bridge/ContextOps.scala | 2 +- .../tasty/experimental/bridge/NameOps.scala | 1 - .../tasty/experimental/bridge/StringOps.scala | 2 +- .../tasty/experimental/bridge/SymbolOps.scala | 6 +- .../experimental/bridge/TastyKernel.scala | 45 +- .../tasty/experimental/bridge/TreeOps.scala | 26 +- 11 files changed, 937 insertions(+), 134 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 0c566c674744..e559504ecfda 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -12,12 +12,12 @@ 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, TastyPrinter } +import dotty.tools.dotc.core.tasty.TastyPrinter import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode import dotty.tools.dotc.quoted.QuoteContext import dotty.tools.dotc.tastyreflect.{ReflectionImpl, TastyTreeExpr, TreeType} -import dotty.tools.tasty.experimental.TastyPickler +import dotty.tools.tasty.experimental.{ TastyPickler, PositionPickler } import dotty.tools.tasty.TastyString import scala.internal.quoted._ @@ -99,24 +99,25 @@ object PickledQuotes { /** Pickle tree into it's TASTY bytes s*/ private def pickle(tree: Tree)(implicit ctx: Context): Array[Byte] = { - val pickler = new TastyPickler(defn.RootClass) - val treePkl = pickler.treePkl - treePkl.pickle(tree :: Nil) - treePkl.compactify() - pickler.addrOfTree = treePkl.buf.addrOfTree - pickler.addrOfSym = treePkl.addrOfSym - if (tree.span.exists) - new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) + // val pickler = new TastyPickler(defn.RootClass) + // val treePkl = pickler.treePkl + // treePkl.pickle(tree :: Nil) + // treePkl.compactify() + // pickler.addrOfTree = treePkl.buf.addrOfTree + // pickler.addrOfSym = treePkl.addrOfSym + // if (tree.span.exists) + // new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) - if (quotePickling ne noPrinter) - println(i"**** pickling quote of \n${tree.show}") + // if (quotePickling ne noPrinter) + // println(i"**** pickling quote of \n${tree.show}") - val pickled = pickler.assembleParts() + // val pickled = pickler.assembleParts() - if (quotePickling ne noPrinter) - println(new TastyPrinter(pickled).printContents()) + // if (quotePickling ne noPrinter) + // println(new TastyPrinter(pickled).printContents()) - pickled + // pickled + Array.empty } /** Unpickle TASTY bytes into it's tree */ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala new file mode 100644 index 000000000000..fd297eec1ce4 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala @@ -0,0 +1,806 @@ +package dotty.tools.dotc.core.tasty.experimental + +import reflect.{classTag, ClassTag} + +import dotty.tools.dotc.core.tasty.TreePickler + +import dotty.tools.tasty.experimental.function._ +import dotty.tools.tasty.experimental.bridge.TastyKernel +import dotty.tools.dotc.config.Printers +import dotty.tools.dotc.{util, core, ast, transform} + +import core.Contexts, core.Names, core.Annotations, core.Types, core.Symbols, core.Flags, util.Spans, + core.Comments, core.Constants, ast.Trees, core.Decorators, core.NameKinds, core.StdNames +import ast.{tpd, untpd} + +object DottyKernel extends TastyKernel { + + type Context = Contexts.Context + + type SourceFile = util.SourceFile + + type Designator = Names.Designator + + type Annotation = Annotations.Annotation + + val Annotation_CT = classTag[Annotation] + + type Name = Names.Name + type SimpleName = Names.SimpleName + type DerivedName = Names.DerivedName + type TypeName = Names.TypeName + type TermName = Names.TermName + + val Name_CT = classTag[Name] + val SimpleName_CT = classTag[SimpleName] + val DerivedName_CT = classTag[DerivedName] + val TypeName_CT = classTag[TypeName] + val TermName_CT = classTag[TermName] + + type Signature = core.Signature + val Signature_CT = classTag[Signature] + + type Positioned = ast.Positioned + + type untpd_Tree = untpd.Tree + type untpd_ImportSelector = untpd.ImportSelector + type untpd_TypedSplice = untpd.TypedSplice + type untpd_MemberDef = untpd.MemberDef + type untpd_Ident = untpd.Ident + + type Tree = tpd.Tree + type MemberDef = tpd.MemberDef + type Hole = TreePickler.Hole + type Template = tpd.Template + type ValOrDefDef = tpd.ValOrDefDef + type TypeDef = tpd.TypeDef + type ValDef = tpd.ValDef + type DefDef = tpd.DefDef + type RefTree = tpd.RefTree + type Ident = tpd.Ident + type This = tpd.This + type Select = tpd.Select + type Apply = tpd.Apply + type TypeApply = tpd.TypeApply + type Literal = tpd.Literal + type Super = tpd.Super + type New = tpd.New + type Typed = tpd.Typed + type NamedArg = tpd.NamedArg + type Assign = tpd.Assign + type Block = tpd.Block + type If = tpd.If + type Closure = tpd.Closure + type Match = tpd.Match + type CaseDef = tpd.CaseDef + type Labeled = tpd.Labeled + type Return = tpd.Return + type WhileDo = tpd.WhileDo + type Try = tpd.Try + type SeqLiteral = tpd.SeqLiteral + type Inlined = tpd.Inlined + type Bind = tpd.Bind + type Alternative = tpd.Alternative + type UnApply = tpd.UnApply + type Import = tpd.Import + type PackageDef = tpd.PackageDef + type TypeTree = tpd.TypeTree + type SingletonTypeTree = tpd.SingletonTypeTree + type RefinedTypeTree = tpd.RefinedTypeTree + type AppliedTypeTree = tpd.AppliedTypeTree + type MatchTypeTree = tpd.MatchTypeTree + type ByNameTypeTree = tpd.ByNameTypeTree + type Annotated = tpd.Annotated + type LambdaTypeTree = tpd.LambdaTypeTree + type TypeBoundsTree = tpd.TypeBoundsTree + type Thicket = tpd.Thicket + + val untpd_Tree_CT: ClassTag[untpd_Tree] = new { + def runtimeClass: Class[?] = classOf[untpd_Tree] + override def unapply(x: Any): Option[untpd_Tree] = x match + case tree: untpd.Tree => Some(tree) + case _ => None + } + val untpd_TypedSplice_CT: ClassTag[untpd_TypedSplice] = new { + def runtimeClass: Class[?] = classOf[untpd_TypedSplice] + override def unapply(x: Any): Option[untpd_TypedSplice] = x match + case tree: untpd.TypedSplice => Some(tree) + case _ => None + } + val untpd_MemberDef_CT: ClassTag[untpd_MemberDef] = new { + def runtimeClass: Class[?] = classOf[untpd_MemberDef] + override def unapply(x: Any): Option[untpd_MemberDef] = x match + case tree: untpd.MemberDef => Some(tree) + case _ => None + } + val untpd_Ident_CT: ClassTag[untpd_Ident] = new { + def runtimeClass: Class[?] = classOf[untpd_Ident] + override def unapply(x: Any): Option[untpd_Ident] = x match + case tree: untpd.Ident => Some(tree) + case _ => None + } + + val Tree_CT: ClassTag[Tree] = new { + def runtimeClass: Class[?] = classOf[Tree] + override def unapply(x: Any): Option[Tree] = x match + case tree: tpd.Tree => Some(tree) + case _ => None + } + val MemberDef_CT: ClassTag[MemberDef] = new { + def runtimeClass: Class[?] = classOf[MemberDef] + override def unapply(x: Any): Option[MemberDef] = x match + case tree: tpd.MemberDef => Some(tree) + case _ => None + } + val Hole_CT: ClassTag[Hole] = new { + def runtimeClass: Class[?] = classOf[Hole] + override def unapply(x: Any): Option[Hole] = x match + case tree: TreePickler.Hole => Some(tree) + case _ => None + } + val Template_CT: ClassTag[Template] = new { + def runtimeClass: Class[?] = classOf[Template] + override def unapply(x: Any): Option[Template] = x match + case tree: tpd.Template => Some(tree) + case _ => None + } + val ValOrDefDef_CT: ClassTag[ValOrDefDef] = new { + def runtimeClass: Class[?] = classOf[ValOrDefDef] + override def unapply(x: Any): Option[ValOrDefDef] = x match + case tree: tpd.ValOrDefDef => Some(tree) + case _ => None + } + val TypeDef_CT: ClassTag[TypeDef] = new { + def runtimeClass: Class[?] = classOf[TypeDef] + override def unapply(x: Any): Option[TypeDef] = x match + case tree: tpd.TypeDef => Some(tree) + case _ => None + } + val ValDef_CT: ClassTag[ValDef] = new { + def runtimeClass: Class[?] = classOf[ValDef] + override def unapply(x: Any): Option[ValDef] = x match + case tree: tpd.ValDef => Some(tree) + case _ => None + } + val DefDef_CT: ClassTag[DefDef] = new { + def runtimeClass: Class[?] = classOf[DefDef] + override def unapply(x: Any): Option[DefDef] = x match + case tree: tpd.DefDef => Some(tree) + case _ => None + } + val Ident_CT: ClassTag[Ident] = new { + def runtimeClass: Class[?] = classOf[Ident] + override def unapply(x: Any): Option[Ident] = x match + case tree: tpd.Ident => Some(tree) + case _ => None + } + val This_CT: ClassTag[This] = new { + def runtimeClass: Class[?] = classOf[This] + override def unapply(x: Any): Option[This] = x match + case tree: tpd.This => Some(tree) + case _ => None + } + val Select_CT: ClassTag[Select] = new { + def runtimeClass: Class[?] = classOf[Select] + override def unapply(x: Any): Option[Select] = x match + case tree: tpd.Select => Some(tree) + case _ => None + } + val Apply_CT: ClassTag[Apply] = new { + def runtimeClass: Class[?] = classOf[Apply] + override def unapply(x: Any): Option[Apply] = x match + case tree: tpd.Apply => Some(tree) + case _ => None + } + val TypeApply_CT: ClassTag[TypeApply] = new { + def runtimeClass: Class[?] = classOf[TypeApply] + override def unapply(x: Any): Option[TypeApply] = x match + case tree: tpd.TypeApply => Some(tree) + case _ => None + } + val Literal_CT: ClassTag[Literal] = new { + def runtimeClass: Class[?] = classOf[Literal] + override def unapply(x: Any): Option[Literal] = x match + case tree: tpd.Literal => Some(tree) + case _ => None + } + val Super_CT: ClassTag[Super] = new { + def runtimeClass: Class[?] = classOf[Super] + override def unapply(x: Any): Option[Super] = x match + case tree: tpd.Super => Some(tree) + case _ => None + } + val New_CT: ClassTag[New] = new { + def runtimeClass: Class[?] = classOf[New] + override def unapply(x: Any): Option[New] = x match + case tree: tpd.New => Some(tree) + case _ => None + } + val Typed_CT: ClassTag[Typed] = new { + def runtimeClass: Class[?] = classOf[Typed] + override def unapply(x: Any): Option[Typed] = x match + case tree: tpd.Typed => Some(tree) + case _ => None + } + val NamedArg_CT: ClassTag[NamedArg] = new { + def runtimeClass: Class[?] = classOf[NamedArg] + override def unapply(x: Any): Option[NamedArg] = x match + case tree: tpd.NamedArg => Some(tree) + case _ => None + } + val Assign_CT: ClassTag[Assign] = new { + def runtimeClass: Class[?] = classOf[Assign] + override def unapply(x: Any): Option[Assign] = x match + case tree: tpd.Assign => Some(tree) + case _ => None + } + val Block_CT: ClassTag[Block] = new { + def runtimeClass: Class[?] = classOf[Block] + override def unapply(x: Any): Option[Block] = x match + case tree: tpd.Block => Some(tree) + case _ => None + } + val If_CT: ClassTag[If] = new { + def runtimeClass: Class[?] = classOf[If] + override def unapply(x: Any): Option[If] = x match + case tree: tpd.If => Some(tree) + case _ => None + } + val Closure_CT: ClassTag[Closure] = new { + def runtimeClass: Class[?] = classOf[Closure] + override def unapply(x: Any): Option[Closure] = x match + case tree: tpd.Closure => Some(tree) + case _ => None + } + val Match_CT: ClassTag[Match] = new { + def runtimeClass: Class[?] = classOf[Match] + override def unapply(x: Any): Option[Match] = x match + case tree: tpd.Match => Some(tree) + case _ => None + } + val CaseDef_CT: ClassTag[CaseDef] = new { + def runtimeClass: Class[?] = classOf[CaseDef] + override def unapply(x: Any): Option[CaseDef] = x match + case tree: tpd.CaseDef => Some(tree) + case _ => None + } + val Labeled_CT: ClassTag[Labeled] = new { + def runtimeClass: Class[?] = classOf[Labeled] + override def unapply(x: Any): Option[Labeled] = x match + case tree: tpd.Labeled => Some(tree) + case _ => None + } + val Return_CT: ClassTag[Return] = new { + def runtimeClass: Class[?] = classOf[Return] + override def unapply(x: Any): Option[Return] = x match + case tree: tpd.Return => Some(tree) + case _ => None + } + val WhileDo_CT: ClassTag[WhileDo] = new { + def runtimeClass: Class[?] = classOf[WhileDo] + override def unapply(x: Any): Option[WhileDo] = x match + case tree: tpd.WhileDo => Some(tree) + case _ => None + } + val Try_CT: ClassTag[Try] = new { + def runtimeClass: Class[?] = classOf[Try] + override def unapply(x: Any): Option[Try] = x match + case tree: tpd.Try => Some(tree) + case _ => None + } + val SeqLiteral_CT: ClassTag[SeqLiteral] = new { + def runtimeClass: Class[?] = classOf[SeqLiteral] + override def unapply(x: Any): Option[SeqLiteral] = x match + case tree: tpd.SeqLiteral => Some(tree) + case _ => None + } + val Inlined_CT: ClassTag[Inlined] = new { + def runtimeClass: Class[?] = classOf[Inlined] + override def unapply(x: Any): Option[Inlined] = x match + case tree: tpd.Inlined => Some(tree) + case _ => None + } + val Bind_CT: ClassTag[Bind] = new { + def runtimeClass: Class[?] = classOf[Bind] + override def unapply(x: Any): Option[Bind] = x match + case tree: tpd.Bind => Some(tree) + case _ => None + } + val Alternative_CT: ClassTag[Alternative] = new { + def runtimeClass: Class[?] = classOf[Alternative] + override def unapply(x: Any): Option[Alternative] = x match + case tree: tpd.Alternative => Some(tree) + case _ => None + } + val UnApply_CT: ClassTag[UnApply] = new { + def runtimeClass: Class[?] = classOf[UnApply] + override def unapply(x: Any): Option[UnApply] = x match + case tree: tpd.UnApply => Some(tree) + case _ => None + } + val Import_CT: ClassTag[Import] = new { + def runtimeClass: Class[?] = classOf[Import] + override def unapply(x: Any): Option[Import] = x match + case tree: tpd.Import => Some(tree) + case _ => None + } + val PackageDef_CT: ClassTag[PackageDef] = new { + def runtimeClass: Class[?] = classOf[PackageDef] + override def unapply(x: Any): Option[PackageDef] = x match + case tree: tpd.PackageDef => Some(tree) + case _ => None + } + val TypeTree_CT: ClassTag[TypeTree] = new { + def runtimeClass: Class[?] = classOf[TypeTree] + override def unapply(x: Any): Option[TypeTree] = x match + case tree: tpd.TypeTree => Some(tree) + case _ => None + } + val SingletonTypeTree_CT: ClassTag[SingletonTypeTree] = new { + def runtimeClass: Class[?] = classOf[SingletonTypeTree] + override def unapply(x: Any): Option[SingletonTypeTree] = x match + case tree: tpd.SingletonTypeTree => Some(tree) + case _ => None + } + val RefinedTypeTree_CT: ClassTag[RefinedTypeTree] = new { + def runtimeClass: Class[?] = classOf[RefinedTypeTree] + override def unapply(x: Any): Option[RefinedTypeTree] = x match + case tree: tpd.RefinedTypeTree => Some(tree) + case _ => None + } + val AppliedTypeTree_CT: ClassTag[AppliedTypeTree] = new { + def runtimeClass: Class[?] = classOf[AppliedTypeTree] + override def unapply(x: Any): Option[AppliedTypeTree] = x match + case tree: tpd.AppliedTypeTree => Some(tree) + case _ => None + } + val MatchTypeTree_CT: ClassTag[MatchTypeTree] = new { + def runtimeClass: Class[?] = classOf[MatchTypeTree] + override def unapply(x: Any): Option[MatchTypeTree] = x match + case tree: tpd.MatchTypeTree => Some(tree) + case _ => None + } + val ByNameTypeTree_CT: ClassTag[ByNameTypeTree] = new { + def runtimeClass: Class[?] = classOf[ByNameTypeTree] + override def unapply(x: Any): Option[ByNameTypeTree] = x match + case tree: tpd.ByNameTypeTree => Some(tree) + case _ => None + } + val Annotated_CT: ClassTag[Annotated] = new { + def runtimeClass: Class[?] = classOf[Annotated] + override def unapply(x: Any): Option[Annotated] = x match + case tree: tpd.Annotated => Some(tree) + case _ => None + } + val LambdaTypeTree_CT: ClassTag[LambdaTypeTree] = new { + def runtimeClass: Class[?] = classOf[LambdaTypeTree] + override def unapply(x: Any): Option[LambdaTypeTree] = x match + case tree: tpd.LambdaTypeTree => Some(tree) + case _ => None + } + val TypeBoundsTree_CT: ClassTag[TypeBoundsTree] = new { + def runtimeClass: Class[?] = classOf[TypeBoundsTree] + override def unapply(x: Any): Option[TypeBoundsTree] = x match + case tree: tpd.TypeBoundsTree => Some(tree) + case _ => None + } + val Thicket_CT: ClassTag[Thicket] = new { + def runtimeClass: Class[?] = classOf[Thicket] + override def unapply(x: Any): Option[Thicket] = x match + case tree: tpd.Thicket => Some(tree) + case _ => None + } + + type Type = Types.Type + type AppliedType = Types.AppliedType + type ConstantType = Types.ConstantType + type ClassInfo = Types.ClassInfo + type NamedType = Types.NamedType + type ThisType = Types.ThisType + type SuperType = Types.SuperType + type BoundType = Types.BoundType + type RecThis = Types.RecThis + type ParamRef = Types.ParamRef + type RecType = Types.RecType + type RefinedType = Types.RefinedType + type SkolemType = Types.SkolemType + type TypeBounds = Types.TypeBounds + type TypeAlias = Types.TypeAlias + type TermRef = Types.TermRef + type TypeRef = Types.TypeRef + type AnnotatedType = Types.AnnotatedType + type AndOrType = Types.AndOrType + type AndType = Types.AndType + type OrType = Types.OrType + type TypeProxy = Types.TypeProxy + type ExprType = Types.ExprType + type MatchType = Types.MatchType + type LambdaType = Types.LambdaType + type HKTypeLambda = Types.HKTypeLambda + type PolyType = Types.PolyType + type MethodType = Types.MethodType + type LazyRef = Types.LazyRef + + val Type_CT = classTag[Type] + val AppliedType_CT = classTag[AppliedType] + val ConstantType_CT = classTag[ConstantType] + val NamedType_CT = classTag[NamedType] + val ThisType_CT = classTag[ThisType] + val SuperType_CT = classTag[SuperType] + val RecThis_CT = classTag[RecThis] + val RecType_CT = classTag[RecType] + val TermRef_CT = classTag[TermRef] + val TypeRef_CT = classTag[TypeRef] + val ParamRef_CT = classTag[ParamRef] + val SkolemType_CT = classTag[SkolemType] + val RefinedType_CT = classTag[RefinedType] + val TypeAlias_CT = classTag[TypeAlias] + val TypeBounds_CT = classTag[TypeBounds] + val AnnotatedType_CT = classTag[AnnotatedType] + val AndType_CT = classTag[AndType] + val OrType_CT = classTag[OrType] + val MatchType_CT = classTag[MatchType] + val ExprType_CT = classTag[ExprType] + val HKTypeLambda_CT = classTag[HKTypeLambda] + val PolyType_CT = classTag[PolyType] + val MethodType_CT = classTag[MethodType] + val LazyRef_CT = classTag[LazyRef] + val ClassInfo_CT = classTag[ClassInfo] + + type Symbol = Symbols.Symbol + type TermSymbol = Symbols.TermSymbol + type TypeSymbol = Symbols.TypeSymbol + type ClassSymbol = Symbols.ClassSymbol + + type FlagSet = Flags.FlagSet + type Flag = Flags.Flag + + val Symbol_CT = classTag[Symbol] + val ClassSymbol_CT = classTag[ClassSymbol] + + type Symbols_MutableSymbolMap[T] = Symbols.MutableSymbolMap[T] + + type SourcePosition = util.SourcePosition + type Span = Spans.Span + + type ContextDocstrings = Comments.ContextDocstrings + + type Comment = Comments.Comment + + type Constant = Constants.Constant + + final val Flags_Protected = Flags.Protected + final val Flags_ParamAccessor = Flags.ParamAccessor + final val Flags_Private = Flags.Private + final val Flags_Final = Flags.Final + final val Flags_Case = Flags.Case + final val Flags_Override = Flags.Override + final val Flags_Inline = Flags.Inline + final val Flags_InlineProxy = Flags.InlineProxy + final val Flags_Macro = Flags.Macro + final val Flags_JavaStatic = Flags.JavaStatic + final val Flags_Module = Flags.Module + final val Flags_Enum = Flags.Enum + final val Flags_Local = Flags.Local + final val Flags_Synthetic = Flags.Synthetic + final val Flags_Artifact = Flags.Artifact + final val Flags_Scala2x = Flags.Scala2x + final val Flags_Implicit = Flags.Implicit + final val Flags_Given = Flags.Given + final val Flags_Erased = Flags.Erased + final val Flags_Lazy = Flags.Lazy + final val Flags_AbsOverride = Flags.AbsOverride + final val Flags_Mutable = Flags.Mutable + final val Flags_Accessor = Flags.Accessor + final val Flags_CaseAccessor = Flags.CaseAccessor + final val Flags_DefaultParameterized = Flags.DefaultParameterized + final val Flags_StableRealizable = Flags.StableRealizable + final val Flags_Extension = Flags.Extension + final val Flags_Exported = Flags.Exported + final val Flags_Label = Flags.Label + final val Flags_Sealed = Flags.Sealed + final val Flags_Abstract = Flags.Abstract + final val Flags_Trait = Flags.Trait + final val Flags_Covariant = Flags.Covariant + final val Flags_Contravariant = Flags.Contravariant + final val Flags_Opaque = Flags.Opaque + final val Flags_Open = Flags.Open + + def FlagSet_is(flags: FlagSet, flag: Flag): Boolean = flags.is(flag) + def FlagSet_is(flags: FlagSet, flag: Flag, butNot: FlagSet): Boolean = flags.is(flag, butNot) + def FlagSet_&~(flags: FlagSet, flag: Flag): FlagSet = flags &~ flag + + def Context_log(ctx: Context, msg: => String, sourcePos: SourcePosition): Unit = ctx.log(msg, sourcePos) + def Context_source(ctx: Context): SourceFile = ctx.source + def Context_docCtx(ctx: Context): Option[ContextDocstrings] = { + import Comments._ + ctx.docCtx + } + def Context_withOwner(ctx: Context, owner: Symbol): Context = ctx.withOwner(owner) + def Context_withSource(ctx: Context, source: SourceFile): Context = ctx.withSource(source) + + def ContextDocstrings_docstring(ctx: ContextDocstrings, sym: Symbol): Option[Comment] = ctx.docstring(sym) + + def Constant_tag(c: Constant): Int = c.tag + def Constant_intValue(c: Constant): Int = c.intValue + def Constant_booleanValue(c: Constant): Boolean = c.booleanValue + def Constant_byteValue(c: Constant): Byte = c.byteValue + def Constant_charValue(c: Constant): Char = c.charValue + def Constant_shortValue(c: Constant): Short = c.shortValue + def Constant_longValue(c: Constant): Long = c.longValue + def Constant_doubleValue(c: Constant): Double = c.doubleValue + def Constant_floatValue(c: Constant): Float = c.floatValue + def Constant_stringValue(c: Constant): String = c.stringValue + def Constant_typeValue(c: Constant): Type = c.typeValue + def Constant_symbolValue(c: Constant): Symbol = c.symbolValue + + def Symbols_MutableSymbolMap_get[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): Option[T] = map.get(sym) + def Symbols_MutableSymbolMap_getOrElse[U >: T, T](map: Symbols_MutableSymbolMap[T], sym: Symbol, default: => U): U = map.getOrElse(sym, default) + def Symbols_MutableSymbolMap_contains[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): Boolean = map.contains(sym) + def Symbols_MutableSymbolMap_update[T](map: Symbols_MutableSymbolMap[T], sym: Symbol, value: T): Unit = map.update(sym, value) + def Symbols_MutableSymbolMap_-=[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): Unit = map -= sym + def Symbols_MutableSymbolMap_apply[T](map: Symbols_MutableSymbolMap[T], sym: Symbol): T = map(sym) + def Symbols_MutableSymbolMap_keysIterator[T](map: Symbols_MutableSymbolMap[T]): Iterator[Symbol] = map.keysIterator + def Symbols_MutableSymbolMap_isEmpty[T](map: Symbols_MutableSymbolMap[T]): Boolean = map.isEmpty + def Symbols_newMutableSymbolMap[A]: Symbols_MutableSymbolMap[A] = Symbols.newMutableSymbolMap + + def Symbol_isPackage(sym: Symbol)(given Context): Boolean = sym.is(Flags.Package) + def Symbol_isPrivate(sym: Symbol)(given Context): Boolean = sym.is(Flags.Private) + def Symbol_sourcePos(sym: Symbol)(given Context): SourcePosition = sym.sourcePos + def Symbol_owner(sym: Symbol)(given Context): Symbol = sym.owner + def Symbol_isDefinedWithin(sym: Symbol, outer: Symbol)(given Context): Boolean = sym.topLevelClass.isLinkedWith(outer) + def Symbol_termRef(sym: Symbol)(given Context): TermRef = sym.termRef + def Symbol_typeRef(sym: Symbol)(given Context): TypeRef = sym.typeRef + def Symbol_name(sym: Symbol)(given Context): sym.ThisName = sym.name + def Symbol_fullName(sym: Symbol)(given Context): Name = sym.fullName + def Symbol_isClass(sym: Symbol): Boolean = sym.isClass + def Symbol_exists(sym: Symbol)(given Context): Boolean = sym.exists + def Symbol_isEffectiveRoot(sym: Symbol)(given Context): Boolean = sym.isEffectiveRoot + def Symbol_flags(sym: Symbol)(given Context): FlagSet = sym.flags + def Symbol_privateWithin(sym: Symbol)(given Context): Symbol = sym.privateWithin + def Symbol_isTerm(sym: Symbol)(given Context): Boolean = sym.isTerm + def Symbol_isSetter(sym: Symbol)(given Context): Boolean = sym.isSetter + def Symbol_info(sym: Symbol)(given Context): Type = sym.info + def Symbol_showLocated(sym: Symbol)(given Context): String = sym.showLocated + def Symbol_annotations(sym: Symbol)(given Context): List[Annotation] = sym.annotations + def Symbol_isInaccessibleChildOf(sym: Symbol, cls: Symbol)(given Context): Boolean = { + import transform.SymUtils._ + sym.isInaccessibleChildOf(cls) + } + + def SourceFile_path(source: SourceFile): String = source.path + def SourceFile_exists(source: SourceFile): Boolean = source.exists + val SourceFile_noSource: SourceFile = util.NoSource + + def SourcePosition_line(pos: SourcePosition): Int = pos.line + + val Span_empty: Span = Spans.Span(0,0) + val Span_noSpan: Span = Spans.NoSpan + def Span_start(span: Span): Int = span.start + def Span_end(span: Span): Int = span.end + def Span_isSynthetic(span: Span): Boolean = span.isSynthetic + def Span_toSynthetic(span: Span): Span = span.toSynthetic + def Span_pointDelta(span: Span): Int = span.pointDelta + def Span_coords(span: Span): Long = span.coords + def Span_exists(span: Span): Boolean = span.exists + + private inline def defn(given ctx: Context) = ctx.definitions + + def defn_throwMethod(given ctx: Context): TermSymbol = defn.throwMethod + def defn_BodyAnnot(given Context): ClassSymbol = defn.BodyAnnot + + def Name_toTermName(name: Name): TermName = name.toTermName + def Name_isEmpty(name: Name): Boolean = name.isEmpty + def Name_isTypeName(name: Name): Boolean = name.isTypeName + + def Positioned_alwaysNeedsPos(positioned: Positioned): Boolean = positioned match { + case + // initialSpan is inaccurate for trees with lazy field + _: Trees.WithLazyField[?] + + // A symbol is created before the corresponding tree is unpickled, + // and its position cannot be changed afterwards. + // so we cannot use the tree initialSpan to set the symbol position. + // Instead, we always pickle the position of definitions. + | _: Trees.DefTree[?] + + // package defs might be split into several Tasty files + | _: Trees.PackageDef[?] + // holes can change source files when filled, which means + // they might lose their position + | _: TreePickler.Hole => true + case _ => false + } + + def untpd_Tree_span(tree: untpd_Tree): Span = tree.span + def untpd_Tree_source(tree: untpd_Tree): SourceFile = tree.source + def untpd_Tree_envelope(tree: untpd_Tree, src: SourceFile, startSpan: Span): Span = tree.envelope(src, startSpan) + def untpd_Tree_symbol(tree: untpd_Tree)(given Context): Symbol = tree.symbol + def untpd_Tree_withType(tree: untpd_Tree, tpe: Type)(given Context): tree.ThisTree[Type] = tree.withType(tpe) + def untpd_Tree_isEmpty(tree: untpd_Tree): Boolean = tree.isEmpty + + def Tree_isType(tree: Tree): Boolean = tree.isType + def Tree_tpe(tree: Tree): Type = tree.tpe + val EmptyTree: Tree = tpd.EmptyTree + + def If_isInline(tree: If): Boolean = tree.isInline + def Match_isInline(tree: Match): Boolean = tree.isInline + + def inlineContext(tree: Tree)(implicit ctx: Context): Context = tpd.inlineContext(tree) + + def untpd_TypedSplice_unapply(tree: untpd_TypedSplice): Some[Tree] = Some(tree.splice) + def untpd_Ident_unapply(tree: untpd_Ident): Some[Name] = Some(tree.name) + def Ident_unapply(tree: Ident): Some[Name] = Some(tree.name) + def This_unapply(tree: This): Some[untpd_Ident] = Some(tree.qual) + def Select_unapply(tree: Select): (Tree, Name) = (tree.qualifier, tree.name) + def Apply_unapply(tree: Apply): (Tree, List[Tree]) = (tree.fun, tree.args) + def TypeApply_unapply(tree: TypeApply): (Tree, List[Tree]) = (tree.fun, tree.args) + def Literal_unapply(tree: Literal): Some[Constant] = Some(tree.const) + def Super_unapply(tree: Super): (Tree, untpd_Ident) = (tree.qual, tree.mix) + def New_unapply(tree: New): Some[Tree] = Some(tree.tpt) + def Typed_unapply(tree: Typed): (Tree, Tree) = (tree.expr, tree.tpt) + def NamedArg_unapply(tree: NamedArg): (Name, Tree) = (tree.name, tree.arg) + def Assign_unapply(tree: Assign): (Tree, Tree) = (tree.lhs, tree.rhs) + def Block_unapply(tree: Block): (List[Tree], Tree) = (tree.stats, tree.expr) + def If_unapply(tree: If): (Tree, Tree, Tree) = (tree.cond, tree.thenp, tree.elsep) + def Closure_unapply(tree: Closure): (List[Tree], Tree, Tree) = (tree.env, tree.meth, tree.tpt) + def Match_unapply(tree: Match): (Tree, List[CaseDef]) = (tree.selector, tree.cases) + def CaseDef_unapply(tree: CaseDef): (Tree, Tree, Tree) = (tree.pat, tree.guard, tree.body) + def Labeled_unapply(tree: Labeled): (Bind, Tree) = (tree.bind, tree.expr) + def Return_unapply(tree: Return): (Tree, Tree) = (tree.expr, tree.from) + def WhileDo_unapply(tree: WhileDo): (Tree, Tree) = (tree.cond, tree.body) + def Try_unapply(tree: Try): (Tree, List[CaseDef], Tree) = (tree.expr, tree.cases, tree.finalizer) + def SeqLiteral_unapply(tree: SeqLiteral): (List[Tree], Tree) = (tree.elems, tree.elemtpt) + def Inlined_unapply(tree: Inlined): (Tree, List[MemberDef], Tree) = (tree.call, tree.bindings, tree.expansion) + def Bind_unapply(tree: Bind): (Name, Tree) = (tree.name, tree.body) + def Alternative_unapply(tree: Alternative): Some[List[Tree]] = Some(tree.trees) + def UnApply_unapply(tree: UnApply): (Tree, List[Tree], List[Tree]) = (tree.fun, tree.implicits, tree.patterns) + def Import_unapply(tree: Import): (Tree, List[untpd_ImportSelector]) = (tree.expr, tree.selectors) + def PackageDef_unapply(tree: PackageDef): (RefTree, List[Tree]) = (tree.pid, tree.stats) + def SingletonTypeTree_unapply(tree: SingletonTypeTree): Some[Tree] = Some(tree.ref) + def RefinedTypeTree_unapply(tree: RefinedTypeTree): (Tree, List[Tree]) = (tree.tpt, tree.refinements) + def AppliedTypeTree_unapply(tree: AppliedTypeTree): (Tree, List[Tree]) = (tree.tpt, tree.args) + def MatchTypeTree_unapply(tree: MatchTypeTree): (Tree, Tree, List[CaseDef]) = (tree.bound, tree.selector, tree.cases) + def ByNameTypeTree_unapply(tree: ByNameTypeTree): Some[Tree] = Some(tree.result) + def Annotated_unapply(tree: Annotated): (Tree, Tree) = (tree.arg, tree.annot) + def LambdaTypeTree_unapply(tree: LambdaTypeTree): (List[TypeDef], Tree) = (tree.tparams, tree.body) + def TypeBoundsTree_unapply(tree: TypeBoundsTree): (Tree, Tree) = (tree.lo, tree.hi) + def Hole_unapply(tree: Hole): (Int, List[Tree]) = (tree.idx, tree.args) + def Thicket_unapply(tree: Thicket): Some[List[Tree]] = Some(tree.trees) + + def ValOrDefDef_name(tree: ValOrDefDef): TermName = tree.name + def ValOrDefDef_tpt(tree: ValOrDefDef): Tree = tree.tpt + def ValOrDefDef_rhs(tree: ValOrDefDef)(given Context): Tree = tree.rhs + def DefDef_tparams(tree: DefDef): List[TypeDef] = tree.tparams + def DefDef_vparamss(tree: DefDef): List[List[ValDef]] = tree.vparamss + def TypeDef_rhs(tree: TypeDef): Tree = tree.rhs + + def ImportSelector_imported(tree: untpd_ImportSelector): untpd.Ident = tree.imported + def ImportSelector_renamed(tree: untpd_ImportSelector): untpd.Tree = tree.renamed + def ImportSelector_bound(tree: untpd_ImportSelector): untpd_Tree = tree.bound + + def Template_decomposeBody(tree: Template)(given Context): (List[Tree], List[Tree]) = + tpd.decomposeTemplateBody(tree.body) + def Template_parents(tree: Template): List[Tree] = tree.parents + def Template_self(tree: Template): ValDef = tree.self + def Template_body(tree: Template)(given Context): List[Tree] = tree.body + def Template_derived(tree: Template): List[untpd_Tree] = tree.derived + def Template_constr(tree: Template): DefDef = tree.constr + + def Type_stripTypeVar(tpe: Type)(given Context): Type = tpe.stripTypeVar + def Type_member(tpe: Type, name: Name)(given Context): Symbol = tpe.member(name).symbol + def Type_signature(tpe: Type)(given Context): Signature = tpe.signature + def Type_isContextualMethod(tpe: Type): Boolean = tpe.isContextualMethod + def Type_isImplicitMethod(tpe: Type): Boolean = tpe.isImplicitMethod + def Type_isErasedMethod(tpe: Type): Boolean = tpe.isErasedMethod + def Type_exists(tpe: Type): Boolean = tpe.exists + + def AppliedType_unapply(tpe: AppliedType): (Type, List[Type]) = (tpe.tycon, tpe.args) + + def ConstantType_value(tpe: ConstantType): Constant = tpe.value + + def ThisType_cls(tpe: ThisType)(given Context): ClassSymbol = tpe.cls + def ThisType_tref(tpe: ThisType): TypeRef = tpe.tref + + def SuperType_thistpe(tpe: SuperType): Type = tpe.thistpe + def SuperType_supertpe(tpe: SuperType): Type = tpe.supertpe + + def BoundType_binder(tpe: BoundType): tpe.BT = tpe.binder + + def ParamRef_paramNum(tpe: ParamRef): Int = tpe.paramNum + + def RecType_parent(tpe: RecType): Type = tpe.parent + + def RefinedType_parent(tpe: RefinedType): Type = tpe.parent + def RefinedType_refinedName(tpe: RefinedType): Name = tpe.refinedName + def RefinedType_refinedInfo(tpe: RefinedType): Type = tpe.refinedInfo + + def SkolemType_info(tpe: SkolemType): Type = tpe.info + + def NamedType_symbol(tpe: NamedType)(given Context): Symbol = tpe.symbol + def NamedType_prefix(tpe: NamedType): Type = tpe.prefix + def NamedType_designator(tpe: NamedType): Designator = tpe.designator + def NamedType_hasNoPrefix(tpe: NamedType): Boolean = tpe.prefix `eq` Types.NoPrefix + def NamedType_isType(tpe: NamedType): Boolean = tpe.isType + + def TypeAlias_alias(tpe: TypeAlias): Type = tpe.alias + + def TypeBounds_hi(tpe: TypeBounds): Type = tpe.hi + def TypeBounds_lo(tpe: TypeBounds): Type = tpe.lo + + def AnnotatedType_parent(tpe: AnnotatedType): Type = tpe.parent + def AnnotatedType_annot(tpe: AnnotatedType): Annotation = tpe.annot + + def Annotation_tree(annot: Annotation)(given Context): Tree = annot.tree + def Annotation_symbol(annot: Annotation)(given Context): Symbol = annot.symbol + def Annotation_Child_unapply(annot: Annotation)(given Context): Option[Symbol] = + Annotations.Annotation.Child.unapply(annot) + + def AndOrType_tp1(tpe: AndOrType): Type = tpe.tp1 + def AndOrType_tp2(tpe: AndOrType): Type = tpe.tp2 + + def TypeProxy_underlying(tpe: TypeProxy)(given Context): Type = tpe.underlying + + def LambdaType_resultType(tpe: LambdaType)(given Context): Type = tpe.resultType + def LambdaType_paramNames(tpe: LambdaType): List[tpe.ThisName] = tpe.paramNames + def LambdaType_paramInfos(tpe: LambdaType): List[tpe.PInfo] = tpe.paramInfos + + def MatchType_bound(tpe: MatchType): Type = tpe.bound + def MatchType_scrutinee(tpe: MatchType): Type = tpe.scrutinee + def MatchType_cases(tpe: MatchType): List[Type] = tpe.cases + + def ClassInfo_selfInfo(tpe: ClassInfo): Either[Type, Symbol] = tpe.selfInfo match { + case tp: Type => Left(tp) + case sym: Symbol => Right(sym) + } + + def LazyRef_ref(tpe: LazyRef)(given Context): Type = tpe.ref + + def TermName_tag(name: TermName): Int = name.info.kind.tag + + def SimpleName_toUTF8(name: SimpleName): Array[Byte] = io.Codec.toUTF8(Names.chrs, name.start, name.length) + + def String_toTermName(name: String): TermName = { + import Decorators._ + name.toTermName + } + + def SignedName_unapply(name: DerivedName): Option[(TermName, Signature)] = NameKinds.SignedName.unapply(name) + def SignedName_apply(name: TermName, sig: Signature): TermName = NameKinds.SignedName.apply(name, sig) + + def AnyQualifiedName_unapply(name: DerivedName): Option[(TermName, SimpleName)] = NameKinds.AnyQualifiedName.unapply(name) + def AnyUniqueName_unapply(name: DerivedName): Option[(TermName, String, Int)] = NameKinds.AnyUniqueName.unapply(name) + def AnyNumberedName_unapply(name: DerivedName): Option[(TermName, Int)] = NameKinds.AnyNumberedName.unapply(name) + def OuterSelectName_unapply(name: DerivedName): Option[(TermName, Int)] = NameKinds.OuterSelectName.unapply(name) + def DerivedName_unapply(name: DerivedName): Some[TermName] = Some(name.underlying) + + val nme_WILDCARD: TermName = StdNames.nme.WILDCARD + + def Signature_ParamSig_fold[A](paramSig: Signature_ParamSig)(onInt: Int => A, onTypeName: TypeName => A): A = + paramSig match { + case i: Int => onInt(i) + case n: TypeName => onTypeName(n) + } + + def Signature_ParamSig_foldInt(paramSig: Signature_ParamSig)(onInt: IntToInt, onTypeName: ToInt[TypeName]): Int = + paramSig match { + case i: Int => onInt(i) + case n: TypeName => onTypeName(n) + } + + def Signature_isNotAMethod(sig: Signature): Boolean = sig `eq` core.Signature.NotAMethod + + def Signature_unapply(signature: Signature): (List[Signature_ParamSig], TypeName) = + (signature.paramsSig, signature.resSig) + + def pickling_println(msg: => String): Unit = Printers.pickling.println(msg) + + def StringContext_i(stringContext: StringContext, args: Any*)(given Context): String = { + import Decorators._ + stringContext.i(args) + } + + def Comment_raw(comment: Comment): String = comment.raw + def Comment_span(comment: Comment): Span = comment.span + +} diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index 1306ef80ab5e..c87e9911d97d 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -48,74 +48,75 @@ class Pickler extends Phase { } override def run(implicit ctx: Context): Unit = { - val unit = ctx.compilationUnit - pickling.println(i"unpickling in run ${ctx.runId}") - - for { - cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree)) - tree <- sliceTopLevel(unit.tpdTree, cls) - } - { - val pickler = new TastyPickler(cls) - if (ctx.settings.YtestPickler.value) { - beforePickling(cls) = tree.show - picklers(cls) = pickler - } - val treePkl = pickler.treePkl - treePkl.pickle(tree :: Nil) - treePkl.compactify() - pickler.addrOfTree = treePkl.buf.addrOfTree - pickler.addrOfSym = treePkl.addrOfSym - if (tree.span.exists) - new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) - - if (!ctx.settings.YdropComments.value) - new CommentPickler(pickler, treePkl.buf.addrOfTree).pickleComment(tree) - - // other pickle sections go here. - val pickled = pickler.assembleParts() - unit.pickled += (cls -> pickled) - - def rawBytes = // not needed right now, but useful to print raw format. - pickled.iterator.grouped(10).toList.zipWithIndex.map { - case (row, i) => s"${i}0: ${row.mkString(" ")}" - } - - // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG - if (pickling ne noPrinter) { - println(i"**** pickled info of $cls") - println(new TastyPrinter(pickled).printContents()) - } - } + // val unit = ctx.compilationUnit + // pickling.println(i"unpickling in run ${ctx.runId}") + + // for { + // cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree)) + // tree <- sliceTopLevel(unit.tpdTree, cls) + // } + // { + // val pickler = new TastyPickler(cls) + // if (ctx.settings.YtestPickler.value) { + // beforePickling(cls) = tree.show + // picklers(cls) = pickler + // } + // val treePkl = pickler.treePkl + // treePkl.pickle(tree :: Nil) + // treePkl.compactify() + // pickler.addrOfTree = treePkl.buf.addrOfTree + // pickler.addrOfSym = treePkl.addrOfSym + // if (tree.span.exists) + // new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) + + // if (!ctx.settings.YdropComments.value) + // new CommentPickler(pickler, treePkl.buf.addrOfTree).pickleComment(tree) + + // // other pickle sections go here. + // val pickled = pickler.assembleParts() + // unit.pickled += (cls -> pickled) + + // def rawBytes = // not needed right now, but useful to print raw format. + // pickled.iterator.grouped(10).toList.zipWithIndex.map { + // case (row, i) => s"${i}0: ${row.mkString(" ")}" + // } + + // // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG + // if (pickling ne noPrinter) { + // println(i"**** pickled info of $cls") + // println(new TastyPrinter(pickled).printContents()) + // } + // } } override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { - val result = super.runOn(units) - if (ctx.settings.YtestPickler.value) - testUnpickler( - ctx.fresh - .setPeriod(Period(ctx.runId + 1, FirstPhaseId)) - .setReporter(new ThrowingReporter(ctx.reporter)) - .addMode(Mode.ReadPositions) - .addMode(Mode.ReadComments) - .addMode(Mode.PrintShowExceptions)) - result + // val result = super.runOn(units) + // if (ctx.settings.YtestPickler.value) + // testUnpickler( + // ctx.fresh + // .setPeriod(Period(ctx.runId + 1, FirstPhaseId)) + // .setReporter(new ThrowingReporter(ctx.reporter)) + // .addMode(Mode.ReadPositions) + // .addMode(Mode.ReadComments) + // .addMode(Mode.PrintShowExceptions)) + // result + Nil } private def testUnpickler(implicit ctx: Context): Unit = { - pickling.println(i"testing unpickler at run ${ctx.runId}") - ctx.initialize() - val unpicklers = - for ((cls, pickler) <- picklers) yield { - val unpickler = new DottyUnpickler(pickler.assembleParts()) - unpickler.enter(roots = Set.empty) - cls -> unpickler - } - pickling.println("************* entered toplevel ***********") - for ((cls, unpickler) <- unpicklers) { - val unpickled = unpickler.rootTrees - testSame(i"$unpickled%\n%", beforePickling(cls), cls) - } + // pickling.println(i"testing unpickler at run ${ctx.runId}") + // ctx.initialize() + // val unpicklers = + // for ((cls, pickler) <- picklers) yield { + // val unpickler = new DottyUnpickler(pickler.assembleParts()) + // unpickler.enter(roots = Set.empty) + // cls -> unpickler + // } + // pickling.println("************* entered toplevel ***********") + // for ((cls, unpickler) <- unpicklers) { + // val unpickled = unpickler.rootTrees + // testSame(i"$unpickled%\n%", beforePickling(cls), cls) + // } } private def testSame(unpickled: String, previous: String, cls: ClassSymbol)(implicit ctx: Context) = diff --git a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala index 0b2491d86e04..bd385f525bb0 100644 --- a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala @@ -40,25 +40,6 @@ class PositionPickler(val pickler: TastyPickler)(addrOfTree: pickler.tasty.untpd buf.writeInt(pickler.nameBuffer.nameIndex(source.path.toTermName).index) } - // def alwaysNeedsPos(x: Positioned) = x match { - // case - // // initialSpan is inaccurate for trees with lazy field - // _: WithLazyField[?] - - // // A symbol is created before the corresponding tree is unpickled, - // // and its position cannot be changed afterwards. - // // so we cannot use the tree initialSpan to set the symbol position. - // // Instead, we always pickle the position of definitions. - // | _: Trees.DefTree[?] - - // // package defs might be split into several Tasty files - // | _: Trees.PackageDef[?] - // // holes can change source files when filled, which means - // // they might lose their position - // | _: TreePickler.Hole => true - // case _ => false - // } - def traverse(x: Any, current: SourceFile): Unit = x match { case x: untpd.Tree => if (x.span.exists) { diff --git a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala index 159afa72c82b..5e89bb76f8c3 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala @@ -599,7 +599,7 @@ class TreePickler(val pickler: TastyPickler) { for sel <- selectors do pickleSelector(IMPORTED, sel.imported) sel.renamed match - case to @ Ident(_) => pickleSelector(RENAMED, to) + case to: untpd.Ident => pickleSelector(RENAMED, to) case _ => sel.bound match { case bound @ untpd.TypedSplice(tpt) => @@ -609,10 +609,10 @@ class TreePickler(val pickler: TastyPickler) { case _ => } - def pickleSelector(tag: Int, id: Ident)(implicit ctx: Context): Unit = { + def pickleSelector(tag: Int, id: untpd.Ident)(implicit ctx: Context): Unit = { registerTreeAddr(id) writeByte(tag) - val Ident(name) = id + val untpd.Ident(name) = id pickleName(name) } diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala index 499b4e4bf948..847cda248f4f 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala @@ -13,4 +13,4 @@ trait ContextOps extends Core with def withSource(source: SourceFile): Context = internal.Context_withSource(ctx, source) given ContextDocstringsOps: (ctx: ContextDocstrings) with - def docstring(sym: Symbol): Option[Comment] = internal.ContextDocstrings_docString(ctx, sym) + def docstring(sym: Symbol): Option[Comment] = internal.ContextDocstrings_docstring(ctx, sym) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala index 98ac0b610d29..c9cd38e41cdb 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala @@ -40,7 +40,6 @@ trait NameOps extends Core with def isEmpty: Boolean = internal.Name_isEmpty(name) def isTypeName: Boolean = internal.Name_isTypeName(name) def isTermName: Boolean = !name.isTypeName - def length: Int = internal.Name_length(name) given TermNameOps: (name: TermName) with def tag: Int = internal.TermName_tag(name) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala index 4189bf77f4e0..4292cf8d03de 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala @@ -8,4 +8,4 @@ trait StringOps extends Core with def toTermName: TermName = internal.String_toTermName(string) given StringContextOps: (stringContext: StringContext) with - def i(args: => Any*): String = internal.StringContext_i(stringContext, args) + def i(args: => Any*)(given Context): String = internal.StringContext_i(stringContext, args) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala index 7e7b22e70822..00d0d5bc7056 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala @@ -34,12 +34,12 @@ trait SymbolOps extends Core with def isPackage(given Context): Boolean = internal.Symbol_isPackage(sym) def isPrivate(given Context): Boolean = internal.Symbol_isPrivate(sym) def sourcePos(given Context): SourcePosition = internal.Symbol_sourcePos(sym) - def owner: Symbol = internal.Symbol_owner(sym) + def owner(given Context): Symbol = internal.Symbol_owner(sym) def isDefinedWithin(outer: Symbol)(given Context): Boolean = internal.Symbol_isDefinedWithin(sym, outer) def termRef(given Context): TermRef = internal.Symbol_termRef(sym) def typeRef(given Context): TypeRef = internal.Symbol_typeRef(sym) def name(given Context): sym.ThisName = internal.Symbol_name(sym) - def fullName(given Context): sym.ThisName = internal.Symbol_fullName(sym) + def fullName(given Context): Name = internal.Symbol_fullName(sym) def isClass: Boolean = internal.Symbol_isClass(sym) def isEffectiveRoot(given Context): Boolean = internal.Symbol_isEffectiveRoot(sym) def flags(given Context): FlagSet = internal.Symbol_flags(sym) @@ -48,7 +48,7 @@ trait SymbolOps extends Core with def isSetter(given Context): Boolean = internal.Symbol_isSetter(sym) def info(given Context): Type = internal.Symbol_info(sym) def isInaccessibleChildOf(cls: Symbol)(given Context): Boolean = internal.Symbol_isInaccessibleChildOf(sym, cls) - def exists: Boolean = internal.Symbol_exists(sym) + def exists(given Context): Boolean = internal.Symbol_exists(sym) def showLocated(given Context): String = internal.Symbol_showLocated(sym) def annotations(given Context): List[Annotation] = internal.Symbol_annotations(sym) def asClass: ClassSymbol = sym.asInstanceOf[ClassSymbol] diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala index e41ad2a4256d..66415fb2d8a3 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala @@ -41,8 +41,9 @@ trait TastyKernel with type untpd_ImportSelector <: untpd_Tree type untpd_TypedSplice <: untpd_Tree type untpd_MemberDef <: untpd_Tree + type untpd_Ident <: untpd_Tree - type Tree <: untpd_Tree { type ThisTree <: Tree } + type Tree <: untpd_Tree type MemberDef <: Tree type Hole <: Tree type Template <: Tree // DefTree @@ -92,6 +93,7 @@ trait TastyKernel with val untpd_Tree_CT: ClassTag[untpd_Tree] val untpd_TypedSplice_CT: ClassTag[untpd_TypedSplice] val untpd_MemberDef_CT: ClassTag[untpd_MemberDef] + val untpd_Ident_CT: ClassTag[untpd_Ident] val Tree_CT: ClassTag[Tree] val MemberDef_CT: ClassTag[MemberDef] @@ -200,13 +202,13 @@ trait TastyKernel with type TypeSymbol <: Symbol { type ThisName = TypeName } type ClassSymbol <: TypeSymbol - type FlagSet <: AnyVal + type FlagSet type Flag <: FlagSet val Symbol_CT: ClassTag[Symbol] val ClassSymbol_CT: ClassTag[ClassSymbol] - type Symbols_MutableSymbolMap[T] <: AnyRef + type Symbols_MutableSymbolMap[T] type SourcePosition <: AnyRef type Span <: AnyVal @@ -215,7 +217,7 @@ trait TastyKernel with type Comment <: AnyRef - type Constant <: AnyVal + type Constant <: AnyRef val Flags_Protected: Flag val Flags_ParamAccessor: Flag @@ -279,7 +281,7 @@ trait TastyKernel with def Context_withOwner(ctx: Context, owner: Symbol): Context def Context_withSource(ctx: Context, source: SourceFile): Context - def ContextDocstrings_docString(ctx: ContextDocstrings, sym: Symbol): Option[Comment] + def ContextDocstrings_docstring(ctx: ContextDocstrings, sym: Symbol): Option[Comment] def Constant_tag(c: Constant): Int def Constant_intValue(c: Constant): Int @@ -307,14 +309,14 @@ trait TastyKernel with def Symbol_isPackage(sym: Symbol)(given Context): Boolean def Symbol_isPrivate(sym: Symbol)(given Context): Boolean def Symbol_sourcePos(sym: Symbol)(given Context): SourcePosition - def Symbol_owner(sym: Symbol): Symbol + def Symbol_owner(sym: Symbol)(given Context): Symbol def Symbol_isDefinedWithin(sym: Symbol, outer: Symbol)(given Context): Boolean def Symbol_termRef(sym: Symbol)(given Context): TermRef def Symbol_typeRef(sym: Symbol)(given Context): TypeRef def Symbol_name(sym: Symbol)(given Context): sym.ThisName - def Symbol_fullName(sym: Symbol)(given Context): sym.ThisName + def Symbol_fullName(sym: Symbol)(given Context): Name def Symbol_isClass(sym: Symbol): Boolean - def Symbol_exists(sym: Symbol): Boolean + def Symbol_exists(sym: Symbol)(given Context): Boolean def Symbol_isEffectiveRoot(sym: Symbol)(given Context): Boolean def Symbol_flags(sym: Symbol)(given Context): FlagSet def Symbol_privateWithin(sym: Symbol)(given Context): Symbol @@ -347,7 +349,6 @@ trait TastyKernel with def Name_toTermName(name: Name): TermName def Name_isEmpty(name: Name): Boolean def Name_isTypeName(name: Name): Boolean - def Name_length(name: Name): Int def Positioned_alwaysNeedsPos(positioned: Positioned): Boolean @@ -355,24 +356,28 @@ trait TastyKernel with def untpd_Tree_source(tree: untpd_Tree): SourceFile def untpd_Tree_envelope(tree: untpd_Tree, src: SourceFile, startSpan: Span): Span def untpd_Tree_symbol(tree: untpd_Tree)(given Context): Symbol + def untpd_Tree_withType(tree: untpd_Tree, tpe: Type)(given Context): Tree + def untpd_Tree_isEmpty(tree: untpd_Tree): Boolean - def Tree_withType(tree: Tree, tpe: Type)(given Context): tree.ThisTree - def Tree_isEmpty(tree: Tree): Boolean def Tree_isType(tree: Tree): Boolean - def Tree_isInline(tree: Tree): Boolean def Tree_tpe(tree: Tree): Type val EmptyTree: Tree + def If_isInline(tree: If): Boolean + def Match_isInline(tree: Match): Boolean + def inlineContext(tree: Tree)(implicit ctx: Context): Context - def TypedSplice_unapply(tree: untpd_TypedSplice): Some[Tree] + def untpd_TypedSplice_unapply(tree: untpd_TypedSplice): Some[Tree] + def untpd_Ident_unapply(tree: untpd_Ident): Some[Name] + def Ident_unapply(tree: Ident): Some[Name] - def This_unapply(tree: This): Some[Ident] + def This_unapply(tree: This): Some[untpd_Ident] def Select_unapply(tree: Select): (Tree, Name) def Apply_unapply(tree: Apply): (Tree, List[Tree]) def TypeApply_unapply(tree: TypeApply): (Tree, List[Tree]) def Literal_unapply(tree: Literal): Some[Constant] - def Super_unapply(tree: Super): (Tree, Ident) + def Super_unapply(tree: Super): (Tree, untpd_Ident) def New_unapply(tree: New): Some[Tree] def Typed_unapply(tree: Typed): (Tree, Tree) def NamedArg_unapply(tree: NamedArg): (Name, Tree) @@ -411,14 +416,14 @@ trait TastyKernel with def DefDef_vparamss(tree: DefDef): List[List[ValDef]] def TypeDef_rhs(tree: TypeDef): Tree - def ImportSelector_imported(tree: untpd_ImportSelector): Ident - def ImportSelector_renamed(tree: untpd_ImportSelector): Tree + def ImportSelector_imported(tree: untpd_ImportSelector): untpd_Ident + def ImportSelector_renamed(tree: untpd_ImportSelector): untpd_Tree def ImportSelector_bound(tree: untpd_ImportSelector): untpd_Tree def Template_decomposeBody(tree: Template)(given Context): (List[Tree], List[Tree]) def Template_parents(tree: Template): List[Tree] def Template_self(tree: Template): ValDef - def Template_body(tree: Template): List[Tree] + def Template_body(tree: Template)(given Context): List[Tree] def Template_derived(tree: Template): List[untpd_Tree] def Template_constr(tree: Template): DefDef @@ -455,7 +460,7 @@ trait TastyKernel with def NamedType_symbol(tpe: NamedType)(given Context): Symbol def NamedType_prefix(tpe: NamedType): Type def NamedType_designator(tpe: NamedType): Designator - def NamedType_hasNoPrefix(tpe: Type): Boolean + def NamedType_hasNoPrefix(tpe: NamedType): Boolean def NamedType_isType(tpe: NamedType): Boolean def TypeAlias_alias(tpe: TypeAlias): Type @@ -512,7 +517,7 @@ trait TastyKernel with def pickling_println(msg: => String): Unit - def StringContext_i(stringContext: StringContext, args: Any*): String + def StringContext_i(stringContext: StringContext, args: Any*)(given Context): String def Comment_raw(comment: Comment): String def Comment_span(comment: Comment): Span diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala index ef4ba052e65b..1ca1a11f9ee4 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala @@ -54,6 +54,7 @@ trait TreeOps extends Core with given untpdTree: ClassTag[untpd.Tree] = internal.untpd_Tree_CT given untpdTypedSplice: ClassTag[untpd.TypedSplice] = internal.untpd_TypedSplice_CT given untpdMemberDef: ClassTag[untpd.MemberDef] = internal.untpd_MemberDef_CT + given untpdIdent: ClassTag[untpd.Ident] = internal.untpd_Ident_CT object untpd with @@ -61,13 +62,17 @@ trait TreeOps extends Core with type TypedSplice = internal.untpd_TypedSplice type ImportSelector = internal.untpd_ImportSelector type MemberDef = internal.untpd_MemberDef + type Ident = internal.untpd_Ident object TypedSplice with - def unapply(tree: TypedSplice): Some[self.Tree] = internal.TypedSplice_unapply(tree) + def unapply(tree: TypedSplice): Some[self.Tree] = internal.untpd_TypedSplice_unapply(tree) + + object Ident with + def unapply(tree: Ident): Some[Name] = internal.untpd_Ident_unapply(tree) given ImportSelectorOps: (tree: ImportSelector) with def imported: Ident = internal.ImportSelector_imported(tree) - def renamed: self.Tree = internal.ImportSelector_renamed(tree) + def renamed: Tree = internal.ImportSelector_renamed(tree) def bound: Tree = internal.ImportSelector_bound(tree) end untpd @@ -75,7 +80,7 @@ trait TreeOps extends Core with object Ident with def unapply(tree: Ident): Some[Name] = internal.Ident_unapply(tree) object This with - def unapply(tree: This): Some[Ident] = internal.This_unapply(tree) + def unapply(tree: This): Some[untpd.Ident] = internal.This_unapply(tree) object Select with def unapply(tree: Select): (Tree, Name) = internal.Select_unapply(tree) object Apply with @@ -85,7 +90,7 @@ trait TreeOps extends Core with object Literal with def unapply(tree: Literal): Some[Constant] = internal.Literal_unapply(tree) object Super with - def unapply(tree: Super): (Tree, Ident) = internal.Super_unapply(tree) + def unapply(tree: Super): (Tree, untpd.Ident) = internal.Super_unapply(tree) object New with def unapply(tree: New): Some[Tree] = internal.New_unapply(tree) object Typed with @@ -152,14 +157,19 @@ trait TreeOps extends Core with def span: Span = internal.untpd_Tree_span(tree) def source: SourceFile = internal.untpd_Tree_source(tree) def envelope(src: SourceFile, startSpan: Span = Span.noSpan): Span = internal.untpd_Tree_envelope(tree, src, startSpan) + def withType(tpe: Type)(given Context): Tree = internal.untpd_Tree_withType(tree, tpe) + def isEmpty: Boolean = internal.untpd_Tree_isEmpty(tree) given TreeOps: (tree: Tree) with - def isEmpty: Boolean = internal.Tree_isEmpty(tree) def isType: Boolean = internal.Tree_isType(tree) - def withType(tpe: Type)(given Context): tree.ThisTree = internal.Tree_withType(tree, tpe) - def isInline: Boolean = internal.Tree_isInline(tree) def tpe: Type = internal.Tree_tpe(tree) + given IfOps: (tree: If) with + def isInline: Boolean = internal.If_isInline(tree) + + given MatchOps: (tree: Match) with + def isInline: Boolean = internal.Match_isInline(tree) + given ValOrDefDefOps: (tree: ValOrDefDef) with def name: TermName = internal.ValOrDefDef_name(tree) def tpt: Tree = internal.ValOrDefDef_tpt(tree) @@ -177,7 +187,7 @@ trait TreeOps extends Core with def parents: List[Tree] = internal.Template_parents(tree) def self: ValDef = internal.Template_self(tree) def constr: DefDef = internal.Template_constr(tree) - def body: List[Tree] = internal.Template_body(tree) + def body(given Context): List[Tree] = internal.Template_body(tree) def derived: List[untpd.Tree] = internal.Template_derived(tree) final val EmptyTree = internal.EmptyTree From 6c10d4e3666286904df4d00b4d8dd7867a69e1aa Mon Sep 17 00:00:00 2001 From: bishabosha Date: Sun, 1 Dec 2019 01:22:04 +0100 Subject: [PATCH 4/8] run the compiler --- .../dotc/core/quoted/PickledQuotes.scala | 32 +-- .../core/tasty/experimental/DottyKernel.scala | 16 +- .../core/tasty/experimental/DottyTasty.scala | 6 + .../dotty/tools/dotc/transform/Pickler.scala | 137 +++++----- .../tasty/experimental/CommentPickler.scala | 4 +- .../tools/tasty/experimental/NameBuffer.scala | 2 +- .../tasty/experimental/PositionPickler.scala | 4 +- .../tasty/experimental/TastyPickler.scala | 6 +- .../tools/tasty/experimental/TreeBuffer.scala | 4 +- .../tasty/experimental/TreePickler.scala | 8 +- .../experimental/bridge/ConstantOps.scala | 2 + .../tasty/experimental/bridge/FlagOps.scala | 13 - .../experimental/bridge/TastyKernel.scala | 250 +++++++++--------- .../tasty/experimental/bridge/TreeOps.scala | 2 +- 14 files changed, 247 insertions(+), 239 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyTasty.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index e559504ecfda..661d7a94955e 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -13,6 +13,7 @@ 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.TastyPrinter +import dotty.tools.dotc.core.tasty.experimental.DottyTasty import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode import dotty.tools.dotc.quoted.QuoteContext import dotty.tools.dotc.tastyreflect.{ReflectionImpl, TastyTreeExpr, TreeType} @@ -99,25 +100,26 @@ object PickledQuotes { /** Pickle tree into it's TASTY bytes s*/ private def pickle(tree: Tree)(implicit ctx: Context): Array[Byte] = { - // val pickler = new TastyPickler(defn.RootClass) - // val treePkl = pickler.treePkl - // treePkl.pickle(tree :: Nil) - // treePkl.compactify() - // pickler.addrOfTree = treePkl.buf.addrOfTree - // pickler.addrOfSym = treePkl.addrOfSym - // if (tree.span.exists) - // new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) + val pickler = new TastyPickler(DottyTasty)(defn.RootClass) + val treePkl = pickler.treePkl + treePkl.pickle(tree :: Nil) + treePkl.compactify() + pickler.addrOfTree = treePkl.buf.addrOfTree + pickler.addrOfSym = treePkl.addrOfSym + if (tree.span.exists) { + val pospkl = new PositionPickler(DottyTasty)(pickler, treePkl.buf.addrOfTree) + pospkl.picklePositions(tree :: Nil) + } - // if (quotePickling ne noPrinter) - // println(i"**** pickling quote of \n${tree.show}") + if (quotePickling ne noPrinter) + println(i"**** pickling quote of \n${tree.show}") - // val pickled = pickler.assembleParts() + val pickled = pickler.assembleParts() - // if (quotePickling ne noPrinter) - // println(new TastyPrinter(pickled).printContents()) + if (quotePickling ne noPrinter) + println(new TastyPrinter(pickled).printContents()) - // pickled - Array.empty + pickled } /** Unpickle TASTY bytes into it's tree */ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala index fd297eec1ce4..6b0bd34d705a 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala @@ -13,6 +13,8 @@ import core.Contexts, core.Names, core.Annotations, core.Types, core.Symbols, co core.Comments, core.Constants, ast.Trees, core.Decorators, core.NameKinds, core.StdNames import ast.{tpd, untpd} +import annotation.internal.sharable + object DottyKernel extends TastyKernel { type Context = Contexts.Context @@ -570,12 +572,12 @@ object DottyKernel extends TastyKernel { def SourceFile_path(source: SourceFile): String = source.path def SourceFile_exists(source: SourceFile): Boolean = source.exists - val SourceFile_noSource: SourceFile = util.NoSource + @sharable val SourceFile_noSource: SourceFile = util.NoSource def SourcePosition_line(pos: SourcePosition): Int = pos.line - val Span_empty: Span = Spans.Span(0,0) - val Span_noSpan: Span = Spans.NoSpan + @sharable val Span_empty: Span = Spans.Span(0,0) + @sharable val Span_noSpan: Span = Spans.NoSpan def Span_start(span: Span): Int = span.start def Span_end(span: Span): Int = span.end def Span_isSynthetic(span: Span): Boolean = span.isSynthetic @@ -621,7 +623,7 @@ object DottyKernel extends TastyKernel { def Tree_isType(tree: Tree): Boolean = tree.isType def Tree_tpe(tree: Tree): Type = tree.tpe - val EmptyTree: Tree = tpd.EmptyTree + @sharable val EmptyTree: Tree = tpd.EmptyTree def If_isInline(tree: If): Boolean = tree.isInline def Match_isInline(tree: Match): Boolean = tree.isInline @@ -758,7 +760,9 @@ object DottyKernel extends TastyKernel { def TermName_tag(name: TermName): Int = name.info.kind.tag - def SimpleName_toUTF8(name: SimpleName): Array[Byte] = io.Codec.toUTF8(Names.chrs, name.start, name.length) + def SimpleName_toUTF8(name: SimpleName): Array[Byte] = + if (name.length == 0) new Array[Byte](0) + else io.Codec.toUTF8(Names.chrs, name.start, name.length) def String_toTermName(name: String): TermName = { import Decorators._ @@ -774,7 +778,7 @@ object DottyKernel extends TastyKernel { def OuterSelectName_unapply(name: DerivedName): Option[(TermName, Int)] = NameKinds.OuterSelectName.unapply(name) def DerivedName_unapply(name: DerivedName): Some[TermName] = Some(name.underlying) - val nme_WILDCARD: TermName = StdNames.nme.WILDCARD + @sharable val nme_WILDCARD: TermName = StdNames.nme.WILDCARD def Signature_ParamSig_fold[A](paramSig: Signature_ParamSig)(onInt: Int => A, onTypeName: TypeName => A): A = paramSig match { diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyTasty.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyTasty.scala new file mode 100644 index 000000000000..09629662457c --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyTasty.scala @@ -0,0 +1,6 @@ +package dotty.tools.dotc.core.tasty.experimental + +import dotty.tools.tasty.experimental.Tasty + +object DottyTasty extends Tasty with + final val internal: DottyKernel.type = DottyKernel diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index c87e9911d97d..de3c562f7750 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -13,8 +13,12 @@ import Flags.Module import reporting.ThrowingReporter import collection.mutable +import dotty.tools.dotc.core.tasty.experimental.DottyTasty + +import dotty.tools.dotc.core.tasty.{TastyPrinter, DottyUnpickler} + import dotty.tools.tasty._ -import experimental._ +import dotty.tools.tasty.experimental._ object Pickler { val name: String = "pickler" @@ -38,7 +42,7 @@ class Pickler extends Phase { // Maps that keep a record if -Ytest-pickler is set. private val beforePickling = new mutable.HashMap[ClassSymbol, String] - private val picklers = new mutable.HashMap[ClassSymbol, TastyPickler] + private val picklers = new mutable.HashMap[ClassSymbol, TastyPickler[DottyTasty.type]] /** Drop any elements of this list that are linked module classes of other elements in the list */ private def dropCompanionModuleClasses(clss: List[ClassSymbol])(implicit ctx: Context): List[ClassSymbol] = { @@ -48,75 +52,78 @@ class Pickler extends Phase { } override def run(implicit ctx: Context): Unit = { - // val unit = ctx.compilationUnit - // pickling.println(i"unpickling in run ${ctx.runId}") - - // for { - // cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree)) - // tree <- sliceTopLevel(unit.tpdTree, cls) - // } - // { - // val pickler = new TastyPickler(cls) - // if (ctx.settings.YtestPickler.value) { - // beforePickling(cls) = tree.show - // picklers(cls) = pickler - // } - // val treePkl = pickler.treePkl - // treePkl.pickle(tree :: Nil) - // treePkl.compactify() - // pickler.addrOfTree = treePkl.buf.addrOfTree - // pickler.addrOfSym = treePkl.addrOfSym - // if (tree.span.exists) - // new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) - - // if (!ctx.settings.YdropComments.value) - // new CommentPickler(pickler, treePkl.buf.addrOfTree).pickleComment(tree) - - // // other pickle sections go here. - // val pickled = pickler.assembleParts() - // unit.pickled += (cls -> pickled) - - // def rawBytes = // not needed right now, but useful to print raw format. - // pickled.iterator.grouped(10).toList.zipWithIndex.map { - // case (row, i) => s"${i}0: ${row.mkString(" ")}" - // } - - // // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG - // if (pickling ne noPrinter) { - // println(i"**** pickled info of $cls") - // println(new TastyPrinter(pickled).printContents()) - // } - // } + val unit = ctx.compilationUnit + pickling.println(i"unpickling in run ${ctx.runId}") + + for { + cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree)) + tree <- sliceTopLevel(unit.tpdTree, cls) + } + { + val pickler = new TastyPickler(DottyTasty)(cls) + if (ctx.settings.YtestPickler.value) { + beforePickling(cls) = tree.show + picklers(cls) = pickler + } + val treePkl = pickler.treePkl + treePkl.pickle(tree :: Nil) + treePkl.compactify() + pickler.addrOfTree = treePkl.buf.addrOfTree + pickler.addrOfSym = treePkl.addrOfSym + if (tree.span.exists) { + val pospkl = new PositionPickler(DottyTasty)(pickler, treePkl.buf.addrOfTree) + pospkl.picklePositions(tree :: Nil) + } + + if (!ctx.settings.YdropComments.value) { + val compkl = new CommentPickler(DottyTasty)(pickler, treePkl.buf.addrOfTree) + compkl.pickleComment(tree) + } + + // other pickle sections go here. + val pickled = pickler.assembleParts() + unit.pickled += (cls -> pickled) + + def rawBytes = // not needed right now, but useful to print raw format. + pickled.iterator.grouped(10).toList.zipWithIndex.map { + case (row, i) => s"${i}0: ${row.mkString(" ")}" + } + + // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG + if (pickling ne noPrinter) { + println(i"**** pickled info of $cls") + println(new TastyPrinter(pickled).printContents()) + } + } } override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { - // val result = super.runOn(units) - // if (ctx.settings.YtestPickler.value) - // testUnpickler( - // ctx.fresh - // .setPeriod(Period(ctx.runId + 1, FirstPhaseId)) - // .setReporter(new ThrowingReporter(ctx.reporter)) - // .addMode(Mode.ReadPositions) - // .addMode(Mode.ReadComments) - // .addMode(Mode.PrintShowExceptions)) - // result - Nil + val result = super.runOn(units) + if (ctx.settings.YtestPickler.value) + testUnpickler( + ctx.fresh + .setPeriod(Period(ctx.runId + 1, FirstPhaseId)) + .setReporter(new ThrowingReporter(ctx.reporter)) + .addMode(Mode.ReadPositions) + .addMode(Mode.ReadComments) + .addMode(Mode.PrintShowExceptions)) + result } private def testUnpickler(implicit ctx: Context): Unit = { - // pickling.println(i"testing unpickler at run ${ctx.runId}") - // ctx.initialize() - // val unpicklers = - // for ((cls, pickler) <- picklers) yield { - // val unpickler = new DottyUnpickler(pickler.assembleParts()) - // unpickler.enter(roots = Set.empty) - // cls -> unpickler - // } - // pickling.println("************* entered toplevel ***********") - // for ((cls, unpickler) <- unpicklers) { - // val unpickled = unpickler.rootTrees - // testSame(i"$unpickled%\n%", beforePickling(cls), cls) - // } + pickling.println(i"testing unpickler at run ${ctx.runId}") + ctx.initialize() + val unpicklers = + for ((cls, pickler) <- picklers) yield { + val unpickler = new DottyUnpickler(pickler.assembleParts()) + unpickler.enter(roots = Set.empty) + cls -> unpickler + } + pickling.println("************* entered toplevel ***********") + for ((cls, unpickler) <- unpicklers) { + val unpickled = unpickler.rootTrees + testSame(i"$unpickled%\n%", beforePickling(cls), cls) + } } private def testSame(unpickled: String, previous: String, cls: ClassSymbol)(implicit ctx: Context) = diff --git a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala index 297c4de94b29..37fee762dc26 100644 --- a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala @@ -5,8 +5,8 @@ import TastyBuffer.{Addr, NoAddr} import java.nio.charset.Charset -class CommentPickler(val pickler: TastyPickler)(addrOfTree: pickler.tasty.Tree => Addr)(implicit ctx: pickler.tasty.Context) { - import pickler.tasty.{_, given} +class CommentPickler[T <: Tasty with Singleton](val tasty: T)(pickler: TastyPickler[tasty.type], addrOfTree: tasty.untpd.Tree => Addr)(implicit ctx: pickler.tasty.Context) { + import tasty.{_, given} private val buf = new TastyBuffer(5000) pickler.newSection("Comments", buf) diff --git a/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala index 9519aaf3da2c..2c4f60bb63fd 100644 --- a/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala +++ b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala @@ -7,7 +7,7 @@ import dotty.tools.tasty._ import TastyBuffer._ import scala.io.Codec -class NameBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(10000) { +class NameBuffer[T <: Tasty with Singleton](given val tasty: T) extends TastyBuffer(10000) { import tasty.{_, given} import NameBuffer._ diff --git a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala index bd385f525bb0..8930b2104437 100644 --- a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala @@ -6,8 +6,8 @@ import TastyBuffer._ import collection.mutable -class PositionPickler(val pickler: TastyPickler)(addrOfTree: pickler.tasty.untpd.Tree => Addr) { - import pickler.tasty.{_,given} +class PositionPickler[T <: Tasty with Singleton](val tasty: T)(val pickler: TastyPickler[tasty.type], addrOfTree: tasty.untpd.Tree => Addr) { + import tasty.{_,given} val buf: TastyBuffer = new TastyBuffer(5000) pickler.newSection("Positions", buf) diff --git a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala index aff7361aac0a..6f0120dcc15c 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala @@ -6,7 +6,7 @@ import dotty.tools.tasty.{TastyFormat, TastyBuffer, TastyHash} import TastyFormat._ import TastyBuffer._ -class TastyPickler(val tasty: Tasty)(val rootCls: tasty.ClassSymbol) { self => +class TastyPickler[T <: Tasty with Singleton](val tasty: T)(val rootCls: tasty.ClassSymbol) { self => import tasty.{_, given} private val sections = mutable.ArrayBuffer.empty[(NameRef, TastyBuffer)] @@ -64,7 +64,7 @@ class TastyPickler(val tasty: Tasty)(val rootCls: tasty.ClassSymbol) { self => * Note that trees are looked up by reference equality, * so one can reliably use this function only directly after `pickler`. */ - var addrOfTree: Tree => Addr = (_ => NoAddr) + var addrOfTree: untpd.Tree => Addr = (_ => NoAddr) /** * Addresses in TASTY file of symbols, stored by pickling. @@ -73,5 +73,5 @@ class TastyPickler(val tasty: Tasty)(val rootCls: tasty.ClassSymbol) { self => */ var addrOfSym: Symbol => Option[Addr] = (_ => None) - val treePkl = new TreePickler(self) + val treePkl = new TreePickler(tasty)(self.asInstanceOf[TastyPickler[tasty.type]]) } diff --git a/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala index e995f24ae471..0facf87b6364 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala @@ -6,7 +6,7 @@ import dotty.tools.tasty.TastyBuffer.{Addr, NoAddr, AddrWidth} import util.Util.bestFit -class TreeBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(50000) { +class TreeBuffer[T <: Tasty with Singleton](given val tasty: T) extends TastyBuffer(50000) { import tasty.{_, given} import Printers.pickling @@ -25,7 +25,7 @@ class TreeBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(50000) { case addr: Addr => addr } - def addrOfTree(tree: Tree): Addr = treeAddrs.get(tree) match { + def addrOfTree(tree: untpd.Tree): Addr = treeAddrs.get(tree) match { case null => NoAddr case addr: Addr => addr } diff --git a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala index 5e89bb76f8c3..2e20b0727aaf 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala @@ -9,9 +9,9 @@ object TreePickler { val sectionName = "ASTs" } -class TreePickler(val pickler: TastyPickler) { - import pickler.tasty.{_, given} - val buf = TreeBuffer[pickler.tasty.type](given pickler.tasty) +class TreePickler[T <: Tasty with Singleton](val tasty: T)(val pickler: TastyPickler[tasty.type]) { + import tasty.{_, given} + val buf = TreeBuffer[tasty.type](given tasty) pickler.newSection(TreePickler.sectionName, buf) import TreePickler._ import buf._ @@ -278,7 +278,7 @@ class TreePickler(val pickler: TastyPickler) { if (!tree.isEmpty) pickleTree(tree) } - def pickleDef(tag: Int, sym: Symbol, tpt: Tree, rhs: Tree = EmptyTree, pickleParams: => Unit = ())(implicit ctx: Context): Unit = { + def pickleDef(tag: Int, sym: Symbol, tpt: Tree, rhs: Tree = emptyTree, pickleParams: => Unit = ())(implicit ctx: Context): Unit = { assert(symRefs(sym) == NoAddr, sym) registerDef(sym) writeByte(tag) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala index 0e3cf5a8c7c0..285034c03c9c 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala @@ -19,6 +19,7 @@ trait ConstantOps extends Core with final val NullTag = internal.Constants_NullTag final val ClazzTag = internal.Constants_ClazzTag final val EnumTag = internal.Constants_EnumTag + end Constants given ConstantOps: (c: Constant) with def tag: Int = internal.Constant_tag(c) @@ -33,3 +34,4 @@ trait ConstantOps extends Core with def stringValue: String = internal.Constant_stringValue(c) def typeValue: Type = internal.Constant_typeValue(c) def symbolValue: Symbol = internal.Constant_symbolValue(c) + end ConstantOps diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala index c155536bc0c0..de33b0108765 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala @@ -47,16 +47,3 @@ trait FlagOps extends Core with def is(flag: Flag): Boolean = internal.FlagSet_is(flags, flag) def is(flag: Flag, butNot: FlagSet): Boolean = internal.FlagSet_is(flags, flag, butNot) def &~(flag: Flag): FlagSet = internal.FlagSet_&~(flags, flag) - - // given ClassTag[Tree] = internal.Tree_CT - // given ClassTag[MemberDef] = internal.MemberDef_CT - // given ClassTag[UntpdTree] = internal.UntpdTree_CT - // given ClassTag[Hole] = internal.Hole_CT - // given ClassTag[Template] = internal.Template_CT - - // given TreeOps: (tree: Tree) with - // def symbol(given Context): Symbol = internal.Tree_symbol(tree) - // def isEmpty: Boolean = internal.Tree_isEmpty(tree) - // def isType: Boolean = internal.Tree_isType(tree) - - // final val EmptyTree = internal.EmptyTree diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala index 66415fb2d8a3..d4fc85c415af 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala @@ -15,7 +15,7 @@ trait TastyKernel with type Designator <: AnyRef type Annotation <: AnyRef - val Annotation_CT: ClassTag[Annotation] + def Annotation_CT: ClassTag[Annotation] type Name <: Designator type SimpleName <: TermName @@ -23,15 +23,15 @@ trait TastyKernel with type TypeName <: Name type TermName <: Name - val Name_CT: ClassTag[Name] - val SimpleName_CT: ClassTag[SimpleName] - val DerivedName_CT: ClassTag[DerivedName] - val TypeName_CT: ClassTag[TypeName] - val TermName_CT: ClassTag[TermName] + def Name_CT: ClassTag[Name] + def SimpleName_CT: ClassTag[SimpleName] + def DerivedName_CT: ClassTag[DerivedName] + def TypeName_CT: ClassTag[TypeName] + def TermName_CT: ClassTag[TermName] type Signature <: AnyRef - val Signature_CT: ClassTag[Signature] + def Signature_CT: ClassTag[Signature] type Signature_ParamSig = Int | TypeName @@ -90,56 +90,56 @@ trait TastyKernel with type TypeBoundsTree <: Tree // TypTree[T] type Thicket <: Tree - val untpd_Tree_CT: ClassTag[untpd_Tree] - val untpd_TypedSplice_CT: ClassTag[untpd_TypedSplice] - val untpd_MemberDef_CT: ClassTag[untpd_MemberDef] - val untpd_Ident_CT: ClassTag[untpd_Ident] - - val Tree_CT: ClassTag[Tree] - val MemberDef_CT: ClassTag[MemberDef] - val Hole_CT: ClassTag[Hole] - val Template_CT: ClassTag[Template] - val ValOrDefDef_CT: ClassTag[ValOrDefDef] - val TypeDef_CT: ClassTag[TypeDef] - val ValDef_CT: ClassTag[ValDef] - val DefDef_CT: ClassTag[DefDef] - val Ident_CT: ClassTag[Ident] - val This_CT: ClassTag[This] - val Select_CT: ClassTag[Select] - val Apply_CT: ClassTag[Apply] - val TypeApply_CT: ClassTag[TypeApply] - val Literal_CT: ClassTag[Literal] - val Super_CT: ClassTag[Super] - val New_CT: ClassTag[New] - val Typed_CT: ClassTag[Typed] - val NamedArg_CT: ClassTag[NamedArg] - val Assign_CT: ClassTag[Assign] - val Block_CT: ClassTag[Block] - val If_CT: ClassTag[If] - val Closure_CT: ClassTag[Closure] - val Match_CT: ClassTag[Match] - val CaseDef_CT: ClassTag[CaseDef] - val Labeled_CT: ClassTag[Labeled] - val Return_CT: ClassTag[Return] - val WhileDo_CT: ClassTag[WhileDo] - val Try_CT: ClassTag[Try] - val SeqLiteral_CT: ClassTag[SeqLiteral] - val Inlined_CT: ClassTag[Inlined] - val Bind_CT: ClassTag[Bind] - val Alternative_CT: ClassTag[Alternative] - val UnApply_CT: ClassTag[UnApply] - val Import_CT: ClassTag[Import] - val PackageDef_CT: ClassTag[PackageDef] - val TypeTree_CT: ClassTag[TypeTree] - val SingletonTypeTree_CT: ClassTag[SingletonTypeTree] - val RefinedTypeTree_CT: ClassTag[RefinedTypeTree] - val AppliedTypeTree_CT: ClassTag[AppliedTypeTree] - val MatchTypeTree_CT: ClassTag[MatchTypeTree] - val ByNameTypeTree_CT: ClassTag[ByNameTypeTree] - val Annotated_CT: ClassTag[Annotated] - val LambdaTypeTree_CT: ClassTag[LambdaTypeTree] - val TypeBoundsTree_CT: ClassTag[TypeBoundsTree] - val Thicket_CT: ClassTag[Thicket] + def untpd_Tree_CT: ClassTag[untpd_Tree] + def untpd_TypedSplice_CT: ClassTag[untpd_TypedSplice] + def untpd_MemberDef_CT: ClassTag[untpd_MemberDef] + def untpd_Ident_CT: ClassTag[untpd_Ident] + + def Tree_CT: ClassTag[Tree] + def MemberDef_CT: ClassTag[MemberDef] + def Hole_CT: ClassTag[Hole] + def Template_CT: ClassTag[Template] + def ValOrDefDef_CT: ClassTag[ValOrDefDef] + def TypeDef_CT: ClassTag[TypeDef] + def ValDef_CT: ClassTag[ValDef] + def DefDef_CT: ClassTag[DefDef] + def Ident_CT: ClassTag[Ident] + def This_CT: ClassTag[This] + def Select_CT: ClassTag[Select] + def Apply_CT: ClassTag[Apply] + def TypeApply_CT: ClassTag[TypeApply] + def Literal_CT: ClassTag[Literal] + def Super_CT: ClassTag[Super] + def New_CT: ClassTag[New] + def Typed_CT: ClassTag[Typed] + def NamedArg_CT: ClassTag[NamedArg] + def Assign_CT: ClassTag[Assign] + def Block_CT: ClassTag[Block] + def If_CT: ClassTag[If] + def Closure_CT: ClassTag[Closure] + def Match_CT: ClassTag[Match] + def CaseDef_CT: ClassTag[CaseDef] + def Labeled_CT: ClassTag[Labeled] + def Return_CT: ClassTag[Return] + def WhileDo_CT: ClassTag[WhileDo] + def Try_CT: ClassTag[Try] + def SeqLiteral_CT: ClassTag[SeqLiteral] + def Inlined_CT: ClassTag[Inlined] + def Bind_CT: ClassTag[Bind] + def Alternative_CT: ClassTag[Alternative] + def UnApply_CT: ClassTag[UnApply] + def Import_CT: ClassTag[Import] + def PackageDef_CT: ClassTag[PackageDef] + def TypeTree_CT: ClassTag[TypeTree] + def SingletonTypeTree_CT: ClassTag[SingletonTypeTree] + def RefinedTypeTree_CT: ClassTag[RefinedTypeTree] + def AppliedTypeTree_CT: ClassTag[AppliedTypeTree] + def MatchTypeTree_CT: ClassTag[MatchTypeTree] + def ByNameTypeTree_CT: ClassTag[ByNameTypeTree] + def Annotated_CT: ClassTag[Annotated] + def LambdaTypeTree_CT: ClassTag[LambdaTypeTree] + def TypeBoundsTree_CT: ClassTag[TypeBoundsTree] + def Thicket_CT: ClassTag[Thicket] type Type <: AnyRef type AppliedType <: Type // <: CachedProxyType with ValueType @@ -171,31 +171,31 @@ trait TastyKernel with type MethodType <: LambdaType // MethodOrPoly with TermLambda type LazyRef <: Type - val Type_CT: ClassTag[Type] - val AppliedType_CT: ClassTag[AppliedType] - val ConstantType_CT: ClassTag[ConstantType] - val NamedType_CT: ClassTag[NamedType] - val ThisType_CT: ClassTag[ThisType] - val SuperType_CT: ClassTag[SuperType] - val RecThis_CT: ClassTag[RecThis] - val RecType_CT: ClassTag[RecType] - val TermRef_CT: ClassTag[TermRef] - val TypeRef_CT: ClassTag[TypeRef] - val ParamRef_CT: ClassTag[ParamRef] - val SkolemType_CT: ClassTag[SkolemType] - val RefinedType_CT: ClassTag[RefinedType] - val TypeAlias_CT: ClassTag[TypeAlias] - val TypeBounds_CT: ClassTag[TypeBounds] - val AnnotatedType_CT: ClassTag[AnnotatedType] - val AndType_CT: ClassTag[AndType] - val OrType_CT: ClassTag[OrType] - val MatchType_CT: ClassTag[MatchType] - val ExprType_CT: ClassTag[ExprType] - val HKTypeLambda_CT: ClassTag[HKTypeLambda] - val PolyType_CT: ClassTag[PolyType] - val MethodType_CT: ClassTag[MethodType] - val LazyRef_CT: ClassTag[LazyRef] - val ClassInfo_CT: ClassTag[ClassInfo] + def Type_CT: ClassTag[Type] + def AppliedType_CT: ClassTag[AppliedType] + def ConstantType_CT: ClassTag[ConstantType] + def NamedType_CT: ClassTag[NamedType] + def ThisType_CT: ClassTag[ThisType] + def SuperType_CT: ClassTag[SuperType] + def RecThis_CT: ClassTag[RecThis] + def RecType_CT: ClassTag[RecType] + def TermRef_CT: ClassTag[TermRef] + def TypeRef_CT: ClassTag[TypeRef] + def ParamRef_CT: ClassTag[ParamRef] + def SkolemType_CT: ClassTag[SkolemType] + def RefinedType_CT: ClassTag[RefinedType] + def TypeAlias_CT: ClassTag[TypeAlias] + def TypeBounds_CT: ClassTag[TypeBounds] + def AnnotatedType_CT: ClassTag[AnnotatedType] + def AndType_CT: ClassTag[AndType] + def OrType_CT: ClassTag[OrType] + def MatchType_CT: ClassTag[MatchType] + def ExprType_CT: ClassTag[ExprType] + def HKTypeLambda_CT: ClassTag[HKTypeLambda] + def PolyType_CT: ClassTag[PolyType] + def MethodType_CT: ClassTag[MethodType] + def LazyRef_CT: ClassTag[LazyRef] + def ClassInfo_CT: ClassTag[ClassInfo] type Symbol <: Designator { type ThisName <: Name } type TermSymbol <: Symbol { type ThisName = TermName } @@ -205,8 +205,8 @@ trait TastyKernel with type FlagSet type Flag <: FlagSet - val Symbol_CT: ClassTag[Symbol] - val ClassSymbol_CT: ClassTag[ClassSymbol] + def Symbol_CT: ClassTag[Symbol] + def ClassSymbol_CT: ClassTag[ClassSymbol] type Symbols_MutableSymbolMap[T] @@ -219,42 +219,42 @@ trait TastyKernel with type Constant <: AnyRef - val Flags_Protected: Flag - val Flags_ParamAccessor: Flag - val Flags_Private: Flag - val Flags_Final: Flag - val Flags_Case: Flag - val Flags_Override: Flag - val Flags_Inline: Flag - val Flags_InlineProxy: Flag - val Flags_Macro: Flag - val Flags_JavaStatic: Flag - val Flags_Module: Flag - val Flags_Enum: Flag - val Flags_Local: Flag - val Flags_Synthetic: Flag - val Flags_Artifact: Flag - val Flags_Scala2x: Flag - val Flags_Implicit: Flag - val Flags_Given: Flag - val Flags_Erased: Flag - val Flags_Lazy: Flag - val Flags_AbsOverride: Flag - val Flags_Mutable: Flag - val Flags_Accessor: Flag - val Flags_CaseAccessor: Flag - val Flags_DefaultParameterized: Flag - val Flags_StableRealizable: Flag - val Flags_Extension: Flag - val Flags_Exported: Flag - val Flags_Label: Flag - val Flags_Sealed: Flag - val Flags_Abstract: Flag - val Flags_Trait: Flag - val Flags_Covariant: Flag - val Flags_Contravariant: Flag - val Flags_Opaque: Flag - val Flags_Open: Flag + def Flags_Protected: Flag + def Flags_ParamAccessor: Flag + def Flags_Private: Flag + def Flags_Final: Flag + def Flags_Case: Flag + def Flags_Override: Flag + def Flags_Inline: Flag + def Flags_InlineProxy: Flag + def Flags_Macro: Flag + def Flags_JavaStatic: Flag + def Flags_Module: Flag + def Flags_Enum: Flag + def Flags_Local: Flag + def Flags_Synthetic: Flag + def Flags_Artifact: Flag + def Flags_Scala2x: Flag + def Flags_Implicit: Flag + def Flags_Given: Flag + def Flags_Erased: Flag + def Flags_Lazy: Flag + def Flags_AbsOverride: Flag + def Flags_Mutable: Flag + def Flags_Accessor: Flag + def Flags_CaseAccessor: Flag + def Flags_DefaultParameterized: Flag + def Flags_StableRealizable: Flag + def Flags_Extension: Flag + def Flags_Exported: Flag + def Flags_Label: Flag + def Flags_Sealed: Flag + def Flags_Abstract: Flag + def Flags_Trait: Flag + def Flags_Covariant: Flag + def Flags_Contravariant: Flag + def Flags_Opaque: Flag + def Flags_Open: Flag def FlagSet_is(flags: FlagSet, flag: Flag): Boolean def FlagSet_is(flags: FlagSet, flag: Flag, butNot: FlagSet): Boolean @@ -329,12 +329,12 @@ trait TastyKernel with def SourceFile_path(source: SourceFile): String def SourceFile_exists(source: SourceFile): Boolean - val SourceFile_noSource: SourceFile + def SourceFile_noSource: SourceFile def SourcePosition_line(pos: SourcePosition): Int - val Span_empty: Span - val Span_noSpan: Span + def Span_empty: Span + def Span_noSpan: Span def Span_start(span: Span): Int def Span_end(span: Span): Int def Span_isSynthetic(span: Span): Boolean @@ -361,7 +361,7 @@ trait TastyKernel with def Tree_isType(tree: Tree): Boolean def Tree_tpe(tree: Tree): Type - val EmptyTree: Tree + def EmptyTree: Tree def If_isInline(tree: If): Boolean def Match_isInline(tree: Match): Boolean @@ -507,7 +507,7 @@ trait TastyKernel with def OuterSelectName_unapply(name: DerivedName): Option[(TermName, Int)] def DerivedName_unapply(name: DerivedName): Some[TermName] - val nme_WILDCARD: TermName + def nme_WILDCARD: TermName def Signature_ParamSig_fold[A](paramSig: Signature_ParamSig)(onInt: Int => A, onTypeName: TypeName => A): A def Signature_ParamSig_foldInt(paramSig: Signature_ParamSig)(onInt: IntToInt, onTypeName: ToInt[TypeName]): Int diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala index 1ca1a11f9ee4..f8cccc09dd22 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala @@ -190,7 +190,7 @@ trait TreeOps extends Core with def body(given Context): List[Tree] = internal.Template_body(tree) def derived: List[untpd.Tree] = internal.Template_derived(tree) - final val EmptyTree = internal.EmptyTree + def emptyTree = internal.EmptyTree def inlineContext(tree: Tree)(implicit ctx: Context): Context = internal.inlineContext(tree) From fccebb0cb7d05319ef227df0c8252a7656be0d7d Mon Sep 17 00:00:00 2001 From: bishabosha Date: Sun, 1 Dec 2019 21:21:18 +0100 Subject: [PATCH 5/8] make new wrapper classes to avoid passing in tasty explicitly --- .../dotc/core/quoted/PickledQuotes.scala | 11 ++++------ .../tasty/experimental/CommentPickler.scala | 10 +++++++++ .../core/tasty/experimental/DottyKernel.scala | 8 +++---- .../tasty/experimental/PositionPickler.scala | 9 ++++++++ .../tasty/experimental/TastyPickler.scala | 7 +++++++ .../dotty/tools/dotc/transform/Pickler.scala | 21 +++++++------------ .../tasty/experimental/CommentPickler.scala | 2 +- .../tools/tasty/experimental/NameBuffer.scala | 2 +- .../tasty/experimental/PositionPickler.scala | 2 +- .../tasty/experimental/TastyPickler.scala | 4 ++-- .../tools/tasty/experimental/TreeBuffer.scala | 6 +++--- .../tasty/experimental/TreePickler.scala | 2 +- 12 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala create mode 100644 compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala create mode 100644 compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 661d7a94955e..d731ed5ac0ff 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -13,12 +13,11 @@ 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.TastyPrinter -import dotty.tools.dotc.core.tasty.experimental.DottyTasty +import dotty.tools.dotc.core.tasty.experimental.{DottyTasty, PositionPickler, TastyPickler} import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode import dotty.tools.dotc.quoted.QuoteContext import dotty.tools.dotc.tastyreflect.{ReflectionImpl, TastyTreeExpr, TreeType} -import dotty.tools.tasty.experimental.{ TastyPickler, PositionPickler } import dotty.tools.tasty.TastyString import scala.internal.quoted._ @@ -100,16 +99,14 @@ object PickledQuotes { /** Pickle tree into it's TASTY bytes s*/ private def pickle(tree: Tree)(implicit ctx: Context): Array[Byte] = { - val pickler = new TastyPickler(DottyTasty)(defn.RootClass) + val pickler = new TastyPickler(defn.RootClass) val treePkl = pickler.treePkl treePkl.pickle(tree :: Nil) treePkl.compactify() pickler.addrOfTree = treePkl.buf.addrOfTree pickler.addrOfSym = treePkl.addrOfSym - if (tree.span.exists) { - val pospkl = new PositionPickler(DottyTasty)(pickler, treePkl.buf.addrOfTree) - pospkl.picklePositions(tree :: Nil) - } + if (tree.span.exists) + new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) if (quotePickling ne noPrinter) println(i"**** pickling quote of \n${tree.show}") diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala new file mode 100644 index 000000000000..f5a900683e10 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala @@ -0,0 +1,10 @@ +package dotty.tools.dotc.core.tasty.experimental + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context + +import dotty.tools.tasty.experimental.{TastyPickler, CommentPickler => CommentPicklerImpl} +import dotty.tools.tasty.TastyBuffer.Addr + +class CommentPickler(pickler: TastyPickler[DottyTasty.type], addrOfTree: tpd.Tree => Addr)(implicit ctx: Context) + extends CommentPicklerImpl(DottyTasty)(pickler, addrOfTree) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala index 6b0bd34d705a..8aa702658b66 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala @@ -588,7 +588,7 @@ object DottyKernel extends TastyKernel { private inline def defn(given ctx: Context) = ctx.definitions - def defn_throwMethod(given ctx: Context): TermSymbol = defn.throwMethod + def defn_throwMethod(given Context): TermSymbol = defn.throwMethod def defn_BodyAnnot(given Context): ClassSymbol = defn.BodyAnnot def Name_toTermName(name: Name): TermName = name.toTermName @@ -677,8 +677,8 @@ object DottyKernel extends TastyKernel { def DefDef_vparamss(tree: DefDef): List[List[ValDef]] = tree.vparamss def TypeDef_rhs(tree: TypeDef): Tree = tree.rhs - def ImportSelector_imported(tree: untpd_ImportSelector): untpd.Ident = tree.imported - def ImportSelector_renamed(tree: untpd_ImportSelector): untpd.Tree = tree.renamed + def ImportSelector_imported(tree: untpd_ImportSelector): untpd_Ident = tree.imported + def ImportSelector_renamed(tree: untpd_ImportSelector): untpd_Tree = tree.renamed def ImportSelector_bound(tree: untpd_ImportSelector): untpd_Tree = tree.bound def Template_decomposeBody(tree: Template)(given Context): (List[Tree], List[Tree]) = @@ -722,7 +722,7 @@ object DottyKernel extends TastyKernel { def NamedType_symbol(tpe: NamedType)(given Context): Symbol = tpe.symbol def NamedType_prefix(tpe: NamedType): Type = tpe.prefix def NamedType_designator(tpe: NamedType): Designator = tpe.designator - def NamedType_hasNoPrefix(tpe: NamedType): Boolean = tpe.prefix `eq` Types.NoPrefix + def NamedType_hasNoPrefix(tpe: NamedType): Boolean = tpe.prefix == Types.NoPrefix def NamedType_isType(tpe: NamedType): Boolean = tpe.isType def TypeAlias_alias(tpe: TypeAlias): Type = tpe.alias diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala new file mode 100644 index 000000000000..acdb2075b7fd --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala @@ -0,0 +1,9 @@ +package dotty.tools.dotc.core.tasty.experimental + +import dotty.tools.dotc.ast.untpd + +import dotty.tools.tasty.experimental.{TastyPickler, PositionPickler => PositionPicklerImpl} +import dotty.tools.tasty.TastyBuffer.Addr + +class PositionPickler(pickler: TastyPickler[DottyTasty.type], addrOfTree: untpd.Tree => Addr) + extends PositionPicklerImpl(DottyTasty)(pickler, addrOfTree) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala new file mode 100644 index 000000000000..11eb8caca463 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala @@ -0,0 +1,7 @@ +package dotty.tools.dotc.core.tasty.experimental + +import dotty.tools.dotc.core.Symbols.ClassSymbol + +import dotty.tools.tasty.experimental.{TastyPickler => TastyPicklerImpl} + +class TastyPickler(rootCls: ClassSymbol) extends TastyPicklerImpl(DottyTasty)(rootCls) diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index de3c562f7750..fa946f14a574 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -13,13 +13,10 @@ import Flags.Module import reporting.ThrowingReporter import collection.mutable -import dotty.tools.dotc.core.tasty.experimental.DottyTasty +import dotty.tools.dotc.core.tasty.experimental.{DottyTasty, PositionPickler, CommentPickler, TastyPickler} import dotty.tools.dotc.core.tasty.{TastyPrinter, DottyUnpickler} -import dotty.tools.tasty._ -import dotty.tools.tasty.experimental._ - object Pickler { val name: String = "pickler" } @@ -42,7 +39,7 @@ class Pickler extends Phase { // Maps that keep a record if -Ytest-pickler is set. private val beforePickling = new mutable.HashMap[ClassSymbol, String] - private val picklers = new mutable.HashMap[ClassSymbol, TastyPickler[DottyTasty.type]] + private val picklers = new mutable.HashMap[ClassSymbol, TastyPickler] /** Drop any elements of this list that are linked module classes of other elements in the list */ private def dropCompanionModuleClasses(clss: List[ClassSymbol])(implicit ctx: Context): List[ClassSymbol] = { @@ -60,7 +57,7 @@ class Pickler extends Phase { tree <- sliceTopLevel(unit.tpdTree, cls) } { - val pickler = new TastyPickler(DottyTasty)(cls) + val pickler = new TastyPickler(cls) if (ctx.settings.YtestPickler.value) { beforePickling(cls) = tree.show picklers(cls) = pickler @@ -70,15 +67,11 @@ class Pickler extends Phase { treePkl.compactify() pickler.addrOfTree = treePkl.buf.addrOfTree pickler.addrOfSym = treePkl.addrOfSym - if (tree.span.exists) { - val pospkl = new PositionPickler(DottyTasty)(pickler, treePkl.buf.addrOfTree) - pospkl.picklePositions(tree :: Nil) - } + if (tree.span.exists) + new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) - if (!ctx.settings.YdropComments.value) { - val compkl = new CommentPickler(DottyTasty)(pickler, treePkl.buf.addrOfTree) - compkl.pickleComment(tree) - } + if (!ctx.settings.YdropComments.value) + new CommentPickler(pickler, treePkl.buf.addrOfTree).pickleComment(tree) // other pickle sections go here. val pickled = pickler.assembleParts() diff --git a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala index 37fee762dc26..8223b425c552 100644 --- a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala @@ -5,7 +5,7 @@ import TastyBuffer.{Addr, NoAddr} import java.nio.charset.Charset -class CommentPickler[T <: Tasty with Singleton](val tasty: T)(pickler: TastyPickler[tasty.type], addrOfTree: tasty.untpd.Tree => Addr)(implicit ctx: pickler.tasty.Context) { +class CommentPickler[T <: Tasty](val tasty: T)(pickler: TastyPickler[tasty.type], addrOfTree: tasty.Tree => Addr)(implicit ctx: tasty.Context) { import tasty.{_, given} private val buf = new TastyBuffer(5000) pickler.newSection("Comments", buf) diff --git a/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala index 2c4f60bb63fd..9519aaf3da2c 100644 --- a/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala +++ b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala @@ -7,7 +7,7 @@ import dotty.tools.tasty._ import TastyBuffer._ import scala.io.Codec -class NameBuffer[T <: Tasty with Singleton](given val tasty: T) extends TastyBuffer(10000) { +class NameBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(10000) { import tasty.{_, given} import NameBuffer._ diff --git a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala index 8930b2104437..5f7efcd59af0 100644 --- a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala @@ -6,7 +6,7 @@ import TastyBuffer._ import collection.mutable -class PositionPickler[T <: Tasty with Singleton](val tasty: T)(val pickler: TastyPickler[tasty.type], addrOfTree: tasty.untpd.Tree => Addr) { +class PositionPickler[T <: Tasty](val tasty: T)(val pickler: TastyPickler[tasty.type], addrOfTree: tasty.untpd.Tree => Addr) { import tasty.{_,given} val buf: TastyBuffer = new TastyBuffer(5000) pickler.newSection("Positions", buf) diff --git a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala index 6f0120dcc15c..317303df9f78 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala @@ -6,7 +6,7 @@ import dotty.tools.tasty.{TastyFormat, TastyBuffer, TastyHash} import TastyFormat._ import TastyBuffer._ -class TastyPickler[T <: Tasty with Singleton](val tasty: T)(val rootCls: tasty.ClassSymbol) { self => +class TastyPickler[T <: Tasty](val tasty: T)(val rootCls: tasty.ClassSymbol) { self => import tasty.{_, given} private val sections = mutable.ArrayBuffer.empty[(NameRef, TastyBuffer)] @@ -64,7 +64,7 @@ class TastyPickler[T <: Tasty with Singleton](val tasty: T)(val rootCls: tasty.C * Note that trees are looked up by reference equality, * so one can reliably use this function only directly after `pickler`. */ - var addrOfTree: untpd.Tree => Addr = (_ => NoAddr) + var addrOfTree: Tree => Addr = (_ => NoAddr) /** * Addresses in TASTY file of symbols, stored by pickling. diff --git a/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala index 0facf87b6364..d953a4e5dad3 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala @@ -1,12 +1,12 @@ package dotty.tools.tasty.experimental -import dotty.tools.tasty.util.Util.{dble} +import dotty.tools.tasty.util.Util.dble import dotty.tools.tasty.TastyBuffer -import dotty.tools.tasty.TastyBuffer.{Addr, NoAddr, AddrWidth} +import TastyBuffer.{Addr, NoAddr, AddrWidth} import util.Util.bestFit -class TreeBuffer[T <: Tasty with Singleton](given val tasty: T) extends TastyBuffer(50000) { +class TreeBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(50000) { import tasty.{_, given} import Printers.pickling diff --git a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala index 2e20b0727aaf..ff4f88a12027 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala @@ -9,7 +9,7 @@ object TreePickler { val sectionName = "ASTs" } -class TreePickler[T <: Tasty with Singleton](val tasty: T)(val pickler: TastyPickler[tasty.type]) { +class TreePickler[T <: Tasty](val tasty: T)(val pickler: TastyPickler[tasty.type]) { import tasty.{_, given} val buf = TreeBuffer[tasty.type](given tasty) pickler.newSection(TreePickler.sectionName, buf) From 8f32efb26d415732d57bd13fdd4b3ee3b8d356dc Mon Sep 17 00:00:00 2001 From: bishabosha Date: Sun, 1 Dec 2019 23:10:57 +0100 Subject: [PATCH 6/8] attempt to pass Ycheck --- .../tasty/experimental/CommentPickler.scala | 6 +- .../tasty/experimental/PositionPickler.scala | 6 +- .../tasty/experimental/CommentPickler.scala | 10 +- .../tasty/experimental/PositionPickler.scala | 6 +- .../tasty/experimental/TastyPickler.scala | 4 +- .../tools/tasty/experimental/TreeBuffer.scala | 2 +- .../tasty/experimental/TreePickler.scala | 7 +- .../experimental/bridge/AnnotationOps.scala | 3 +- .../tasty/experimental/bridge/Core.scala | 47 --- .../tasty/experimental/bridge/TreeOps.scala | 338 ++++++++++-------- 10 files changed, 218 insertions(+), 211 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala index f5a900683e10..297c23087959 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala @@ -3,8 +3,8 @@ package dotty.tools.dotc.core.tasty.experimental import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.tasty.experimental.{TastyPickler, CommentPickler => CommentPicklerImpl} +import dotty.tools.tasty.experimental.{CommentPickler => CommentPicklerImpl} import dotty.tools.tasty.TastyBuffer.Addr -class CommentPickler(pickler: TastyPickler[DottyTasty.type], addrOfTree: tpd.Tree => Addr)(implicit ctx: Context) - extends CommentPicklerImpl(DottyTasty)(pickler, addrOfTree) +class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr)(implicit ctx: Context) + extends CommentPicklerImpl(pickler, addrOfTree) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala index acdb2075b7fd..b2e2a06f8057 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala @@ -2,8 +2,8 @@ package dotty.tools.dotc.core.tasty.experimental import dotty.tools.dotc.ast.untpd -import dotty.tools.tasty.experimental.{TastyPickler, PositionPickler => PositionPicklerImpl} +import dotty.tools.tasty.experimental.{PositionPickler => PositionPicklerImpl} import dotty.tools.tasty.TastyBuffer.Addr -class PositionPickler(pickler: TastyPickler[DottyTasty.type], addrOfTree: untpd.Tree => Addr) - extends PositionPicklerImpl(DottyTasty)(pickler, addrOfTree) +class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) + extends PositionPicklerImpl(pickler, addrOfTree) diff --git a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala index 8223b425c552..627237b1807f 100644 --- a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala @@ -5,12 +5,12 @@ import TastyBuffer.{Addr, NoAddr} import java.nio.charset.Charset -class CommentPickler[T <: Tasty](val tasty: T)(pickler: TastyPickler[tasty.type], addrOfTree: tasty.Tree => Addr)(implicit ctx: tasty.Context) { - import tasty.{_, given} +class CommentPickler[T <: Tasty](val pickler: TastyPickler[T], addrOfTree: pickler.tasty.tpd.Tree => Addr)(implicit ctx: pickler.tasty.Context) { + import pickler.tasty.{_, given} private val buf = new TastyBuffer(5000) pickler.newSection("Comments", buf) - def pickleComment(root: Tree): Unit = { + def pickleComment(root: tpd.Tree): Unit = { val docCtx = ctx.docCtx assert(docCtx.isDefined, "Trying to pickle comments, but there's no `docCtx`.") new Traverser(docCtx.get).traverse(root) @@ -29,9 +29,9 @@ class CommentPickler[T <: Tasty](val tasty: T)(pickler: TastyPickler[tasty.type] } private class Traverser(docCtx: ContextDocstrings) extends TreeTraverser { - override def traverse(tree: Tree)(implicit ctx: Context): Unit = + override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match { - case md: MemberDef => + case md: tpd.MemberDef => val comment = docCtx.docstring(md.symbol) pickleComment(addrOfTree(md), comment) traverseChildren(md) diff --git a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala index 5f7efcd59af0..7c1bed5b8431 100644 --- a/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala @@ -6,8 +6,8 @@ import TastyBuffer._ import collection.mutable -class PositionPickler[T <: Tasty](val tasty: T)(val pickler: TastyPickler[tasty.type], addrOfTree: tasty.untpd.Tree => Addr) { - import tasty.{_,given} +class PositionPickler[T <: Tasty](val pickler: TastyPickler[T], addrOfTree: pickler.tasty.untpd.Tree => Addr) { + import pickler.tasty.{_,given} val buf: TastyBuffer = new TastyBuffer(5000) pickler.newSection("Positions", buf) @@ -18,7 +18,7 @@ class PositionPickler[T <: Tasty](val tasty: T)(val pickler: TastyPickler[tasty. (addrDelta << 3) | (toInt(hasStartDelta) << 2) | (toInt(hasEndDelta) << 1) | toInt(hasPoint) } - def picklePositions(roots: List[Tree])(implicit ctx: Context): Unit = { + def picklePositions(roots: List[tpd.Tree])(implicit ctx: Context): Unit = { var lastIndex = 0 var lastSpan = Span.empty def pickleDeltas(index: Int, span: Span) = { diff --git a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala index 317303df9f78..77e355686c43 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala @@ -64,7 +64,7 @@ class TastyPickler[T <: Tasty](val tasty: T)(val rootCls: tasty.ClassSymbol) { s * Note that trees are looked up by reference equality, * so one can reliably use this function only directly after `pickler`. */ - var addrOfTree: Tree => Addr = (_ => NoAddr) + var addrOfTree: tpd.Tree => Addr = (_ => NoAddr) /** * Addresses in TASTY file of symbols, stored by pickling. @@ -73,5 +73,5 @@ class TastyPickler[T <: Tasty](val tasty: T)(val rootCls: tasty.ClassSymbol) { s */ var addrOfSym: Symbol => Option[Addr] = (_ => None) - val treePkl = new TreePickler(tasty)(self.asInstanceOf[TastyPickler[tasty.type]]) + val treePkl = new TreePickler(self) } diff --git a/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala index d953a4e5dad3..fca732ecb715 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala @@ -6,7 +6,7 @@ import TastyBuffer.{Addr, NoAddr, AddrWidth} import util.Util.bestFit -class TreeBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(50000) { +class TreeBuffer[T <: Tasty](val tasty: T) extends TastyBuffer(50000) { import tasty.{_, given} import Printers.pickling diff --git a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala index ff4f88a12027..1f655f0f323e 100644 --- a/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala @@ -9,15 +9,16 @@ object TreePickler { val sectionName = "ASTs" } -class TreePickler[T <: Tasty](val tasty: T)(val pickler: TastyPickler[tasty.type]) { - import tasty.{_, given} - val buf = TreeBuffer[tasty.type](given tasty) +class TreePickler[T <: Tasty](val pickler: TastyPickler[T]) { + import pickler.tasty.{_, given} + val buf = TreeBuffer[pickler.tasty.type](pickler.tasty) pickler.newSection(TreePickler.sectionName, buf) import TreePickler._ import buf._ import pickler.nameBuffer.nameIndex import Constants._ import Symbols.{_,given} + import tpd._ private val symRefs = Symbols.newMutableSymbolMap[Addr] private val forwardSymRefs = Symbols.newMutableSymbolMap[List[Addr]] diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala index 81a2350c326f..30405781ee87 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala @@ -3,6 +3,7 @@ package dotty.tools.tasty.experimental.bridge import reflect.ClassTag trait AnnotationOps extends Core with + self: TreeOps with PositionOps with ContextOps with SourceFileOps with SymbolOps => given ClassTag[Annotation] = internal.Annotation_CT @@ -13,5 +14,5 @@ trait AnnotationOps extends Core with def unapply(annot: Annotation)(given Context): Option[Symbol] = internal.Annotation_Child_unapply(annot) given AnnotationOps: (annot: Annotation) with - def tree(given Context): Tree = internal.Annotation_tree(annot) + def tree(given Context): tpd.Tree = internal.Annotation_tree(annot) def symbol(given Context): Symbol = internal.Annotation_symbol(annot) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala index 086948c4e47b..a8c1ac301702 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala @@ -22,53 +22,6 @@ trait Core with type Positioned = internal.Positioned - type Tree = internal.Tree - type MemberDef = internal.MemberDef - type Hole = internal.Hole - type Template = internal.Template - type ValOrDefDef = internal.ValOrDefDef - type TypeDef = internal.TypeDef - type ValDef = internal.ValDef - type DefDef = internal.DefDef - type RefTree = internal.RefTree - type Ident = internal.Ident - type Select = internal.Select - type This = internal.This - type Apply = internal.Apply - type TypeApply = internal.TypeApply - type Literal = internal.Literal - type Super = internal.Super - type New = internal.New - type Typed = internal.Typed - type NamedArg = internal.NamedArg - type Assign = internal.Assign - type Block = internal.Block - type If = internal.If - type Closure = internal.Closure - type Match = internal.Match - type CaseDef = internal.CaseDef - type Labeled = internal.Labeled - type Return = internal.Return - type WhileDo = internal.WhileDo - type Try = internal.Try - type SeqLiteral = internal.SeqLiteral - type Inlined = internal.Inlined - type Bind = internal.Bind - type Alternative = internal.Alternative - type UnApply = internal.UnApply - type Import = internal.Import - type PackageDef = internal.PackageDef - type TypeTree = internal.TypeTree - type SingletonTypeTree = internal.SingletonTypeTree - type RefinedTypeTree = internal.RefinedTypeTree - type AppliedTypeTree = internal.AppliedTypeTree - type MatchTypeTree = internal.MatchTypeTree - type ByNameTypeTree = internal.ByNameTypeTree - type Annotated = internal.Annotated - type LambdaTypeTree = internal.LambdaTypeTree - type TypeBoundsTree = internal.TypeBoundsTree - type Thicket = internal.Thicket - type Type = internal.Type type AppliedType = internal.AppliedType type ConstantType = internal.ConstantType diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala index f8cccc09dd22..b587b7e42965 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala @@ -5,57 +5,182 @@ import reflect.ClassTag trait TreeOps extends Core with self: PositionOps with ContextOps with SourceFileOps with SymbolOps => - given ClassTag[Tree] = internal.Tree_CT - given ClassTag[MemberDef] = internal.MemberDef_CT - given ClassTag[Hole] = internal.Hole_CT - given ClassTag[Template] = internal.Template_CT - given ClassTag[ValOrDefDef] = internal.ValOrDefDef_CT - given ClassTag[TypeDef] = internal.TypeDef_CT - given ClassTag[ValDef] = internal.ValDef_CT - given ClassTag[DefDef] = internal.DefDef_CT - given ClassTag[Ident] = internal.Ident_CT - given ClassTag[This] = internal.This_CT - given ClassTag[Select] = internal.Select_CT - given ClassTag[Apply] = internal.Apply_CT - given ClassTag[TypeApply] = internal.TypeApply_CT - given ClassTag[Literal] = internal.Literal_CT - given ClassTag[Super] = internal.Super_CT - given ClassTag[New] = internal.New_CT - given ClassTag[Typed] = internal.Typed_CT - given ClassTag[NamedArg] = internal.NamedArg_CT - given ClassTag[Assign] = internal.Assign_CT - given ClassTag[Block] = internal.Block_CT - given ClassTag[If] = internal.If_CT - given ClassTag[Closure] = internal.Closure_CT - given ClassTag[Match] = internal.Match_CT - given ClassTag[CaseDef] = internal.CaseDef_CT - given ClassTag[Labeled] = internal.Labeled_CT - given ClassTag[Return] = internal.Return_CT - given ClassTag[WhileDo] = internal.WhileDo_CT - given ClassTag[Try] = internal.Try_CT - given ClassTag[SeqLiteral] = internal.SeqLiteral_CT - given ClassTag[Inlined] = internal.Inlined_CT - given ClassTag[Bind] = internal.Bind_CT - given ClassTag[Alternative] = internal.Alternative_CT - given ClassTag[UnApply] = internal.UnApply_CT - given ClassTag[Import] = internal.Import_CT - given ClassTag[PackageDef] = internal.PackageDef_CT - given ClassTag[TypeTree] = internal.TypeTree_CT - given ClassTag[SingletonTypeTree] = internal.SingletonTypeTree_CT - given ClassTag[RefinedTypeTree] = internal.RefinedTypeTree_CT - given ClassTag[AppliedTypeTree] = internal.AppliedTypeTree_CT - given ClassTag[MatchTypeTree] = internal.MatchTypeTree_CT - given ClassTag[ByNameTypeTree] = internal.ByNameTypeTree_CT - given ClassTag[Annotated] = internal.Annotated_CT - given ClassTag[LambdaTypeTree] = internal.LambdaTypeTree_CT - given ClassTag[TypeBoundsTree] = internal.TypeBoundsTree_CT - given ClassTag[Thicket] = internal.Thicket_CT + given ClassTag[tpd.Tree] = internal.Tree_CT + given ClassTag[tpd.MemberDef] = internal.MemberDef_CT + given ClassTag[tpd.Hole] = internal.Hole_CT + given ClassTag[tpd.Template] = internal.Template_CT + given ClassTag[tpd.ValOrDefDef] = internal.ValOrDefDef_CT + given ClassTag[tpd.TypeDef] = internal.TypeDef_CT + given ClassTag[tpd.ValDef] = internal.ValDef_CT + given ClassTag[tpd.DefDef] = internal.DefDef_CT + given ClassTag[tpd.Ident] = internal.Ident_CT + given ClassTag[tpd.This] = internal.This_CT + given ClassTag[tpd.Select] = internal.Select_CT + given ClassTag[tpd.Apply] = internal.Apply_CT + given ClassTag[tpd.TypeApply] = internal.TypeApply_CT + given ClassTag[tpd.Literal] = internal.Literal_CT + given ClassTag[tpd.Super] = internal.Super_CT + given ClassTag[tpd.New] = internal.New_CT + given ClassTag[tpd.Typed] = internal.Typed_CT + given ClassTag[tpd.NamedArg] = internal.NamedArg_CT + given ClassTag[tpd.Assign] = internal.Assign_CT + given ClassTag[tpd.Block] = internal.Block_CT + given ClassTag[tpd.If] = internal.If_CT + given ClassTag[tpd.Closure] = internal.Closure_CT + given ClassTag[tpd.Match] = internal.Match_CT + given ClassTag[tpd.CaseDef] = internal.CaseDef_CT + given ClassTag[tpd.Labeled] = internal.Labeled_CT + given ClassTag[tpd.Return] = internal.Return_CT + given ClassTag[tpd.WhileDo] = internal.WhileDo_CT + given ClassTag[tpd.Try] = internal.Try_CT + given ClassTag[tpd.SeqLiteral] = internal.SeqLiteral_CT + given ClassTag[tpd.Inlined] = internal.Inlined_CT + given ClassTag[tpd.Bind] = internal.Bind_CT + given ClassTag[tpd.Alternative] = internal.Alternative_CT + given ClassTag[tpd.UnApply] = internal.UnApply_CT + given ClassTag[tpd.Import] = internal.Import_CT + given ClassTag[tpd.PackageDef] = internal.PackageDef_CT + given ClassTag[tpd.TypeTree] = internal.TypeTree_CT + given ClassTag[tpd.SingletonTypeTree] = internal.SingletonTypeTree_CT + given ClassTag[tpd.RefinedTypeTree] = internal.RefinedTypeTree_CT + given ClassTag[tpd.AppliedTypeTree] = internal.AppliedTypeTree_CT + given ClassTag[tpd.MatchTypeTree] = internal.MatchTypeTree_CT + given ClassTag[tpd.ByNameTypeTree] = internal.ByNameTypeTree_CT + given ClassTag[tpd.Annotated] = internal.Annotated_CT + given ClassTag[tpd.LambdaTypeTree] = internal.LambdaTypeTree_CT + given ClassTag[tpd.TypeBoundsTree] = internal.TypeBoundsTree_CT + given ClassTag[tpd.Thicket] = internal.Thicket_CT given untpdTree: ClassTag[untpd.Tree] = internal.untpd_Tree_CT given untpdTypedSplice: ClassTag[untpd.TypedSplice] = internal.untpd_TypedSplice_CT given untpdMemberDef: ClassTag[untpd.MemberDef] = internal.untpd_MemberDef_CT given untpdIdent: ClassTag[untpd.Ident] = internal.untpd_Ident_CT + object tpd with + + type Tree = internal.Tree + type MemberDef = internal.MemberDef + type Hole = internal.Hole + type Template = internal.Template + type ValOrDefDef = internal.ValOrDefDef + type TypeDef = internal.TypeDef + type ValDef = internal.ValDef + type DefDef = internal.DefDef + type RefTree = internal.RefTree + type Ident = internal.Ident + type Select = internal.Select + type This = internal.This + type Apply = internal.Apply + type TypeApply = internal.TypeApply + type Literal = internal.Literal + type Super = internal.Super + type New = internal.New + type Typed = internal.Typed + type NamedArg = internal.NamedArg + type Assign = internal.Assign + type Block = internal.Block + type If = internal.If + type Closure = internal.Closure + type Match = internal.Match + type CaseDef = internal.CaseDef + type Labeled = internal.Labeled + type Return = internal.Return + type WhileDo = internal.WhileDo + type Try = internal.Try + type SeqLiteral = internal.SeqLiteral + type Inlined = internal.Inlined + type Bind = internal.Bind + type Alternative = internal.Alternative + type UnApply = internal.UnApply + type Import = internal.Import + type PackageDef = internal.PackageDef + type TypeTree = internal.TypeTree + type SingletonTypeTree = internal.SingletonTypeTree + type RefinedTypeTree = internal.RefinedTypeTree + type AppliedTypeTree = internal.AppliedTypeTree + type MatchTypeTree = internal.MatchTypeTree + type ByNameTypeTree = internal.ByNameTypeTree + type Annotated = internal.Annotated + type LambdaTypeTree = internal.LambdaTypeTree + type TypeBoundsTree = internal.TypeBoundsTree + type Thicket = internal.Thicket + + object Ident with + def unapply(tree: Ident): Some[Name] = internal.Ident_unapply(tree) + object This with + def unapply(tree: This): Some[untpd.Ident] = internal.This_unapply(tree) + object Select with + def unapply(tree: Select): (Tree, Name) = internal.Select_unapply(tree) + object Apply with + def unapply(tree: Apply): (Tree, List[Tree]) = internal.Apply_unapply(tree) + object TypeApply with + def unapply(tree: TypeApply): (Tree, List[Tree]) = internal.TypeApply_unapply(tree) + object Literal with + def unapply(tree: Literal): Some[Constant] = internal.Literal_unapply(tree) + object Super with + def unapply(tree: Super): (Tree, untpd.Ident) = internal.Super_unapply(tree) + object New with + def unapply(tree: New): Some[Tree] = internal.New_unapply(tree) + object Typed with + def unapply(tree: Typed): (Tree, Tree) = internal.Typed_unapply(tree) + object NamedArg with + def unapply(tree: NamedArg): (Name, Tree) = internal.NamedArg_unapply(tree) + object Assign with + def unapply(tree: Assign): (Tree, Tree) = internal.Assign_unapply(tree) + object Block with + def unapply(tree: Block): (List[Tree], Tree) = internal.Block_unapply(tree) + object If with + def unapply(tree: If): (Tree, Tree, Tree) = internal.If_unapply(tree) + object Closure with + def unapply(tree: Closure): (List[Tree], Tree, Tree) = internal.Closure_unapply(tree) + object Match with + def unapply(tree: Match): (Tree, List[CaseDef]) = internal.Match_unapply(tree) + object CaseDef with + def unapply(tree: CaseDef): (Tree, Tree, Tree) = internal.CaseDef_unapply(tree) + object Labeled with + def unapply(tree: Labeled): (Bind, Tree) = internal.Labeled_unapply(tree) + object Return with + def unapply(tree: Return): (Tree, Tree) = internal.Return_unapply(tree) + object WhileDo with + def unapply(tree: WhileDo): (Tree, Tree) = internal.WhileDo_unapply(tree) + object Try with + def unapply(tree: Try): (Tree, List[CaseDef], Tree) = internal.Try_unapply(tree) + object SeqLiteral with + def unapply(tree: SeqLiteral): (List[Tree], Tree) = internal.SeqLiteral_unapply(tree) + object Inlined with + def unapply(tree: Inlined): (Tree, List[MemberDef], Tree) = internal.Inlined_unapply(tree) + object Bind with + def unapply(tree: Bind): (Name, Tree) = internal.Bind_unapply(tree) + object Alternative with + def unapply(tree: Alternative): Some[List[Tree]] = internal.Alternative_unapply(tree) + object UnApply with + def unapply(tree: UnApply): (Tree, List[Tree], List[Tree]) = internal.UnApply_unapply(tree) + object Import with + def unapply(tree: Import): (Tree, List[untpd.ImportSelector]) = internal.Import_unapply(tree) + object PackageDef with + def unapply(tree: PackageDef): (RefTree, List[Tree]) = internal.PackageDef_unapply(tree) + object SingletonTypeTree with + def unapply(tree: SingletonTypeTree): Some[Tree] = internal.SingletonTypeTree_unapply(tree) + object RefinedTypeTree with + def unapply(tree: RefinedTypeTree): (Tree, List[Tree]) = internal.RefinedTypeTree_unapply(tree) + object AppliedTypeTree with + def unapply(tree: AppliedTypeTree): (Tree, List[Tree]) = internal.AppliedTypeTree_unapply(tree) + object MatchTypeTree with + def unapply(tree: MatchTypeTree): (Tree, Tree, List[CaseDef]) = internal.MatchTypeTree_unapply(tree) + object ByNameTypeTree with + def unapply(tree: ByNameTypeTree): Some[Tree] = internal.ByNameTypeTree_unapply(tree) + object Annotated with + def unapply(tree: Annotated): (Tree, Tree) = internal.Annotated_unapply(tree) + object LambdaTypeTree with + def unapply(tree: LambdaTypeTree): (List[TypeDef], Tree) = internal.LambdaTypeTree_unapply(tree) + object TypeBoundsTree with + def unapply(tree: TypeBoundsTree): (Tree, Tree) = internal.TypeBoundsTree_unapply(tree) + object Hole with + def unapply(tree: Hole): (Int, List[Tree]) = internal.Hole_unapply(tree) + object Thicket with + def unapply(tree: Thicket): Some[List[Tree]] = internal.Thicket_unapply(tree) + end tpd + object untpd with type Tree = internal.untpd_Tree @@ -65,7 +190,7 @@ trait TreeOps extends Core with type Ident = internal.untpd_Ident object TypedSplice with - def unapply(tree: TypedSplice): Some[self.Tree] = internal.untpd_TypedSplice_unapply(tree) + def unapply(tree: TypedSplice): Some[tpd.Tree] = internal.untpd_TypedSplice_unapply(tree) object Ident with def unapply(tree: Ident): Some[Name] = internal.untpd_Ident_unapply(tree) @@ -77,124 +202,51 @@ trait TreeOps extends Core with end untpd - object Ident with - def unapply(tree: Ident): Some[Name] = internal.Ident_unapply(tree) - object This with - def unapply(tree: This): Some[untpd.Ident] = internal.This_unapply(tree) - object Select with - def unapply(tree: Select): (Tree, Name) = internal.Select_unapply(tree) - object Apply with - def unapply(tree: Apply): (Tree, List[Tree]) = internal.Apply_unapply(tree) - object TypeApply with - def unapply(tree: TypeApply): (Tree, List[Tree]) = internal.TypeApply_unapply(tree) - object Literal with - def unapply(tree: Literal): Some[Constant] = internal.Literal_unapply(tree) - object Super with - def unapply(tree: Super): (Tree, untpd.Ident) = internal.Super_unapply(tree) - object New with - def unapply(tree: New): Some[Tree] = internal.New_unapply(tree) - object Typed with - def unapply(tree: Typed): (Tree, Tree) = internal.Typed_unapply(tree) - object NamedArg with - def unapply(tree: NamedArg): (Name, Tree) = internal.NamedArg_unapply(tree) - object Assign with - def unapply(tree: Assign): (Tree, Tree) = internal.Assign_unapply(tree) - object Block with - def unapply(tree: Block): (List[Tree], Tree) = internal.Block_unapply(tree) - object If with - def unapply(tree: If): (Tree, Tree, Tree) = internal.If_unapply(tree) - object Closure with - def unapply(tree: Closure): (List[Tree], Tree, Tree) = internal.Closure_unapply(tree) - object Match with - def unapply(tree: Match): (Tree, List[CaseDef]) = internal.Match_unapply(tree) - object CaseDef with - def unapply(tree: CaseDef): (Tree, Tree, Tree) = internal.CaseDef_unapply(tree) - object Labeled with - def unapply(tree: Labeled): (Bind, Tree) = internal.Labeled_unapply(tree) - object Return with - def unapply(tree: Return): (Tree, Tree) = internal.Return_unapply(tree) - object WhileDo with - def unapply(tree: WhileDo): (Tree, Tree) = internal.WhileDo_unapply(tree) - object Try with - def unapply(tree: Try): (Tree, List[CaseDef], Tree) = internal.Try_unapply(tree) - object SeqLiteral with - def unapply(tree: SeqLiteral): (List[Tree], Tree) = internal.SeqLiteral_unapply(tree) - object Inlined with - def unapply(tree: Inlined): (Tree, List[MemberDef], Tree) = internal.Inlined_unapply(tree) - object Bind with - def unapply(tree: Bind): (Name, Tree) = internal.Bind_unapply(tree) - object Alternative with - def unapply(tree: Alternative): Some[List[Tree]] = internal.Alternative_unapply(tree) - object UnApply with - def unapply(tree: UnApply): (Tree, List[Tree], List[Tree]) = internal.UnApply_unapply(tree) - object Import with - def unapply(tree: Import): (Tree, List[untpd.ImportSelector]) = internal.Import_unapply(tree) - object PackageDef with - def unapply(tree: PackageDef): (RefTree, List[Tree]) = internal.PackageDef_unapply(tree) - object SingletonTypeTree with - def unapply(tree: SingletonTypeTree): Some[Tree] = internal.SingletonTypeTree_unapply(tree) - object RefinedTypeTree with - def unapply(tree: RefinedTypeTree): (Tree, List[Tree]) = internal.RefinedTypeTree_unapply(tree) - object AppliedTypeTree with - def unapply(tree: AppliedTypeTree): (Tree, List[Tree]) = internal.AppliedTypeTree_unapply(tree) - object MatchTypeTree with - def unapply(tree: MatchTypeTree): (Tree, Tree, List[CaseDef]) = internal.MatchTypeTree_unapply(tree) - object ByNameTypeTree with - def unapply(tree: ByNameTypeTree): Some[Tree] = internal.ByNameTypeTree_unapply(tree) - object Annotated with - def unapply(tree: Annotated): (Tree, Tree) = internal.Annotated_unapply(tree) - object LambdaTypeTree with - def unapply(tree: LambdaTypeTree): (List[TypeDef], Tree) = internal.LambdaTypeTree_unapply(tree) - object TypeBoundsTree with - def unapply(tree: TypeBoundsTree): (Tree, Tree) = internal.TypeBoundsTree_unapply(tree) - object Hole with - def unapply(tree: Hole): (Int, List[Tree]) = internal.Hole_unapply(tree) - object Thicket with - def unapply(tree: Thicket): Some[List[Tree]] = internal.Thicket_unapply(tree) - given untpdTreeOps: (tree: untpd.Tree) with def symbol(given Context): Symbol = internal.untpd_Tree_symbol(tree) def span: Span = internal.untpd_Tree_span(tree) def source: SourceFile = internal.untpd_Tree_source(tree) def envelope(src: SourceFile, startSpan: Span = Span.noSpan): Span = internal.untpd_Tree_envelope(tree, src, startSpan) - def withType(tpe: Type)(given Context): Tree = internal.untpd_Tree_withType(tree, tpe) + def withType(tpe: Type)(given Context): tpd.Tree = internal.untpd_Tree_withType(tree, tpe) def isEmpty: Boolean = internal.untpd_Tree_isEmpty(tree) - given TreeOps: (tree: Tree) with + given TreeOps: (tree: tpd.Tree) with def isType: Boolean = internal.Tree_isType(tree) def tpe: Type = internal.Tree_tpe(tree) - given IfOps: (tree: If) with + given IfOps: (tree: tpd.If) with def isInline: Boolean = internal.If_isInline(tree) - given MatchOps: (tree: Match) with + given MatchOps: (tree: tpd.Match) with def isInline: Boolean = internal.Match_isInline(tree) - given ValOrDefDefOps: (tree: ValOrDefDef) with + given ValOrDefDefOps: (tree: tpd.ValOrDefDef) with def name: TermName = internal.ValOrDefDef_name(tree) - def tpt: Tree = internal.ValOrDefDef_tpt(tree) - def rhs(given Context): Tree = internal.ValOrDefDef_rhs(tree) + def tpt: tpd.Tree = internal.ValOrDefDef_tpt(tree) + def rhs(given Context): tpd.Tree = internal.ValOrDefDef_rhs(tree) - given DefDefOps: (tree: DefDef) with - def tparams: List[TypeDef] = internal.DefDef_tparams(tree) - def vparamss: List[List[ValDef]] = internal.DefDef_vparamss(tree) + given DefDefOps: (tree: tpd.DefDef) with + def tparams: List[tpd.TypeDef] = internal.DefDef_tparams(tree) + def vparamss: List[List[tpd.ValDef]] = internal.DefDef_vparamss(tree) - given TypeDefOps: (tree: TypeDef) with - def rhs: Tree = internal.TypeDef_rhs(tree) + given TypeDefOps: (tree: tpd.TypeDef) with + def rhs: tpd.Tree = internal.TypeDef_rhs(tree) - given TemplateOps: (tree: Template) with - def decomposeBody(given Context): (List[Tree], List[Tree]) = internal.Template_decomposeBody(tree) - def parents: List[Tree] = internal.Template_parents(tree) - def self: ValDef = internal.Template_self(tree) - def constr: DefDef = internal.Template_constr(tree) - def body(given Context): List[Tree] = internal.Template_body(tree) + given TemplateOps: (tree: tpd.Template) with + def decomposeBody(given Context): (List[tpd.Tree], List[tpd.Tree]) = internal.Template_decomposeBody(tree) + def parents: List[tpd.Tree] = internal.Template_parents(tree) + def self: tpd.ValDef = internal.Template_self(tree) + def constr: tpd.DefDef = internal.Template_constr(tree) + def body(given Context): List[tpd.Tree] = internal.Template_body(tree) def derived: List[untpd.Tree] = internal.Template_derived(tree) def emptyTree = internal.EmptyTree - def inlineContext(tree: Tree)(implicit ctx: Context): Context = internal.inlineContext(tree) + def inlineContext(tree: tpd.Tree)(implicit ctx: Context): Context = internal.inlineContext(tree) abstract class TreeAccumulator[X] { self => + import tpd._ + def apply(x: X, tree: Tree)(implicit ctx: Context): X def apply(x: X, trees: Traversable[Tree])(implicit ctx: Context): X = @@ -302,7 +354,7 @@ trait TreeOps extends Core with } abstract class TreeTraverser extends TreeAccumulator[Unit] { - def traverse(tree: Tree)(implicit ctx: Context): Unit - def apply(x: Unit, tree: Tree)(implicit ctx: Context): Unit = traverse(tree) - protected def traverseChildren(tree: Tree)(implicit ctx: Context): Unit = foldOver((), tree) + def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit + def apply(x: Unit, tree: tpd.Tree)(implicit ctx: Context): Unit = traverse(tree) + protected def traverseChildren(tree: tpd.Tree)(implicit ctx: Context): Unit = foldOver((), tree) } From ed2f6337c648468cb31393b18c0cc81911211335 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 2 Dec 2019 13:27:00 +0100 Subject: [PATCH 7/8] pass BootstrappedOnlyCompilationTests --- .../tools/dotc/core/tasty/experimental/CommentPickler.scala | 2 +- .../tools/dotc/core/tasty/experimental/TastyPickler.scala | 2 +- tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala index 297c23087959..47b4aee34606 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala @@ -6,5 +6,5 @@ import dotty.tools.dotc.core.Contexts.Context import dotty.tools.tasty.experimental.{CommentPickler => CommentPicklerImpl} import dotty.tools.tasty.TastyBuffer.Addr -class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr)(implicit ctx: Context) +class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr) extends CommentPicklerImpl(pickler, addrOfTree) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala index 11eb8caca463..9915c2a218e5 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/TastyPickler.scala @@ -4,4 +4,4 @@ import dotty.tools.dotc.core.Symbols.ClassSymbol import dotty.tools.tasty.experimental.{TastyPickler => TastyPicklerImpl} -class TastyPickler(rootCls: ClassSymbol) extends TastyPicklerImpl(DottyTasty)(rootCls) +class TastyPickler(rootCls: ClassSymbol) extends TastyPicklerImpl[DottyTasty.type](DottyTasty)(rootCls) diff --git a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala index 627237b1807f..fbec9603c7bf 100644 --- a/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala @@ -5,12 +5,12 @@ import TastyBuffer.{Addr, NoAddr} import java.nio.charset.Charset -class CommentPickler[T <: Tasty](val pickler: TastyPickler[T], addrOfTree: pickler.tasty.tpd.Tree => Addr)(implicit ctx: pickler.tasty.Context) { +class CommentPickler[T <: Tasty](val pickler: TastyPickler[T], addrOfTree: pickler.tasty.tpd.Tree => Addr) { import pickler.tasty.{_, given} private val buf = new TastyBuffer(5000) pickler.newSection("Comments", buf) - def pickleComment(root: tpd.Tree): Unit = { + def pickleComment(root: tpd.Tree)(implicit ctx: Context): Unit = { val docCtx = ctx.docCtx assert(docCtx.isDefined, "Trying to pickle comments, but there's no `docCtx`.") new Traverser(docCtx.get).traverse(root) From e2824b0d43df8095c2973809f1b85782ee6994b7 Mon Sep 17 00:00:00 2001 From: bishabosha Date: Thu, 2 Jan 2020 11:48:03 +0000 Subject: [PATCH 8/8] Update extension method syntax --- community-build/community-projects/ScalaPB | 2 +- community-build/community-projects/fastparse | 2 +- community-build/community-projects/os-lib | 2 +- community-build/community-projects/scalacheck | 2 +- community-build/community-projects/shapeless | 1 + community-build/community-projects/sourcecode | 2 +- community-build/community-projects/utest | 2 +- .../community-projects/xml-interpolator | 2 +- .../experimental/bridge/AnnotationOps.scala | 2 +- .../experimental/bridge/CommentOps.scala | 2 +- .../experimental/bridge/ConstantOps.scala | 2 +- .../experimental/bridge/ContextOps.scala | 4 +- .../tasty/experimental/bridge/FlagOps.scala | 2 +- .../tasty/experimental/bridge/NameOps.scala | 6 +-- .../experimental/bridge/PositionOps.scala | 6 +-- .../experimental/bridge/SignatureOps.scala | 4 +- .../experimental/bridge/SourceFileOps.scala | 2 +- .../tasty/experimental/bridge/StringOps.scala | 4 +- .../tasty/experimental/bridge/SymbolOps.scala | 10 +++-- .../tasty/experimental/bridge/TreeOps.scala | 18 ++++----- .../tasty/experimental/bridge/TypeOps.scala | 38 +++++++++---------- 21 files changed, 60 insertions(+), 55 deletions(-) create mode 160000 community-build/community-projects/shapeless diff --git a/community-build/community-projects/ScalaPB b/community-build/community-projects/ScalaPB index 2b2af046cc98..984eba1d17a9 160000 --- a/community-build/community-projects/ScalaPB +++ b/community-build/community-projects/ScalaPB @@ -1 +1 @@ -Subproject commit 2b2af046cc98c5fe440777f2b8258280919a5079 +Subproject commit 984eba1d17a9371e166fd76f89880590d8f5bfa5 diff --git a/community-build/community-projects/fastparse b/community-build/community-projects/fastparse index 2b26ee9a89af..c49998f74aa0 160000 --- a/community-build/community-projects/fastparse +++ b/community-build/community-projects/fastparse @@ -1 +1 @@ -Subproject commit 2b26ee9a89af1c033f9c6b6d731cee440adb342b +Subproject commit c49998f74aa05f27720eab974f25c3ee780f3549 diff --git a/community-build/community-projects/os-lib b/community-build/community-projects/os-lib index b29d68ffee5a..9cb5d0eb4bf2 160000 --- a/community-build/community-projects/os-lib +++ b/community-build/community-projects/os-lib @@ -1 +1 @@ -Subproject commit b29d68ffee5a6e0aedbfdd048d10059f250134e4 +Subproject commit 9cb5d0eb4bf20a5b4ef86a7bf55cc896719f887e diff --git a/community-build/community-projects/scalacheck b/community-build/community-projects/scalacheck index 371113633e8b..9c5fc6e36970 160000 --- a/community-build/community-projects/scalacheck +++ b/community-build/community-projects/scalacheck @@ -1 +1 @@ -Subproject commit 371113633e8b0ee140a4addb66526ae0e71e7118 +Subproject commit 9c5fc6e36970c704fb431f56eaaf4a3fea4b1f9c diff --git a/community-build/community-projects/shapeless b/community-build/community-projects/shapeless new file mode 160000 index 000000000000..63c5e0a4c57e --- /dev/null +++ b/community-build/community-projects/shapeless @@ -0,0 +1 @@ +Subproject commit 63c5e0a4c57efbaf17699144b627db1639800e90 diff --git a/community-build/community-projects/sourcecode b/community-build/community-projects/sourcecode index 49c20bd80cb6..db11447fd045 160000 --- a/community-build/community-projects/sourcecode +++ b/community-build/community-projects/sourcecode @@ -1 +1 @@ -Subproject commit 49c20bd80cb61a53c0b11e80b9946bbe513a4c0f +Subproject commit db11447fd045125b84a69832b2b6c5f9cd3290de diff --git a/community-build/community-projects/utest b/community-build/community-projects/utest index 4953683a23fe..7eac23c8aad1 160000 --- a/community-build/community-projects/utest +++ b/community-build/community-projects/utest @@ -1 +1 @@ -Subproject commit 4953683a23fe8f60f8f25f061a7b3095f8ddbeac +Subproject commit 7eac23c8aad186c724ddaee4d00030fbacb8a969 diff --git a/community-build/community-projects/xml-interpolator b/community-build/community-projects/xml-interpolator index 435d9e076531..f3185019a161 160000 --- a/community-build/community-projects/xml-interpolator +++ b/community-build/community-projects/xml-interpolator @@ -1 +1 @@ -Subproject commit 435d9e076531555ebc5bac8f196645a157bc6c11 +Subproject commit f3185019a16182a2fba20523ccfff6665436424a diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala index 30405781ee87..b2181d12e93b 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala @@ -13,6 +13,6 @@ trait AnnotationOps extends Core with def unapply(annot: Annotation)(given Context): Option[Symbol] = internal.Annotation_Child_unapply(annot) - given AnnotationOps: (annot: Annotation) with + given AnnotationOps: (annot: Annotation) extended with def tree(given Context): tpd.Tree = internal.Annotation_tree(annot) def symbol(given Context): Symbol = internal.Annotation_symbol(annot) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala index b9ffc735e095..711b31235ead 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/CommentOps.scala @@ -4,6 +4,6 @@ import reflect.ClassTag trait CommentOps extends Core with - given CommentOps: (comment: Comment) with + given CommentOps: (comment: Comment) extended with def raw: String = internal.Comment_raw(comment) def span: Span = internal.Comment_span(comment) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala index 285034c03c9c..ffbb4b634e17 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala @@ -21,7 +21,7 @@ trait ConstantOps extends Core with final val EnumTag = internal.Constants_EnumTag end Constants - given ConstantOps: (c: Constant) with + given ConstantOps: (c: Constant) extended with def tag: Int = internal.Constant_tag(c) def intValue: Int = internal.Constant_intValue(c) def booleanValue: Boolean = internal.Constant_booleanValue(c) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala index 847cda248f4f..ce3441bcdcbc 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala @@ -5,12 +5,12 @@ import java.nio.file.Path trait ContextOps extends Core with - given ContextOps: (ctx: Context) with + given ContextOps: (ctx: Context) extended with def log(msg: => String, sourcePos: SourcePosition): Unit = internal.Context_log(ctx, msg, sourcePos) def source: SourceFile = internal.Context_source(ctx) def docCtx: Option[ContextDocstrings] = internal.Context_docCtx(ctx) def withOwner(owner: Symbol): Context = internal.Context_withOwner(ctx, owner) def withSource(source: SourceFile): Context = internal.Context_withSource(ctx, source) - given ContextDocstringsOps: (ctx: ContextDocstrings) with + given ContextDocstringsOps: (ctx: ContextDocstrings) extended with def docstring(sym: Symbol): Option[Comment] = internal.ContextDocstrings_docstring(ctx, sym) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala index de33b0108765..362147274b12 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala @@ -43,7 +43,7 @@ trait FlagOps extends Core with val Open: Flag = internal.Flags_Open end Flags - given FlagSetOps: (flags: FlagSet) + given FlagSetOps: (flags: FlagSet) extended with def is(flag: Flag): Boolean = internal.FlagSet_is(flags, flag) def is(flag: Flag, butNot: FlagSet): Boolean = internal.FlagSet_is(flags, flag, butNot) def &~(flag: Flag): FlagSet = internal.FlagSet_&~(flags, flag) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala index c9cd38e41cdb..f104351df8b6 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala @@ -35,14 +35,14 @@ trait NameOps extends Core with def unapply(name: DerivedName): Option[(TermName, Int)] = internal.OuterSelectName_unapply(name) - given NameOps: (name: Name) with + given NameOps: (name: Name) extended with def toTermName: TermName = internal.Name_toTermName(name) def isEmpty: Boolean = internal.Name_isEmpty(name) def isTypeName: Boolean = internal.Name_isTypeName(name) def isTermName: Boolean = !name.isTypeName - given TermNameOps: (name: TermName) with + given TermNameOps: (name: TermName) extended with def tag: Int = internal.TermName_tag(name) - given SimpleNameOps: (name: SimpleName) with + given SimpleNameOps: (name: SimpleName) extended with def toUTF8: Array[Byte] = internal.SimpleName_toUTF8(name) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala index 1ea4aae5db50..c2cccaae3d59 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala @@ -4,20 +4,20 @@ import reflect.ClassTag trait PositionOps extends Core with - given PositionedOps: (positioned: Positioned) with + given PositionedOps: (positioned: Positioned) extended with /** True if x's position shouldn't be reconstructed automatically from its initial span */ def alwaysNeedsPos: Boolean = internal.Positioned_alwaysNeedsPos(positioned) - given SourcePositionOps: (pos: SourcePosition) with + given SourcePositionOps: (pos: SourcePosition) extended with def line: Int = internal.SourcePosition_line(pos) object Span with val empty: Span = internal.Span_empty val noSpan: Span = internal.Span_noSpan - given SpanOps: (span: Span) with + given SpanOps: (span: Span) extended with def coords: Long = internal.Span_coords(span) def isSynthetic: Boolean = internal.Span_isSynthetic(span) def toSynthetic: Span = internal.Span_toSynthetic(span) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala index 76657950287d..d781c535703c 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SignatureOps.scala @@ -14,11 +14,11 @@ trait SignatureOps extends Core with def unapply(signature: Signature): (List[ParamSig], TypeName) = internal.Signature_unapply(signature) - given ParamSigOps: (paramSig: ParamSig) with + given ParamSigOps: (paramSig: ParamSig) extended with def fold[A](onInt: Int => A, onTypeName: TypeName => A): A = internal.Signature_ParamSig_fold(paramSig)(onInt, onTypeName) def foldInt(onInt: IntToInt, onTypeName: ToInt[TypeName]): Int = internal.Signature_ParamSig_foldInt(paramSig)(onInt, onTypeName) end Signature - given SignatureOps: (signature: Signature) with + given SignatureOps: (signature: Signature) extended with def isNotAMethod: Boolean = internal.Signature_isNotAMethod(signature) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala index 5eaa9c38ad43..b18e591ea69c 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SourceFileOps.scala @@ -7,6 +7,6 @@ trait SourceFileOps extends Core with object SourceFile with val noSource: SourceFile = internal.SourceFile_noSource - given SourceFileOps: (source: SourceFile) with + given SourceFileOps: (source: SourceFile) extended with def path: String = internal.SourceFile_path(source) def exists: Boolean = internal.SourceFile_exists(source) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala index 4292cf8d03de..d57b1e10560d 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/StringOps.scala @@ -4,8 +4,8 @@ import reflect.ClassTag trait StringOps extends Core with - given StringOps: (string: String) with + given StringOps: (string: String) extended with def toTermName: TermName = internal.String_toTermName(string) - given StringContextOps: (stringContext: StringContext) with + given StringContextOps: (stringContext: StringContext) extended with def i(args: => Any*)(given Context): String = internal.StringContext_i(stringContext, args) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala index 00d0d5bc7056..8be5a01b660d 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala @@ -17,9 +17,8 @@ trait SymbolOps extends Core with def newMutableSymbolMap[T]: MutableSymbolMap[T] = internal.Symbols_newMutableSymbolMap[T] - given MutableSymbolMapOps: [T](map: Symbols.MutableSymbolMap[T]) with + given MutableSymbolMapOps: [T](map: Symbols.MutableSymbolMap[T]) extended with def get(sym: Symbol): Option[T] = internal.Symbols_MutableSymbolMap_get(map, sym) - def getOrElse[U >: T](sym: Symbol, default: => U): U = internal.Symbols_MutableSymbolMap_getOrElse(map, sym, default) def contains(sym: Symbol): Boolean = internal.Symbols_MutableSymbolMap_contains(map, sym) def update(sym: Symbol, value: T): Unit = internal.Symbols_MutableSymbolMap_update(map, sym, value) def -=(sym: Symbol): Unit = internal.Symbols_MutableSymbolMap_-=(map, sym) @@ -28,9 +27,14 @@ trait SymbolOps extends Core with def keysIterator: Iterator[Symbol] = internal.Symbols_MutableSymbolMap_keysIterator(map) end MutableSymbolMapOps + given MutableSymbolMapOpsPlus: AnyRef with + def [T, U >: T](map: Symbols.MutableSymbolMap[T]) getOrElse(sym: Symbol, default: => U): U = + internal.Symbols_MutableSymbolMap_getOrElse(map, sym, default) + end MutableSymbolMapOpsPlus + end Symbols - given SymbolOps: (sym: Symbol) with + given SymbolOps: (sym: Symbol) extended with def isPackage(given Context): Boolean = internal.Symbol_isPackage(sym) def isPrivate(given Context): Boolean = internal.Symbol_isPrivate(sym) def sourcePos(given Context): SourcePosition = internal.Symbol_sourcePos(sym) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala index b587b7e42965..9dcae34b504f 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala @@ -195,14 +195,14 @@ trait TreeOps extends Core with object Ident with def unapply(tree: Ident): Some[Name] = internal.untpd_Ident_unapply(tree) - given ImportSelectorOps: (tree: ImportSelector) with + given ImportSelectorOps: (tree: ImportSelector) extended with def imported: Ident = internal.ImportSelector_imported(tree) def renamed: Tree = internal.ImportSelector_renamed(tree) def bound: Tree = internal.ImportSelector_bound(tree) end untpd - given untpdTreeOps: (tree: untpd.Tree) with + given untpdTreeOps: (tree: untpd.Tree) extended with def symbol(given Context): Symbol = internal.untpd_Tree_symbol(tree) def span: Span = internal.untpd_Tree_span(tree) def source: SourceFile = internal.untpd_Tree_source(tree) @@ -210,29 +210,29 @@ trait TreeOps extends Core with def withType(tpe: Type)(given Context): tpd.Tree = internal.untpd_Tree_withType(tree, tpe) def isEmpty: Boolean = internal.untpd_Tree_isEmpty(tree) - given TreeOps: (tree: tpd.Tree) with + given TreeOps: (tree: tpd.Tree) extended with def isType: Boolean = internal.Tree_isType(tree) def tpe: Type = internal.Tree_tpe(tree) - given IfOps: (tree: tpd.If) with + given IfOps: (tree: tpd.If) extended with def isInline: Boolean = internal.If_isInline(tree) - given MatchOps: (tree: tpd.Match) with + given MatchOps: (tree: tpd.Match) extended with def isInline: Boolean = internal.Match_isInline(tree) - given ValOrDefDefOps: (tree: tpd.ValOrDefDef) with + given ValOrDefDefOps: (tree: tpd.ValOrDefDef) extended with def name: TermName = internal.ValOrDefDef_name(tree) def tpt: tpd.Tree = internal.ValOrDefDef_tpt(tree) def rhs(given Context): tpd.Tree = internal.ValOrDefDef_rhs(tree) - given DefDefOps: (tree: tpd.DefDef) with + given DefDefOps: (tree: tpd.DefDef) extended with def tparams: List[tpd.TypeDef] = internal.DefDef_tparams(tree) def vparamss: List[List[tpd.ValDef]] = internal.DefDef_vparamss(tree) - given TypeDefOps: (tree: tpd.TypeDef) with + given TypeDefOps: (tree: tpd.TypeDef) extended with def rhs: tpd.Tree = internal.TypeDef_rhs(tree) - given TemplateOps: (tree: tpd.Template) with + given TemplateOps: (tree: tpd.Template) extended with def decomposeBody(given Context): (List[tpd.Tree], List[tpd.Tree]) = internal.Template_decomposeBody(tree) def parents: List[tpd.Tree] = internal.Template_parents(tree) def self: tpd.ValDef = internal.Template_self(tree) diff --git a/tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala index ffb0c73c11fb..15b73a294365 100644 --- a/tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TypeOps.scala @@ -33,7 +33,7 @@ trait TypeOps extends Core with object AppliedType with def unapply(tpe: AppliedType): (Type, List[Type]) = internal.AppliedType_unapply(tpe) - given TypeOps: (tpe: Type) with + given TypeOps: (tpe: Type) extended with def stripTypeVar(given Context): Type = internal.Type_stripTypeVar(tpe) def signature(given Context): Signature = internal.Type_signature(tpe) def member(name: Name)(given Context): Symbol = internal.Type_member(tpe, name) @@ -42,71 +42,71 @@ trait TypeOps extends Core with def isErasedMethod: Boolean = internal.Type_isErasedMethod(tpe) def exists: Boolean = internal.Type_exists(tpe) - given ConstantTypeOps: (tpe: ConstantType) with + given ConstantTypeOps: (tpe: ConstantType) extended with def value: Constant = internal.ConstantType_value(tpe) - given SuperTypeOps: (tpe: SuperType) with + given SuperTypeOps: (tpe: SuperType) extended with def thistpe: Type = internal.SuperType_thistpe(tpe) def supertpe: Type = internal.SuperType_supertpe(tpe) - given ThisTypeOps: (tpe: ThisType) with + given ThisTypeOps: (tpe: ThisType) extended with def cls(given Context): ClassSymbol = internal.ThisType_cls(tpe) def tref: TypeRef = internal.ThisType_tref(tpe) - given SkolemTypeOps: (tpe: SkolemType) with + given SkolemTypeOps: (tpe: SkolemType) extended with def info: Type = internal.SkolemType_info(tpe) - given BoundTypeOps: (tpe: BoundType) with + given BoundTypeOps: (tpe: BoundType) extended with def binder: tpe.BT = internal.BoundType_binder(tpe) - given ParamRefOps: (tpe: ParamRef) with + given ParamRefOps: (tpe: ParamRef) extended with def paramNum: Int = internal.ParamRef_paramNum(tpe) - given RecTypeOps: (tpe: RecType) with + given RecTypeOps: (tpe: RecType) extended with def parent: Type = internal.RecType_parent(tpe) - given RefinedTypeOps: (tpe: RefinedType) with + given RefinedTypeOps: (tpe: RefinedType) extended with def parent: Type = internal.RefinedType_parent(tpe) def refinedInfo: Type = internal.RefinedType_refinedInfo(tpe) def refinedName: Name = internal.RefinedType_refinedName(tpe) - given TypeBoundsOps: (tpe: TypeBounds) with + given TypeBoundsOps: (tpe: TypeBounds) extended with def hi: Type = internal.TypeBounds_hi(tpe) def lo: Type = internal.TypeBounds_lo(tpe) - given TypeAliasOps: (tpe: TypeAlias) with + given TypeAliasOps: (tpe: TypeAlias) extended with def alias: Type = internal.TypeAlias_alias(tpe) - given NamedTypeOps: (tpe: NamedType) with + given NamedTypeOps: (tpe: NamedType) extended with def symbol(given Context): Symbol = internal.NamedType_symbol(tpe) def prefix: Type = internal.NamedType_prefix(tpe) def designator: Designator = internal.NamedType_designator(tpe) def hasNoPrefix: Boolean = internal.NamedType_hasNoPrefix(tpe) def isType: Boolean = internal.NamedType_isType(tpe) - given AnnotatedTypeOps: (tpe: AnnotatedType) with + given AnnotatedTypeOps: (tpe: AnnotatedType) extended with def parent: Type = internal.AnnotatedType_parent(tpe) def annot: Annotation = internal.AnnotatedType_annot(tpe) - given AndOrTypeOps: (tpe: AndOrType) with + given AndOrTypeOps: (tpe: AndOrType) extended with def tp1: Type = internal.AndOrType_tp1(tpe) def tp2: Type = internal.AndOrType_tp2(tpe) - given TypeProxyOps: (tpe: TypeProxy) with + given TypeProxyOps: (tpe: TypeProxy) extended with def underlying(given Context): Type = internal.TypeProxy_underlying(tpe) - given MatchTypeOps: (tpe: MatchType) with + given MatchTypeOps: (tpe: MatchType) extended with def bound: Type = internal.MatchType_bound(tpe) def scrutinee: Type = internal.MatchType_scrutinee(tpe) def cases: List[Type] = internal.MatchType_cases(tpe) - given LambdaTypeOps: (tpe: LambdaType) with + given LambdaTypeOps: (tpe: LambdaType) extended with def resultType(given Context): Type = internal.LambdaType_resultType(tpe) def paramNames: List[tpe.ThisName] = internal.LambdaType_paramNames(tpe) def paramInfos: List[tpe.PInfo] = internal.LambdaType_paramInfos(tpe) - given LazyRefOps: (tpe: LazyRef) with + given LazyRefOps: (tpe: LazyRef) extended with def ref(given Context): Type = internal.LazyRef_ref(tpe) - given ClassInfoOps: (tpe: ClassInfo) with + given ClassInfoOps: (tpe: ClassInfo) extended with def selfInfo: Either[Type, Symbol] = internal.ClassInfo_selfInfo(tpe)