tonivade / purefun

Functional Programming library for Java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Generate sealed classes using annotation processor

tonivade opened this issue · comments

For example, in Option interface, we want to make sure that only two implementations of Option are available, Some and None.

Right now I'm doing a trick to forbid other classes may implement the Option interface.

@HigherKind
public interface Option extends OptionOf<T> {

  OptionModule getModule();

  final class Some implements Option<T> {
      //...
      public OptionModule getModule() {
         throw new UnsupportedOperationException();
      }
  }

  final class None implements Option<T> {
      //...
      public OptionModule getModule() {
         throw new UnsupportedOperationException();
      }
  }
}

interface OptionModule {}

OptionModule is not visible outside, so you cannot implement this interface outside this package.

But I think it's possible to implement the same using annotation processing.

@HigherKind(sealed = true)
public interface Option extends OptionOf<T> {

  //..

  final class Some implements SealedOption<T> {
    //...
  }

  final class None implements SealedOption<T> {
      //...
  }
}

The this code will be generated

public interface OptionOf<T> extends Kind<Option_, T> {

  SealedOption<T> youShallNotPass();

  //...
}

// package private
interface SealedOption<T> extends Option<T> {
  @Override
  default SealedOption<T> youShallNotPass() {
    throw new UnsupportedOperationException();
  }
}

This way, if you try to implement Option outside, the compiler will fail, because SealedOption<T> is not visible.