Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@ajafri2001
Copy link
Contributor

@ajafri2001 ajafri2001 commented May 11, 2025

@ajafri2001
Copy link
Contributor Author

I should add tests and only prepend "using" for scala3+ πŸ˜….

I'm not sure if this pr is the correct way to solve the issue tbh, if you have something particular in mind I'm willing to work on it.

object TwirlCompiler {

var isScala3 = false

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this var isScala3 is not necessary.
If you declare emitScala3Sources as a val, it can be referred to later as sc.emitScala3Sources.

.mkString(",") + ")",
returnType,
val hasContextParameters =
params.flatten.exists(_.mods.exists(_.toString.contains("implicit")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the following approach can be used to check whether implicit is present.
It might be cleaner than relying on toString.

import scala.meta.classifiers._
mod.is[Mod.Implicit]

if (TwirlCompiler.isScala3 && hasContextParameters && idx == params.size - 1)
groupStr.replace("(", "(using ")
else groupStr
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be working well.
However, I thought it might be more readable if the processing were completed within the previous map { ... } block, rather than using the zipWithIndex.map.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unable to avoid relying on zipWithIndex as the logic is not clear to me, however, I have reduced the number of transformations by moving it to the beginning of the said transformations

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it wouldn’t be necessary to check whether a parameter is the last, since an implicit parameter is always the last parameter group.
However, I think your current implementation is fine. thanks.

@tototoshi
Copy link
Member

@ajafri2001
Hi. I tried out this pull request, and as far as I can tell, it seems to be working well.
I left a few minor commentsβ€”please take a look.
Also, I think it would be good to add a test case to CompilerSpec.
You can find various test files in compiler/src/test/resources/, so I recommend referring to those as examples.

@ajafri2001
Copy link
Contributor Author

ajafri2001 commented Jun 17, 2025

@tototoshi Hi, I'm unable to get the CompilerSpec Tests to compile with scala3 instead of scala2, I have added the tests but they now fail.

Edit - Also the parser does not recognize using instead of implicit. I'm willing to work on that too, if you can point me in the right direction

@ajafri2001 ajafri2001 requested a review from tototoshi June 17, 2025 18:42
@tototoshi
Copy link
Member

On my end, the tests seem to pass with Scala 3, but not with Scala 2

Also the parser does not recognize using instead of implicit.

I had the same thought as well.
I haven’t looked into it deeply yet, but the TwirlParser probably only looks at parentheses and doesn’t check for implicit or using keywords. So I don’t think any changes are needed there.

As for the TwirlCompiler, I think your current fix could be extended slightly to support this case too.

@ajafri2001
Copy link
Contributor Author

@tototoshi

the TwirlParser probably only looks at parentheses and doesn’t check for implicit or using keywords. So I don’t think any changes are needed there.
As for the TwirlCompiler, I think your current fix could be extended slightly to support this case too.

Yes, you were right this worked πŸ™‡β€β™‚οΈ, twirl is now able to compile the syntax @(....)(using some_name: some_type).

The test fails now because sbt test by default runs with scala2, and I'm not sure how to test with scala3

@ajafri2001 ajafri2001 marked this pull request as ready for review June 25, 2025 22:14
@tototoshi
Copy link
Member

You can do it like this:

sbt
> ++3.3.5
> test

or

sbt ++3.3.5 test

@tototoshi
Copy link
Member

The reason the tests are failing on Scala 2 is not due to the callsite, but because there's an error at the definition site. So I believe it's unrelated to the changes in this PR.
Also, it would be quite unnatural for Scala 2 users to write using in their templates. Given that, I think it's reasonable for Twirl to simply not support using when running under Scala 2.

@ajafri2001
Copy link
Contributor Author

ajafri2001 commented Jun 28, 2025

Ahh, the tests fail with scala2 but pass with scala3 because, as you mentioned, using doesn't exist in scala2. this pr enables the use of using at the definition site as well as the call site for scala3, solving both issues issue-894 and issue-839, which are specifically for scala3 and are both addressed by this pr.

However, the test i've added namely using.scala.html, is only ever supposed to run for scala3 and shouldn't be run with scala2 at all.

How should i deal with this situation and make the test run ONLY with scala3 (since it's a scala3 specific feature)? I'm really grateful for your help so far πŸ˜…

@tototoshi
Copy link
Member

If you want a test to run only on Scala 3, you can place it under src/test/scala-3.
However, that approach requires splitting tests by class, which might be a bit cumbersome.

Alternatively, a simpler way is to check the Scala version at runtime and decide whether to run the test.
With ScalaTest, you can use assume like this:

assume(BuildInfo.scalaVersion.startsWith("3."), "This test is only for Scala 3")

@ajafri2001
Copy link
Contributor Author

Thanks the tests pass now

Copy link
Member

@mkurz mkurz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work!
Code looks good and also did some local testing.
Regarding the parser I also was unsure if we need some modifcation, but you as you mentioned correctly the parser does not check for keywords inside brackets, it's handling the content within (...) stupidly: https://github.com/playframework/twirl/blob/2.0.8/parser/src/main/scala/play/twirl/parser/TwirlParser.scala#L988-L994

We can backport this to the stable branches, pretty sure this is a non breaking addition.

Thanks!

@mkurz mkurz merged commit 070c1e4 into playframework:main Jun 30, 2025
15 checks passed
@mkurz
Copy link
Member

mkurz commented Jun 30, 2025

@Mergifyio backport 2.0.x 1.6.x

@mergify
Copy link
Contributor

mergify bot commented Jun 30, 2025

mergify bot added a commit that referenced this pull request Jun 30, 2025
[1.6.x] Prepend "using" at the callsite when definition site has implicit parameter  (backport #933) by @ajafri2001
mergify bot added a commit that referenced this pull request Jun 30, 2025
[2.0.x] Prepend "using" at the callsite when definition site has implicit parameter  (backport #933) by @ajafri2001
@mkurz
Copy link
Member

mkurz commented Jun 30, 2025

Released:

@ajafri2001
Copy link
Contributor Author

@tototoshi @mkurz
Omg thanks for the all the help and the shoutout!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implicit parameters should be provided with a using clause warning since Scala 3.7

3 participants