-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add minimal prototype for f interpolator macro #5532
Add minimal prototype for f interpolator macro #5532
Conversation
Can we put it in the library to cross-compile code that uses this interpolator ? |
You mean a version that does not check anything? |
It's better than nothing. |
But doesn't this version check things ? |
Yes, I will work on it. But this one is intended as an example for the student to see how to start. |
} | ||
|
||
// [a0, ...]: Any* | ||
val Term.Typed(Term.Repeated(allArgs), _) = args.unseal.underlyingArgument |
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.
So would it be possible to use args.unseal.underlying
and leave args
not by-name?
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.
Yes. I copied this basic implementation from an old version of the xml interpolator. There are many other improvements that can be done. This is just a simple example of one way to do it.
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.
Otherwise, LGTM
values.forall(isStringConstant) => | ||
values.collect { case Term.Literal(Constant.String(value)) => value } | ||
case tree => | ||
throw new QuoteError(s"String literal expected, but ${tree.show} found") |
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.
For later: better error message with positions.
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.
This is just an example for the student to start
|
||
for ((arg, part) <- allArgs.zip(parts.tail)) { | ||
if (part.startsWith("%d") && !(arg.tpe <:< definitions.IntType)) { | ||
return '(s"`${~arg.showCode.toExpr}` is not of type Int") |
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.
Error message instead?
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.
This is just an example for the student to start. It is a simple way to see the output.
|
||
object FQuote { | ||
|
||
implicit class SCOps(ctx: StringContext) { |
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.
Just to confirm: I remember some time ago, we need to use => StringContext
. I guess with underlyingArgument
this is no longer required.
tree.symbol.fullName == "scala.StringContext$.apply" | ||
|
||
// FQuote.SCOps(StringContext.apply([p0, ...]: String*) | ||
val parts = receiver.unseal.underlyingArgument match { |
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.
For later: it seems the name underlyingArgument
does not make sense here, as it's a receiver, not argument.
No description provided.