manifold-systems / manifold

Manifold is a Java compiler plugin, its features include Metaprogramming, Properties, Extension Methods, Operator Overloading, Templates, a Preprocessor, and more.
http://manifold.systems/
Apache License 2.0
2.43k stars 125 forks source link

[Question] field access from inside the class on a @set field #477

Closed CC007 closed 1 year ago

CC007 commented 1 year ago

I noticed that you can't even access field that is annotated with @set from inside the class. Is this intentional behavior? Does this mean that I will always have to mark fields that I want to use inside the class with @get(Private) as well?

If that's the case, then what even is the purpose of the @set annotation without a @get(...) annotation, an abstract modifier or an explicit method implementation?

Is there a way (like with some kind of configuration) to make it so that using @set will implicitly add @get(Private) as well? Alternatively, is there a way to turn off rewriting field access/assignment to getters for fields in that same class (like this.fieldname)?

rsmckinney commented 1 year ago

Ah, good catch! Yes, using @set to denote a write-only property requires an explicit @get(Private) as you surmised. Making that implicit is probably the right way to go here.

@set is useful, for instance, to control write accessibility:

@var @set(Protected) String name;

Anyhow, I'll make that change as well for tonight's release.

Thanks for reporting this!

CC007 commented 1 year ago

No problem. Glad to share my perspective. So from what I'm gathering @set is mostly used in combination with at least one other annotation, modifier or implementation.

I found this behavior when trying to use Lombok's @ToString annotation.

At first I thought that it was a bug when Lombok and Manifold interacted, but after analyzing the code further I saw that this strict behavior was actually intended functionality up until now.

I think that the strictness could be useful in some situations, but in the majority of cases the ability to access a field from inside the class is probably preferred. Maybe adding a strict parameter to the @set could help support both use cases.

The same could be true for @get, so that @get(strict = true) would behave like @val, making the field final, but @get without the parameter would still allow the field to be modified from inside the class. That'd also give a better reason for both @val and @get to exist, other than naming consistency. This change would be backwards-compatible, because it makes the field use only less restrictive, meaning that all existing code would continue to work.

rsmckinney commented 1 year ago

Fix available with release 2023.1.18. Thanks for reporting this!

CC007 commented 1 year ago

Should I put the strict parameter stuff in a separate feature request?

rsmckinney commented 1 year ago

That would be great. Thanks!

CC007 commented 1 year ago

That would be great. Thanks!

Done. See mention above