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/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 73dc082bfe00..d731ed5ac0ff 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -12,7 +12,8 @@ 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.TastyPrinter +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} 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/core/tasty/experimental/CommentPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/CommentPickler.scala new file mode 100644 index 000000000000..47b4aee34606 --- /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.{CommentPickler => CommentPicklerImpl} +import dotty.tools.tasty.TastyBuffer.Addr + +class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr) + extends CommentPicklerImpl(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 new file mode 100644 index 000000000000..8aa702658b66 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/tasty/experimental/DottyKernel.scala @@ -0,0 +1,810 @@ +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} + +import annotation.internal.sharable + +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 + @sharable val SourceFile_noSource: SourceFile = util.NoSource + + def SourcePosition_line(pos: SourcePosition): Int = pos.line + + @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 + 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 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 + @sharable 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 == 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] = + 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._ + 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) + + @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 { + 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/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/core/tasty/experimental/PositionPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/experimental/PositionPickler.scala new file mode 100644 index 000000000000..b2e2a06f8057 --- /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.{PositionPickler => PositionPicklerImpl} +import dotty.tools.tasty.TastyBuffer.Addr + +class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) + extends PositionPicklerImpl(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..9915c2a218e5 --- /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.type](DottyTasty)(rootCls) diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index d536acd76f56..fa946f14a574 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,10 @@ import Flags.Module import reporting.ThrowingReporter import collection.mutable +import dotty.tools.dotc.core.tasty.experimental.{DottyTasty, PositionPickler, CommentPickler, TastyPickler} + +import dotty.tools.dotc.core.tasty.{TastyPrinter, DottyUnpickler} + object Pickler { val name: String = "pickler" } 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/compiler/src/dotty/tools/dotc/core/tasty/CommentPickler.scala b/tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala similarity index 61% rename from compiler/src/dotty/tools/dotc/core/tasty/CommentPickler.scala rename to tasty/src/dotty/tools/tasty/experimental/CommentPickler.scala index 1b57588f45a8..fbec9603c7bf 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[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 = { - assert(ctx.docCtx.isDefined, "Trying to pickle comments, but there's no `docCtx`.") - new Traverser(ctx.docCtx.get).traverse(root) + 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) } def pickleComment(addr: Addr, comment: Option[Comment]): Unit = comment match { @@ -30,7 +28,7 @@ class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr)(implic () } - private class Traverser(docCtx: ContextDocstrings) extends tpd.TreeTraverser { + private class Traverser(docCtx: ContextDocstrings) extends TreeTraverser { override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match { case md: tpd.MemberDef => diff --git a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala similarity index 79% rename from compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala rename to tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala index 63b724b051f8..9519aaf3da2c 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala +++ b/tasty/src/dotty/tools/tasty/experimental/NameBuffer.scala @@ -1,18 +1,14 @@ -package dotty.tools -package dotc -package core -package tasty - -import dotty.tools.tasty.TastyBuffer -import TastyBuffer._ +package dotty.tools.tasty.experimental import collection.mutable -import Names.{Name, chrs, SimpleName, DerivedName, TypeName} -import NameKinds._ -import Decorators._ + +import dotty.tools.tasty._ + +import TastyBuffer._ import scala.io.Codec -class NameBuffer extends TastyBuffer(10000) { +class NameBuffer[T <: Tasty](given val tasty: T) extends TastyBuffer(10000) { + import tasty.{_, given} import NameBuffer._ private val nameRefs = new mutable.LinkedHashMap[Name, NameRef] @@ -37,7 +33,7 @@ class NameBuffer extends TastyBuffer(10000) { case AnyUniqueName(original, separator, num) => nameIndex(separator.toTermName) if (!original.isEmpty) nameIndex(original) - case DerivedName(original, _) => + case DerivedName(original) => nameIndex(original) case _ => } @@ -58,24 +54,20 @@ class NameBuffer extends TastyBuffer(10000) { 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 - } + 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.info.kind.tag + val tag = name.toTermName.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) + val bytes = name.toUTF8 writeNat(bytes.length) writeBytes(bytes, bytes.length) case AnyQualifiedName(prefix, name) => @@ -92,7 +84,7 @@ class NameBuffer extends TastyBuffer(10000) { withLength( { writeNameRef(original); writeNameRef(result); paramsSig.foreach(writeParamSig) }, if ((paramsSig.length + 2) * maxIndexWidth <= maxNumInByte) 1 else 2) - case DerivedName(original, _) => + case DerivedName(original) => withLength { writeNameRef(original) } } } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala b/tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala similarity index 62% rename from compiler/src/dotty/tools/dotc/core/tasty/PositionPickler.scala rename to tasty/src/dotty/tools/tasty/experimental/PositionPickler.scala index 8a7095b21dd3..7c1bed5b8431 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[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) - import ast.tpd._ private val pickledIndices = new mutable.BitSet @@ -28,9 +18,9 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Addr) { (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(0, 0) + var lastSpan = Span.empty def pickleDeltas(index: Int, span: Span) = { val addrDelta = index - lastIndex val startDelta = span.start - lastSpan.start @@ -50,27 +40,6 @@ 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[?] - - // 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) { @@ -84,12 +53,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 +75,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 new file mode 100644 index 000000000000..45f14a78038b --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/Tasty.scala @@ -0,0 +1,20 @@ +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 + with SourceFileOps + with CommentOps diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala similarity index 82% rename from compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala rename to tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala index 3ae6cb79510d..77e355686c43 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TastyPickler.scala @@ -1,22 +1,17 @@ -package dotty.tools -package dotc -package core -package tasty +package dotty.tools.tasty.experimental -import dotty.tools.tasty.{TastyBuffer, TastyFormat, TastyHash} +import collection.mutable + +import dotty.tools.tasty.{TastyFormat, TastyBuffer, TastyHash} import TastyFormat._ import TastyBuffer._ -import collection.mutable -import core.Symbols.{Symbol, ClassSymbol} -import ast.tpd -import Decorators._ - -class TastyPickler(val rootCls: ClassSymbol) { +class TastyPickler[T <: Tasty](val tasty: T)(val rootCls: tasty.ClassSymbol) { self => + import tasty.{_, given} - private val sections = new mutable.ArrayBuffer[(NameRef, TastyBuffer)] + private val sections = mutable.ArrayBuffer.empty[(NameRef, TastyBuffer)] - val nameBuffer: NameBuffer = new NameBuffer + val nameBuffer = NameBuffer[tasty.type](given tasty) def newSection(name: String, buf: TastyBuffer): Unit = sections += ((nameBuffer.nameIndex(name.toTermName), buf)) @@ -38,7 +33,7 @@ class TastyPickler(val rootCls: ClassSymbol) { val headerBuffer = { val buf = new TastyBuffer(header.length + 24) - for (ch <- header) buf.writeByte(ch.toByte) + for (ch <- header) buf.writeByte(ch.toByte.toInt) buf.writeNat(MajorVersion) buf.writeNat(MinorVersion) buf.writeUncompressedLong(uuidLow) @@ -78,5 +73,5 @@ class TastyPickler(val rootCls: ClassSymbol) { */ var addrOfSym: Symbol => Option[Addr] = (_ => None) - val treePkl: TreePickler = new TreePickler(this) + val treePkl = new TreePickler(self) } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala similarity index 92% rename from compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala rename to tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala index 345dde2aad75..fca732ecb715 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala +++ b/tasty/src/dotty/tools/tasty/experimental/TreeBuffer.scala @@ -1,17 +1,14 @@ -package dotty.tools -package dotc -package core -package tasty +package dotty.tools.tasty.experimental 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) { +class TreeBuffer[T <: Tasty](val tasty: T) extends TastyBuffer(50000) { + import tasty.{_, given} + import Printers.pickling private final val ItemsOverOffsets = 2 private val initialOffsetSize = bytes.length / (AddrWidth * ItemsOverOffsets) @@ -21,14 +18,14 @@ class TreeBuffer extends TastyBuffer(50000) { 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 + private val treeAddrs = new java.util.IdentityHashMap[untpd.Tree, Addr | Null] - def registerTreeAddr(tree: Tree): Addr = treeAddrs.get(tree) match { + 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 { + def addrOfTree(tree: untpd.Tree): Addr = treeAddrs.get(tree) match { case null => NoAddr case addr: Addr => addr } @@ -162,6 +159,7 @@ class TreeBuffer extends TastyBuffer(50000) { val tree = it.next treeAddrs.get(tree) match { case addr: Addr => treeAddrs.put(tree, adjusted(addr)) + case null => () } } } 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..1f655f0f323e --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/TreePickler.scala @@ -0,0 +1,716 @@ +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[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]] + 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: untpd.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) + val untpd.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..b2181d12e93b --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/AnnotationOps.scala @@ -0,0 +1,18 @@ +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 + + object Annotation with + + object Child with + + def unapply(annot: Annotation)(given Context): Option[Symbol] = internal.Annotation_Child_unapply(annot) + + 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 new file mode 100644 index 000000000000..711b31235ead --- /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) 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 new file mode 100644 index 000000000000..ffbb4b634e17 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ConstantOps.scala @@ -0,0 +1,37 @@ +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 + end Constants + + 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) + 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) + end ConstantOps 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..ce3441bcdcbc --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/ContextOps.scala @@ -0,0 +1,16 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag +import java.nio.file.Path + +trait ContextOps extends Core 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) extended 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 new file mode 100644 index 000000000000..a8c1ac301702 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/Core.scala @@ -0,0 +1,70 @@ +package dotty.tools.tasty.experimental.bridge + +trait Core with + + private[tasty] val internal: TastyKernel + + type Context = internal.Context + + type SourceFile = internal.SourceFile + + 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 Positioned = internal.Positioned + + 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 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/FlagOps.scala b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala new file mode 100644 index 000000000000..362147274b12 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/FlagOps.scala @@ -0,0 +1,49 @@ +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) 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 new file mode 100644 index 000000000000..f104351df8b6 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/NameOps.scala @@ -0,0 +1,48 @@ +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) 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) extended with + def tag: Int = internal.TermName_tag(name) + + 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 new file mode 100644 index 000000000000..c2cccaae3d59 --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/PositionOps.scala @@ -0,0 +1,27 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait PositionOps extends Core 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) 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) extended 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/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..d781c535703c --- /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) 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) 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 new file mode 100644 index 000000000000..b18e591ea69c --- /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) 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 new file mode 100644 index 000000000000..d57b1e10560d --- /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) extended with + def toTermName: TermName = internal.String_toTermName(string) + + 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 new file mode 100644 index 000000000000..8be5a01b660d --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/SymbolOps.scala @@ -0,0 +1,59 @@ +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]) extended with + def get(sym: Symbol): Option[T] = internal.Symbols_MutableSymbolMap_get(map, sym) + 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 + + 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) 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) + 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): 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) + 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(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] + 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..d4fc85c415af --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TastyKernel.scala @@ -0,0 +1,523 @@ +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 SourceFile <: AnyRef + + type Designator <: AnyRef + + type Annotation <: AnyRef + def Annotation_CT: ClassTag[Annotation] + + type Name <: Designator + type SimpleName <: TermName + type DerivedName <: TermName + type TypeName <: Name + type TermName <: Name + + 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 + + def Signature_CT: ClassTag[Signature] + + type Signature_ParamSig = Int | TypeName + + 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 untpd_Ident <: untpd_Tree + + type Tree <: untpd_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 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 with DefTree with PatternTree + 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] + type Thicket <: Tree + + 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 + 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 + + 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 } + type TypeSymbol <: Symbol { type ThisName = TypeName } + type ClassSymbol <: TypeSymbol + + type FlagSet + type Flag <: FlagSet + + def Symbol_CT: ClassTag[Symbol] + def ClassSymbol_CT: ClassTag[ClassSymbol] + + type Symbols_MutableSymbolMap[T] + + type SourcePosition <: AnyRef + type Span <: AnyVal + + type ContextDocstrings <: AnyRef + + type Comment <: AnyRef + + type Constant <: AnyRef + + 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 + 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): 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 + 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)(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): Name + def Symbol_isClass(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 + 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 SourceFile_path(source: SourceFile): String + def SourceFile_exists(source: SourceFile): Boolean + def SourceFile_noSource: SourceFile + + def SourcePosition_line(pos: SourcePosition): Int + + 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 + 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 + + def Name_toTermName(name: Name): TermName + def Name_isEmpty(name: Name): Boolean + def Name_isTypeName(name: Name): Boolean + + 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 untpd_Tree_withType(tree: untpd_Tree, tpe: Type)(given Context): Tree + def untpd_Tree_isEmpty(tree: untpd_Tree): Boolean + + def Tree_isType(tree: Tree): Boolean + def Tree_tpe(tree: Tree): Type + def EmptyTree: Tree + + def If_isInline(tree: If): Boolean + def Match_isInline(tree: Match): Boolean + + def inlineContext(tree: Tree)(implicit ctx: Context): Context + + 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[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, untpd_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 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) + 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 Thicket_unapply(tree: Thicket): Some[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): 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)(given Context): List[Tree] + def Template_derived(tree: Template): List[untpd_Tree] + 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: NamedType): 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] + + 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 + 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*)(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 new file mode 100644 index 000000000000..9dcae34b504f --- /dev/null +++ b/tasty/src/dotty/tools/tasty/experimental/bridge/TreeOps.scala @@ -0,0 +1,360 @@ +package dotty.tools.tasty.experimental.bridge + +import reflect.ClassTag + +trait TreeOps extends Core with + self: PositionOps with ContextOps with SourceFileOps with SymbolOps => + + 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 + 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[tpd.Tree] = internal.untpd_TypedSplice_unapply(tree) + + object Ident with + def unapply(tree: Ident): Some[Name] = internal.untpd_Ident_unapply(tree) + + 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) 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) + def envelope(src: SourceFile, startSpan: Span = Span.noSpan): Span = internal.untpd_Tree_envelope(tree, src, startSpan) + 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) extended with + def isType: Boolean = internal.Tree_isType(tree) + def tpe: Type = internal.Tree_tpe(tree) + + given IfOps: (tree: tpd.If) extended with + def isInline: Boolean = internal.If_isInline(tree) + + given MatchOps: (tree: tpd.Match) extended with + def isInline: Boolean = internal.Match_isInline(tree) + + 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) 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) extended with + def rhs: tpd.Tree = internal.TypeDef_rhs(tree) + + 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) + 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: 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 = + 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: 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) + } 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..15b73a294365 --- /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) 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) + 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) extended with + def value: Constant = internal.ConstantType_value(tpe) + + given SuperTypeOps: (tpe: SuperType) extended with + def thistpe: Type = internal.SuperType_thistpe(tpe) + def supertpe: Type = internal.SuperType_supertpe(tpe) + + 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) extended with + def info: Type = internal.SkolemType_info(tpe) + + given BoundTypeOps: (tpe: BoundType) extended with + def binder: tpe.BT = internal.BoundType_binder(tpe) + + given ParamRefOps: (tpe: ParamRef) extended with + def paramNum: Int = internal.ParamRef_paramNum(tpe) + + given RecTypeOps: (tpe: RecType) extended with + def parent: Type = internal.RecType_parent(tpe) + + 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) extended with + def hi: Type = internal.TypeBounds_hi(tpe) + def lo: Type = internal.TypeBounds_lo(tpe) + + given TypeAliasOps: (tpe: TypeAlias) extended with + def alias: Type = internal.TypeAlias_alias(tpe) + + 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) extended with + def parent: Type = internal.AnnotatedType_parent(tpe) + def annot: Annotation = internal.AnnotatedType_annot(tpe) + + given AndOrTypeOps: (tpe: AndOrType) extended with + def tp1: Type = internal.AndOrType_tp1(tpe) + def tp2: Type = internal.AndOrType_tp2(tpe) + + given TypeProxyOps: (tpe: TypeProxy) extended with + def underlying(given Context): Type = internal.TypeProxy_underlying(tpe) + + 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) 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) extended with + def ref(given Context): Type = internal.LazyRef_ref(tpe) + + given ClassInfoOps: (tpe: ClassInfo) extended 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) + }