Skip to content

Remove reflect constant value #10754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2092,7 +2092,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
given ConstantMethods: ConstantMethods with
extension (self: Constant)
def value: Any = self.value
def show: String = Extractors.showConstant(using QuotesImpl.this)(self)
def show(using printer: Printer[Constant]): String = printer.show(self)
end extension
end ConstantMethods

Expand Down Expand Up @@ -2774,6 +2774,14 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
def show(tpe: TypeRepr): String =
Extractors.showType(using QuotesImpl.this)(tpe)

lazy val ConstantCode: Printer[Constant] = new Printer[Constant]:
def show(const: Constant): String =
const.show(using ctx.fresh.setSetting(ctx.settings.color, "never"))

lazy val ConstantStructure: Printer[Constant] = new Printer[Constant]:
def show(const: Constant): String =
Extractors.showConstant(using QuotesImpl.this)(const)

end Printer
end reflect

Expand Down
73 changes: 52 additions & 21 deletions library/src-bootstrapped/scala/quoted/FromExpr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,69 +29,100 @@ object FromExpr {
* - Unlifts `'{false}` into `Some(false)`
* - Otherwise unlifts to `None`
*/
given BooleanFromExpr[T <: Boolean]: FromExpr[T] = new PrimitiveFromExpr
given BooleanFromExpr[T <: Boolean]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for BooleanConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[Byte]`
* - Unlifts `'{n}` into `Some(n)` for a literal `n` of type `Byte`
* - Otherwise unlifts to `None`
*/
given ByteFromExpr[T <: Byte]: FromExpr[T] = new PrimitiveFromExpr
given ByteFromExpr[T <: Byte]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for ByteConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[Short]`
* - Unlifts `'{n}` into `Some(n)` for a literal `n` of type `Short`
* - Otherwise unlifts to `None`
*/
given ShortFromExpr[T <: Short]: FromExpr[T] = new PrimitiveFromExpr
given ShortFromExpr[T <: Short]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for ShortConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[Int]`
* - Unlifts `'{n}` into `Some(n)` for a literal `n` of type `Int`
* - Otherwise unlifts to `None`
*/
given IntFromExpr[T <: Int]: FromExpr[T] = new PrimitiveFromExpr
given IntFromExpr[T <: Int]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for IntConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[Long]`
* - Unlifts `'{n}` into `Some(n)` for a literal `n` of type `Long`
* - Otherwise unlifts to `None`
*/
given LongFromExpr[T <: Long]: FromExpr[T] = new PrimitiveFromExpr
given LongFromExpr[T <: Long]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for LongConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[Float]`
* - Unlifts `'{n}` into `Some(n)` for a literal `n` of type `Float`
* - Otherwise unlifts to `None`
*/
given FloatFromExpr[T <: Float]: FromExpr[T] = new PrimitiveFromExpr
given FloatFromExpr[T <: Float]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for FloatConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[Double]`
* - Unlifts `'{n}` into `Some(n)` for a literal `n` of type `Double`
* - Otherwise unlifts to `None`
*/
given DoubleFromExpr[T <: Double]: FromExpr[T] = new PrimitiveFromExpr
given DoubleFromExpr[T <: Double]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for DoubleConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[Char]`
* - Unlifts `'{c}` into `Some(c)` for a literal `c` of type `Char`
* - Otherwise unlifts to `None`
*/
given CharFromExpr[T <: Char]: FromExpr[T] = new PrimitiveFromExpr
given CharFromExpr[T <: Char]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
for CharConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

/** Default implementation of `FromExpr[String]`
* - Unlifts `'{str}` into `Some(str)` for a literal `str` of type `String`
* - Otherwise unlifts to `None`
*/
given StringFromExpr[T <: String]: FromExpr[T] = new PrimitiveFromExpr

/** Lift a quoted primitive value `'{ x }` into `x` */
private class PrimitiveFromExpr[T <: Boolean | Byte | Short | Int | Long | Float | Double | Char | String] extends FromExpr[T] {
given StringFromExpr[T <: String]: FromExpr[T] with
def unapply(expr: Expr[T])(using Quotes) =
import quotes.reflect._
def rec(tree: Term): Option[T] = tree match {
case Literal(c) if c.value != null => Some(c.value.asInstanceOf[T])
case Block(Nil, e) => rec(e)
case Typed(e, _) => rec(e)
case Inlined(_, Nil, e) => rec(e)
case _ => None
}
rec(expr.asTerm)
}
for StringConstant(v) <- nestedConstant(expr.asTerm)
yield v.asInstanceOf[T]

private def nestedConstant(using Quotes)(tree: quotes.reflect.Term): Option[quotes.reflect.Constant] =
import quotes.reflect._
tree match
case Literal(c) => Some(c)
case Block(Nil, e) => nestedConstant(e)
case Typed(e, _) => nestedConstant(e)
case Inlined(_, Nil, e) => nestedConstant(e)
case _ => None

/** Default implementation of `FromExpr[Option]`
* - Unlifts `'{Some(x)}` into `Some(Some(x))` if `x` is unliftable
Expand Down
9 changes: 8 additions & 1 deletion library/src/scala/quoted/Const.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ object Const {
case Literal(c) =>
c match
case NullConstant() | UnitConstant() | ClassOfConstant(_) => None
case _ => Some(c.value.asInstanceOf[T])
case BooleanConstant(x) => Some(x.asInstanceOf[T])
case ShortConstant(x) => Some(x.asInstanceOf[T])
case IntConstant(x) => Some(x.asInstanceOf[T])
case LongConstant(x) => Some(x.asInstanceOf[T])
case FloatConstant(x) => Some(x.asInstanceOf[T])
case DoubleConstant(x) => Some(x.asInstanceOf[T])
case CharConstant(x) => Some(x.asInstanceOf[T])
case StringConstant(x) => Some(x.asInstanceOf[T])
case Block(Nil, e) => rec(e)
case Typed(e, _) => rec(e)
case Inlined(_, Nil, e) => rec(e)
Expand Down
14 changes: 10 additions & 4 deletions library/src/scala/quoted/Quotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2754,11 +2754,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
/** Extension methods of `Constant` */
trait ConstantMethods {
extension (self: Constant)
/** Returns the value of the constant */
def value: Any

/** Shows the constant as a String */
def show: String
def show(using Printer[Constant]): String

end extension
}

Expand Down Expand Up @@ -4113,6 +4111,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
/** Default pinter for `TypeRepr` used when calling `tpe.show` */
given TypeReprPrinter: Printer[TypeRepr] = Printer.TypeReprCode

/** Default pinter for `Constant` used when calling `const.show` */
given ConstantPrinter: Printer[Constant] = Printer.ConstantCode

/** Module object of `type Printer`.
* Contains custom printers such as `TreeCode`, `TreeAnsiCode`, `TreeCases`, `TypeReprCode`, ..., `SymbolFullName` and `FlagsCombination`.
*/
Expand Down Expand Up @@ -4152,6 +4153,11 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
*/
def TypeReprStructure: Printer[TypeRepr]

/** Prints the constant in source code. */
def ConstantCode: Printer[Constant]

/** Prints a pattern like representation of the `Constant`. */
def ConstantStructure: Printer[Constant]
}

}
Expand Down
11 changes: 2 additions & 9 deletions scala3doc/src/dotty/dokka/tasty/BasicSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,15 @@ trait BasicSupport:
val params = annotTerm match
case Apply(target, appliedWith) => {
appliedWith.flatMap {
case Literal(constant) => Some(Annotation.PrimitiveParameter(None, constant.value match {
case s: String => "\"" + s"$s" + "\""
case other => other.toString()
}))
case NamedArg(name, Literal(constant)) => Some(Annotation.PrimitiveParameter(Some(name), constant.value match
case s: String => "\"" + s"$s" + "\""
case other => other.toString()
))
case Literal(constant) => Some(Annotation.PrimitiveParameter(None, constant.show))
case NamedArg(name, Literal(constant)) => Some(Annotation.PrimitiveParameter(Some(name), constant.show))
case x @ Select(qual, name) => None
case other => Some(Annotation.UnresolvedParameter(None, other.show))
}
}

