diff --git a/library/src/scala/internal/quoted/Expr.scala b/library/src-bootstrapped/scala/internal/quoted/Expr.scala similarity index 100% rename from library/src/scala/internal/quoted/Expr.scala rename to library/src-bootstrapped/scala/internal/quoted/Expr.scala diff --git a/library/src/scala/internal/quoted/Matcher.scala b/library/src-bootstrapped/scala/internal/quoted/Matcher.scala similarity index 100% rename from library/src/scala/internal/quoted/Matcher.scala rename to library/src-bootstrapped/scala/internal/quoted/Matcher.scala diff --git a/library/src/scala/internal/quoted/Type.scala b/library/src-bootstrapped/scala/internal/quoted/Type.scala similarity index 100% rename from library/src/scala/internal/quoted/Type.scala rename to library/src-bootstrapped/scala/internal/quoted/Type.scala diff --git a/library/src/scala/internal/quoted/Unpickler.scala b/library/src-bootstrapped/scala/internal/quoted/Unpickler.scala similarity index 100% rename from library/src/scala/internal/quoted/Unpickler.scala rename to library/src-bootstrapped/scala/internal/quoted/Unpickler.scala diff --git a/library/src-non-bootstrapped/scala/internal/quoted/Expr.scala b/library/src-non-bootstrapped/scala/internal/quoted/Expr.scala new file mode 100644 index 000000000000..7d841156396d --- /dev/null +++ b/library/src-non-bootstrapped/scala/internal/quoted/Expr.scala @@ -0,0 +1,36 @@ +package scala.internal.quoted + +import scala.quoted._ + +/** An Expr backed by a tree. Only the current compiler trees are allowed. + * + * These expressions are used for arguments of macros. They contain and actual tree + * from the program that is being expanded by the macro. + * + * May contain references to code defined outside this Expr instance. + */ + final class Expr[Tree](val tree: Tree, val scopeId: Int) extends scala.quoted.Expr[Any] { + override def equals(that: Any): Boolean = that match { + case that: Expr[_] => + // Expr are wrappers around trees, therfore they are equals if their trees are equal. + // All scopeId should be equal unless two different runs of the compiler created the trees. + tree == that.tree && scopeId == that.scopeId + case _ => false + } + + def unseal(using qctx: QuoteContext): qctx.tasty.Term = + if (qctx.tasty.internal.compilerId != scopeId) + throw new scala.quoted.ScopeException("Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`") + tree.asInstanceOf[qctx.tasty.Term] + + override def hashCode: Int = tree.hashCode + override def toString: String = "'{ ... }" +} + +object Expr { + + def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutineeExpr: scala.quoted.Expr[Any])(using patternExpr: scala.quoted.Expr[Any], + hasTypeSplices: Boolean, qctx: QuoteContext): Option[Tup] = + throw new Exception("Non bootstrapped lib") + +} diff --git a/library/src-non-bootstrapped/scala/internal/quoted/Matcher.scala b/library/src-non-bootstrapped/scala/internal/quoted/Matcher.scala new file mode 100644 index 000000000000..06c59a7e2cbe --- /dev/null +++ b/library/src-non-bootstrapped/scala/internal/quoted/Matcher.scala @@ -0,0 +1,45 @@ +package scala.internal.quoted + +import scala.annotation.internal.sharable +import scala.annotation.{Annotation, compileTimeOnly} + +import scala.quoted._ + +object Matcher { + + /** A splice in a quoted pattern is desugared by the compiler into a call to this method */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternHole`") + def patternHole[T]: T = ??? + + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternHigherOrderHole`") + /** A higher order splice in a quoted pattern is desugared by the compiler into a call to this method */ + def patternHigherOrderHole[U](pat: Any, args: Any*): U = ??? + + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.higherOrderHole`") + /** A higher order splice in a quoted pattern is desugared by the compiler into a call to this method */ + def higherOrderHole[U](args: Any*): U = ??? + + // TODO remove + /** A splice of a name in a quoted pattern is desugared by wrapping getting this annotation */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternBindHole`") + class patternBindHole extends Annotation + + /** A splice of a name in a quoted pattern is that marks the definition of a type splice */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternType`") + class patternType extends Annotation + + /** A type pattern that must be aproximated from above */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.fromAbove`") + class fromAbove extends Annotation + + class QuoteMatcher[QCtx <: QuoteContext & Singleton](using val qctx: QCtx) { + import qctx.tasty._ + + def termMatch(scrutineeTerm: Term, patternTerm: Term, hasTypeSplices: Boolean): Option[Tuple] = + throw new Exception("Non bootstrapped lib") + + def typeTreeMatch(scrutineeTypeTree: TypeTree, patternTypeTree: TypeTree, hasTypeSplices: Boolean): Option[Tuple] = + throw new Exception("Non bootstrapped lib") + } + +} diff --git a/library/src-non-bootstrapped/scala/internal/quoted/Type.scala b/library/src-non-bootstrapped/scala/internal/quoted/Type.scala new file mode 100644 index 000000000000..c4827de16ac3 --- /dev/null +++ b/library/src-non-bootstrapped/scala/internal/quoted/Type.scala @@ -0,0 +1,71 @@ +package scala.internal.quoted + +import scala.quoted._ + +/** Quoted type (or kind) `T` backed by a tree */ +final class Type[Tree](val typeTree: Tree, val scopeId: Int) extends scala.quoted.Type[Any] { + override def equals(that: Any): Boolean = that match { + case that: Type[_] => typeTree == + // TastyTreeExpr are wrappers around trees, therfore they are equals if their trees are equal. + // All scopeId should be equal unless two different runs of the compiler created the trees. + that.typeTree && scopeId == that.scopeId + case _ => false + } + + /** View this expression `quoted.Type[T]` as a `TypeTree` */ + def unseal(using qctx: QuoteContext): qctx.tasty.TypeTree = + if (qctx.tasty.internal.compilerId != scopeId) + throw new scala.quoted.ScopeException("Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`") + typeTree.asInstanceOf[qctx.tasty.TypeTree] + + override def hashCode: Int = typeTree.hashCode + override def toString: String = "'[ ... ]" +} + +object Type { + + /** Pattern matches an the scrutineeType against the patternType and returns a tuple + * with the matched holes if successful. + * + * Holes: + * - scala.internal.Quoted.patternHole[T]: hole that matches an expression `x` of type `Type[U]` + * if `U <:< T` and returns `x` as part of the match. + * + * @param scrutineeType `Type[_]` on which we are pattern matching + * @param patternType `Type[_]` containing the pattern tree + * @param hasTypeSplices `Boolean` notify if the pattern has type splices (if so we use a GADT context) + * @param qctx the current QuoteContext + * @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Type[Ti]`` + */ + def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutineeType: scala.quoted.Type[_])(using patternType: scala.quoted.Type[_], + hasTypeSplices: Boolean, qctx: QuoteContext): Option[Tup] = + throw new Exception("Non bootstrapped lib") + + def Unit: QuoteContext ?=> quoted.Type[Unit] = + throw new Exception("Non bootstrapped lib") + + def Boolean: QuoteContext ?=> quoted.Type[Boolean] = + throw new Exception("Non bootstrapped lib") + + def Byte: QuoteContext ?=> quoted.Type[Byte] = + throw new Exception("Non bootstrapped lib") + + def Char: QuoteContext ?=> quoted.Type[Char] = + throw new Exception("Non bootstrapped lib") + + def Short: QuoteContext ?=> quoted.Type[Short] = + throw new Exception("Non bootstrapped lib") + + def Int: QuoteContext ?=> quoted.Type[Int] = + throw new Exception("Non bootstrapped lib") + + def Long: QuoteContext ?=> quoted.Type[Long] = + throw new Exception("Non bootstrapped lib") + + def Float: QuoteContext ?=> quoted.Type[Float] = + throw new Exception("Non bootstrapped lib") + + def Double: QuoteContext ?=> quoted.Type[Double] = + throw new Exception("Non bootstrapped lib") + +} diff --git a/library/src-non-bootstrapped/scala/internal/quoted/Unpickler.scala b/library/src-non-bootstrapped/scala/internal/quoted/Unpickler.scala new file mode 100644 index 000000000000..bd49f720a317 --- /dev/null +++ b/library/src-non-bootstrapped/scala/internal/quoted/Unpickler.scala @@ -0,0 +1,16 @@ +package scala.internal.quoted + +import scala.quoted.{Expr, QuoteContext, Type} + +object Unpickler { + + type PickledQuote = List[String] + type PickledArgs = Seq[Seq[Any] => Any/*(([QCtx <: QuoteContext] =>> QCtx ?=> Expr[Any]) | Type[_])*/] + + def unpickleExpr[T](repr: PickledQuote, args: PickledArgs): QuoteContext ?=> Expr[T] = + throw new Exception("Non bootstrapped lib") + + def unpickleType[T](repr: PickledQuote, args: PickledArgs): QuoteContext ?=> Type[T] = + throw new Exception("Non bootstrapped lib") + +}