[ 
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)

Reply via email to