Annotation(dri, params)


extension (sym: Symbol)
def documentation = sym.docstring match
case Some(docstring) =>
Expand Down
5 changes: 1 addition & 4 deletions scala3doc/src/dotty/dokka/tasty/TypesSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,7 @@ trait TypesSupport:
case AndType(left, right) => inner(left) ++ texts(" & ") ++ inner(right)
case ByNameType(tpe) => text("=> ") :: inner(tpe)
case ConstantType(constant) =>
texts(constant.value match
case c: Char => s"'$c'"
case other => other.toString
)
texts(constant.show)
case ThisType(tpe) => inner(tpe)
case AnnotatedType(AppliedType(_, Seq(tpe)), annotation) if isRepeated(annotation) =>
inner(tpe) :+ text("*")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,20 @@ class Interpreter[Q <: Quotes & Singleton](using q0: Q) extends TreeInterpreter[

def interpretUnit(): AbstractAny = ().asInstanceOf[Object]

def interpretLiteral(const: Constant): Result = const.value
def interpretLiteral(const: Constant): Result =
const match
case UnitConstant() => ()
case NullConstant() => null
case BooleanConstant(v) => v
case ByteConstant(v) => v
case ShortConstant(v) => v
case IntConstant(v) => v
case LongConstant(v) => v
case FloatConstant(v) => v
case DoubleConstant(v) => v
case CharConstant(v) => v
case StringConstant(v) => v
case ClassOfConstant(v) => ???

def interpretIsInstanceOf(o: AbstractAny, tpt: TypeTree): Result =
jvmReflection.getClassOf(tpt.symbol).isInstance(o)
Expand Down