-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add missing version of ValDef.let
which also accepts flags
#23388
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -682,6 +682,22 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => | |
def copy(original: Tree)(name: String, tpt: TypeTree, rhs: Option[Term]): ValDef | ||
def unapply(vdef: ValDef): (String, TypeTree, Option[Term]) | ||
|
||
/** Creates a block `{ val <name> = <rhs: Term>; <body(x): Term> }` | ||
* | ||
* Usage: | ||
* ``` | ||
* ValDef.let(owner, "x", rhs1, Flags.Lazy) { x => | ||
* ValDef.let(x.symbol.owner, "y", rhs2, Flags.Mutable) { y => | ||
* // use `x` and `y` | ||
* } | ||
* } | ||
* ``` | ||
* | ||
* @param flags extra flags to with which the symbol should be constructed. Can be `Private | Protected | Override | Deferred | Final | Param | Implicit | Lazy | Mutable | Local | ParamAccessor | Module | Package | Case | CaseAccessor | Given | Enum | JavaStatic | Synthetic | Artifact` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we know that this new val is going to be defined in a Block (as opposed to class, object, etc.), we know that less flags/modifiers are going to be allowed there, so ideally we would limit this list here (e.g. access modifiers like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a defined list where the allowed subset is defined? The only ones that I can think of, or at least that I was trying to use, were There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To your point, if only a valid subset is allowed, it would probably make sense to check for what that subset is. Also, just putting the idea out there, it would be really nice if quoted code let you splice in a Feels kinda sad to have this: {
lazy val instance_a: oxygen.core.typeclass.Show[scala.Int] = oxygen.core.typeclass.Show.int
lazy val instance_b: oxygen.core.typeclass.Show[scala.Option[java.lang.String]] = oxygen.core.typeclass.Show.option[java.lang.String](oxygen.core.typeclass.Show.string)
final class $anon() extends oxygen.core.typeclass.Show.PreferBuffer[oxygen.meta.NewDeriveShowSpec.CaseClass1] {
override def writeTo(builder: scala.collection.mutable.StringBuilder, value: oxygen.meta.NewDeriveShowSpec.CaseClass1): scala.Unit = {
builder.append("CaseClass1(a = ")
instance_a.writeTo(builder, value.a)
builder.append(", b = ")
instance_b.writeTo(builder, value.b)
builder.append(")")
()
}
}
(new $anon(): oxygen.core.typeclass.Show.PreferBuffer[oxygen.meta.NewDeriveShowSpec.CaseClass1])
} This would be nicer if it wasnt so difficult: {
final class $anon() extends oxygen.core.typeclass.Show.PreferBuffer[oxygen.meta.NewDeriveShowSpec.CaseClass1] {
private lazy val instance_a: oxygen.core.typeclass.Show[scala.Int] = oxygen.core.typeclass.Show.int
private lazy val instance_b: oxygen.core.typeclass.Show[scala.Option[java.lang.String]] = oxygen.core.typeclass.Show.option[java.lang.String](oxygen.core.typeclass.Show.string)
override def writeTo(builder: scala.collection.mutable.StringBuilder, value: oxygen.meta.NewDeriveShowSpec.CaseClass1): scala.Unit = {
builder.append("CaseClass1(a = ")
instance_a.writeTo(builder, value.a)
builder.append(", b = ")
instance_b.writeTo(builder, value.b)
builder.append(")")
()
}
}
(new $anon(): oxygen.core.typeclass.Show.PreferBuffer[oxygen.meta.NewDeriveShowSpec.CaseClass1])
} Realizing there is probably some weirdness there to get things to line up, though, would probably need a new syntax... final case class Definitions(exprs: Seq[Ref])
private def definitions: Definitions =
'%{
private val myVal1: String = "value-1"
private def myVal2(input: String): String = s"value-2:$input"
}
override def derive: Expr[Show[A]] =
'{
new PreferBuffer[A] {
$%{ definitions as blah }
override def writeTo(builder: mutable.StringBuilder, value: A): Unit = {
builder.append(${ blah.exprs(0).asExprOf[String] })
builder.append('\n')
builder.append(${ blah.exprs(1).appliedToArg(Expr("hi").toTerm).asExprOf[String] })
}
}
} This is not the right place to be suggesting this... 😅 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my opinion, after checking what can work in a |
||
*/ | ||
// Keep: `flags` doc aligned with QuotesImpl's `validValFlags` | ||
def let(owner: Symbol, name: String, rhs: Term, flags: Flags)(body: Ref => Term): Term | ||
|
||
/** Creates a block `{ val <name> = <rhs: Term>; <body(x): Term> }` | ||
* | ||
* Usage: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,9 @@ object MiMaFilters { | |
|
||
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.Conversion.underlying"), | ||
ProblemFilters.exclude[MissingClassProblem]("scala.Conversion$"), | ||
|
||
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#ValDefModule.let"), | ||
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#ValDefModule.let"), | ||
Comment on lines
+22
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those won't do much here. Instead, put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can take another stab at it, and if I cant get it, Im happy with you getting it over the finish line. Im not sure why other tests seem to be failing though... Are there some sort of bootstrap steps that I have not executed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, it seems we recently added a test that depends on line positions in QuotesImpl.scala... Sorry about that. You can run |
||
), | ||
|
||
// Additions since last LTS | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also check if the flags are valid, as suggested in the doc:
Of course, as with my other comment, the flags should ideally be different here than in Flags.validValFlags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accepted suggestion as-is. Very open to limiting allowed flags, if I knew what that allowed set was.