+
Skip to content

WIP Add support for transforming constructor names. #114

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
wants to merge 5 commits into from
Closed

WIP Add support for transforming constructor names. #114

wants to merge 5 commits into from

Conversation

danxmoran
Copy link
Contributor

(Eventually) resolves #110

Still WIP because there are some open questions, but the code that's there is ready for a look.

@@ -10,6 +10,7 @@ class JsonCodec(
def macroTransform(annottees: Any*): Any = macro GenericJsonCodecMacros.jsonCodecAnnotationMacro
}

// FIXME: Should these annotations also handle constructor transformations?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Biggest open question feature-wise, I think

Copy link
Member

Choose a reason for hiding this comment

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

I'd vote no.

case ..$discriminatorCases
new _root_.io.circe.Decoder[$tpe] {
// NOTE: This wrapper might look pointless, but leaving it out causes compilation to fail with
// an assertion error from the compiler. There's probably a better way to avoid the problem.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the problem I mentioned in the ticket. I noticed that the compiler crash only happened in the Decoder case, not the Codec. The only difference I could see was that the Codec explicitly created a wrapper class around the generated case statements, so I tried doing that and it worked. This is my first time digging into Scala macros so I have no idea why the other way wouldn't work.

Copy link
Member

@travisbrown travisbrown left a comment

Choose a reason for hiding this comment

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

This generally looks good to me, thanks! I'll take a closer look asap.

@@ -10,6 +10,7 @@ class JsonCodec(
def macroTransform(annottees: Any*): Any = macro GenericJsonCodecMacros.jsonCodecAnnotationMacro
}

// FIXME: Should these annotations also handle constructor 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'd vote no.

@@ -592,24 +602,27 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat {

// we materialize trait
private[this] def materializeEncoderTraitImpl[T: c.WeakTypeTag](
transformMemberNames: Option[c.Expr[String => String]],
transformConstructorNames: Option[c.Expr[String => String]],
Copy link
Member

Choose a reason for hiding this comment

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

Good catch that we didn't need the old argument here.


cq"""$value => c.get($value)(_root_.io.circe.Decoder[${s.asType}]).asInstanceOf[_root_.io.circe.Decoder.Result[$tpe]]"""
cq"""nme if nme == $value => c.get(nme)(_root_.io.circe.Decoder[${s.asType}]).asInstanceOf[_root_.io.circe.Decoder.Result[$tpe]]"""
Copy link
Member

Choose a reason for hiding this comment

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

Out of curiosity, was this change necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was (as far as I could tell). Matching directly on $value caused compilation errors about function 1 not having an unapply method when transformConstructorNames wasn't None. The generated code looked like:

case (((x: String) => someFunc(x))("AdtBar")) => ???
case (((x: String) => someFunc(x))("AdtFoo")) => ???

Now they look like:

case nme if nme == (((x: String) => someFunc(x))("AdtBar")) => ???
case nme if nme == (((x: String) => someFunc(x))("AdtFoo")) => ???

Related question I was wondering about: is there any way to "lift" the transformation function into the macro to make it directly useable, so we can pre-compute the transformed strings?

@danxmoran
Copy link
Contributor Author

Any tips for debugging the JS errors? The problem only seems to be in deriveDecoder, which is weird because the new code is exactly the same as in deriveCodec.

@travisbrown
Copy link
Member

@danxmoran Does this branch have the 0.6.29 update? If so you might try rolling back to 0.6.28. It's a compiler crash, so I suspect it's not our fault. I can take a closer look later.

@danxmoran danxmoran marked this pull request as ready for review September 20, 2019 13:12
@danxmoran
Copy link
Contributor Author

@travisbrown I hit the crash on both 0.6.28 and 0.6.29

@travisbrown
Copy link
Member

These commits are included in #186. Thanks again, @danxmoran!

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.

Support constructor name transformations
2 participants
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载