Lombok: [FEATURE] Class-level type aliases

Created on 15 Feb 2021  路  9Comments  路  Source: projectlombok/lombok

Overview

Provide an annotation to define class-level type aliases.

Overview

In the latter text the annotation will be referenced as @Type although the name for it is obviously a subject for discussion.

An alias may be added for a specific type at the scope of current .java file using the pseudo-field form:

@Type ${aliased_type} ${alias_name};

Which would result in all usages of ${alias_name} be replaced with ${aliased_type}.

The pseudo-field used for the expression should be removed while processing the annotation.

Aliasing should happen from top to bottom, i.e. a type alias may reference other type aliases defined above.

Illustration

With Lombok

public class Example {
    @Type User<? extends UserData> User;
    @Type Result<User, ? extends UserException> UserResult;
    @Type Map<UUID, ? extends UserData> Users;
    @Type Result<Users, ? extends UserException> UsersResult;

    public UserResult getUserByUuid(final UUID uuid) { /* body */ }

    public UsersResult getUsers() { /* body */ }

    public Users usersOr(final Supplier<? extends Users> defaultSupplier) { /* body*/ }
}

Vanilla Java

public class Example {

    public Result<User<? extends UserData>, ? extends UserException> getUserByUuid(final UUID uuid) { /* body */ }

    public Result<Map<UUID, ? extends UserData>, ? extends UserException> getUsers() { /* body */ }

    public Map<UUID, ? extends UserData> usersOr(final Supplier<? extends Map<UUID, ? extends UserData>> defaultSupplier) { /* body*/ }
}

Annotation prototype

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}

Target audience

  • Library and application developers intensively using generics and type annotations
  • Developers having to deal with duplicate class names from different sources in the same classes

Pros

  • May significantly reduce code-size in classes intensively using generics and type annotations
  • May significantly reduce code-size in cases when two different classes with the same name are referenced in the same class.

Cons

  • May be hard to read (although the type-defs are onlu visible at project level thus outside users of the API will see actual types)
  • May be hard to integrate into IDEs
  • May not be as popular on small projects

Subjects to discuss

  • Configurability: which configuration (if any) should be provided for this annotation (both as its parameters and as entries of lombok.config)
  • Syntax: altough current syntax seems to be the most obvious (personally) other variants may also be applicable, e.g. @Type(name = "${alias_name}", target = "${aliased_type}" on the class (same scoping rules as with @ExtensionMethod)
  • Scoping: should this syntax be allowed inside of methods
  • Generics on type aliases: can and should the support be implemented for type aliases to have generics on themselves, for example:

    @Type(generics = {"T", "R"}) Function<T, R> MyFun;
    
    public <S> MyFun<S, String> foo() { /* body */ }
    
    public static <T, S, R> MyFun<T, R> join(final MyFun<T, S> f1,
                                           final MyFun<S, R> f2) { /* body */ }
    

Links

Most helpful comment

I was curious why it doesn't work properly and figured out that there was a error in my initial test and now it works without an additional eclipse patch :smile:
img

All 9 comments

A handy thing, it would be nice to see it in Lombok

I can't imagine how to live without it

I will eat my socks if it appears in Lombok

+1, a very useful thing for those who work a lot with generics.

Thanks for taking the time to write up such a thoughtful feature request.

I like the idea but I'm not sure if the benefits outweigh the costs. The compilation itself works in ecj and javac but as already mentioned in your cons section this does not work properly in eclipse without adding some additional patches, at least auto complete does not work at all. Writing and maintaining these patches is quite time consuming and annoying because right now there is no way to test them without starting eclipse. @rzwitserloot worked on something similar years ago so there might be something that can be reused.

I was curious why it doesn't work properly and figured out that there was a error in my initial test and now it works without an additional eclipse patch :smile:
img

I was curious why it doesn't work properly and figured out that there was a error in my initial test and now it works without an additional eclipse patch


img

img

Wow, it looks great!

It is just a proof of concept, there are a bunch of cases that are not handled properly and there is no error handling at all.

It is just a proof of concept, there are a bunch of cases that are not handled properly and there is no error handling at all.

Anyway, it looks really interesting and promising. Is there any branch of yours at which this concept can be seen?

Was this page helpful?
0 / 5 - 0 ratings