Skip to content
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

Externalize builder class #1108

Open
bmarwell opened this issue Oct 24, 2019 · 3 comments
Open

Externalize builder class #1108

bmarwell opened this issue Oct 24, 2019 · 3 comments

Comments

@bmarwell
Copy link

Hi,

I have the following proposal.

Feature description

For one of my projects I'd like to have two classes generated:

  • source class:
@Value.Immutable
@Value.Style(stagedBuilder=true, jdkOnly=true, builder="", typeImmutable="*")
/* non-public */ abstract class AbstractMyClass {
  public abstract int id();
}
  • Immutable class:
@Generated 
public MyClass { 
  /* does not contain builder, just protected constructor  or similar */
  public int id { return id; }
}
  • Factory/Builder class:
@Generated
public class MyClassFactory { 
  public static MyClass.IdBuildStage builder() {
    return /* generated factory goes here instead of MyClass.java */
  }
} 

Is this possible? I mean I could create the factories myself using https://immutables.github.io/factory.html, but that is not what I had in mind. And for this, I also had to create a public constructor.

Thanks in advance.

Use case

Single responsibility. At the moment, the generated classes will have the builder AND the
immutable class (or vice versa if you enable implementationNestedInBuilder).

@elucash
Copy link
Member

elucash commented Oct 24, 2019

There are includes @Value.Include which can generate immutable stuff externally. Also there's Style.visibility & Style.builderVisibility with which it's possible to nest immutable impl in top level builder. Also @Value.Enclosing annotation can tweak code generation a bit to generate nested builders and implementations. I cannot say there can be exact combination you're looking for, but I suggest to keep things simple, better have single generated file per abstract value type, etc, helps with incremental compilation, for example.

@bmarwell
Copy link
Author

bmarwell commented Oct 25, 2019

Let's keep this open for a while to see if others are interested in this or have an opinion on this. Maybe it is not a good idea, maybe it is?

I do not think the incremental compilation is something we need to keep in mind. I'll try to see what I can make out of your suggestions and post it into this issue.

// Edit
Tried to create this with @Builder.Factory annotation. I lose the staged builder, so I created a new issue for this (#1112). If I could create an immutable class without a builder at all and use a protected constructor, that would be sufficient.
I already use

@Value.Style(builderVisibility = Value.Style.BuilderVisibility.PACKAGE,    
             visibility = Value.Style.ImplementationVisibility.PACKAGE)

which is a step forward, but it is missing constructorVisiblilty=PROTECTED and builder="" (no builder).

The @Value.Include and @Value.Nested won't help here. They will result in just the same class (of possibly another package) which will again contain both the value class itself and the constructor.

But that would still not be as good as an generated external *Builder.java class from @Value.Immutable(generateExternalBuilder=true) (or similar), because with my thoughts from above, it would still be a lot of typing and keeping the static builder method in sync with the abstract value class.

@bmarwell
Copy link
Author

This can be closed when #1112 is implemented.

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

No branches or pull requests

2 participants