[
https://issues.apache.org/jira/browse/FREEMARKER-183?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17788553#comment-17788553
]
Simon edited comment on FREEMARKER-183 at 2/10/24 2:41 PM:
-----------------------------------------------------------
I've created a proof-of-concept here:
[https://github.com/scrhartley/apache-freemarker/commit/a5063b58c41dbb4e43e42e846373fd34e09ad25f|https://github.com/scrhartley/freemarker-records-poc/commit/a5063b58c41dbb4e43e42e846373fd34e09ad25f]
This is more to demonstrate what I meant, rather than being a recommendation
for what should be done.
What I _did_ learn, was that bean property support for records is an odd idea:
For a record, the only fields you can have are the (immutable) components.
If I have a field called value then I would have an accessor called {{value(),}}
so then if I wanted a method to get some derived state, it would make sense for
it to be:
{code:java}
public int doubleValue() { return this.value * 2; }
{code}
This seems to be more consistent with {{value()}} than calling it
{{{}getDoubleValue(){}}}.
Now that I have {{{}doubleValue(){}}}, it would be nice if it was also a
property, but the FreeMarker property support wouldn't do this.
(I think this is just your idea about "zeroArgumentMethodsAreProperties", but
now I appreciate more what you were saying.)
Also does it make sense for a record to support indexed properties or generic
get methods (i.e. other bean related stuff)?
Even if we just force users to not use `()`, I think consideration of how much
bean behavior records should have is worthwhile.
+P-O-C Implementation Notes and Limitations+
* Dot is enhanced to pass on the hint, so both {{record.component}} and
{{{}record.{}}}{{{}component{}}}{{{}(){}}} would work, but I have not tried to
enhance anywhere else.
For example ParentheticalExpression is not enhanced, so
{{(record.component)()}} would not work, which is probably fine.
* The implementation in ClassIntrospector is incomplete/very limited and for
records _only_ supports components, rather than trying to resolve the
conceptual differences from beans or handling overloaded methods.
* BeanModel does not attempt to do any caching in order to avoid false cache
hits. You would need a cache that takes the hint (or lack of) into account to
allow this.
* I have not tried to give anything a good name or worried about the ideal
inheritance structure.
* I have created overloads for {{Expression.eval}} and {{Expression._eval}}
rather than extending the existing methods, avoiding code updates everywhere
and also to highlight that the versions taking a hint are special, rather than
being for normal usage.
was (Author: JIRAUSER301336):
I've created a proof-of-concept here:
[https://github.com/scrhartley/freemarker-records-poc/commit/a5063b58c41dbb4e43e42e846373fd34e09ad25f]
This is more to demonstrate what I meant, rather than being a recommendation
for what should be done.
What I _did_ learn, was that bean property support for records is an odd idea:
For a record, the only fields you can have are the (immutable) components.
If I have a field called value then I would have an accessor called {{value(),}}
so then if I wanted a method to get some derived state, it would make sense for
it to be:
{code:java}
public int doubleValue() { return this.value * 2; }
{code}
This seems to be more consistent with {{value()}} than calling it
{{{}getDoubleValue(){}}}.
Now that I have {{{}doubleValue(){}}}, it would be nice if it was also a
property, but the FreeMarker property support wouldn't do this.
(I think this is just your idea about "zeroArgumentMethodsAreProperties", but
now I appreciate more what you were saying.)
Also does it make sense for a record to support indexed properties or generic
get methods (i.e. other bean related stuff)?
Even if we just force users to not use `()`, I think consideration of how much
bean behavior records should have is worthwhile.
+P-O-C Implementation Notes and Limitations+
* Dot is enhanced to pass on the hint, so both {{record.component}} and
{{{}record.{}}}{{{}component{}}}{{{}(){}}} would work, but I have not tried to
enhance anywhere else.
For example ParentheticalExpression is not enhanced, so
{{(record.component)()}} would not work, which is probably fine.
* The implementation in ClassIntrospector is incomplete/very limited and for
records _only_ supports components, rather than trying to resolve the
conceptual differences from beans or handling overloaded methods.
* BeanModel does not attempt to do any caching in order to avoid false cache
hits. You would need a cache that takes the hint (or lack of) into account to
allow this.
* I have not tried to give anything a good name or worried about the ideal
inheritance structure.
* I have created overloads for {{Expression.eval}} and {{Expression._eval}}
rather than extending the existing methods, avoiding code updates everywhere
and also to highlight that the versions taking a hint are special, rather than
being for normal usage.
> Add support for Java records
> ----------------------------
>
> Key: FREEMARKER-183
> URL: https://issues.apache.org/jira/browse/FREEMARKER-183
> Project: Apache Freemarker
> Issue Type: Task
> Reporter: Dániel Dékány
> Assignee: Dániel Dékány
> Priority: Major
>
> Currently we don't support records (JEP 395), which was finalized in Java 16.
> Users can extend {{DefaultObjectWrapper}} for that of course, but it should
> be supported out of the box.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)