adt4j - Algebraic Data Types for Java

Overview

adt4j - Algebraic Data Types for Java

This library implements Algebraic Data Types for Java.
ADT4J provides annotation processor for @GenerateValueClassForVisitor annotation.
ADT4J generates new class for each @GenerateValueClassForVisitor annotation.

It allows you to easily define custom data types. Like this:

// Define Expression data type
@WrapsGeneratedValueClass(visitor = ExpressionVisitor.class)
// ExpressionBase class will be automatically generated by annotation processor
// You can use any other name instead of ExpressionBase, like VeryLongNameThatYouShouldNeverActuallyUse
class Expression extends ExpressionBase {
  public static void main(String[] args) {
    // Static constructor methods are automatically generated for Expression class
    Expression e = mul(sum(lit(5), lit(1)), lit(2));

    // Reasonable default toString implementation is provided:
    System.out.println(e + " = " + e.eval());
  }

  // This is the required boilerplate for wrapper-class
  Expression(ExpressionBase base) {
    super(base);
  }

  // Example of "pattern-matching"
  int eval() {
    return accept(new ExpressionVisitor<Integer>() {
      Integer lit(int i) {
        return i;
      }
      Integer sum(Expression e1, Expression e2) {
        return e1.eval() + e2.eval();
      }
      Integer mul(Expression e1, Expression e2) {
        return e1.eval() * e2.eval();
      }
    });
  }

  // Actual data-type definition
  // Data type is recursive. No special treatment of recursive definition is required.
  @GenerateValueClassForVisitor(wrapperClass = Expression.class)
  @Visitor(resultVariableName="R")
  interface ExpressionVisitor<R> {
    @GeneratePredicate(name = "isLiteral");
    R lit(int i);

    R sum(@Getter(name = "leftOperand") Expression e1, @Getter(name = "rightOperand") Expression e2);
    R mul(@Getter(name = "leftOperand") Expression e1, @Getter(name = "rightOperand") Expression e2);
  }

}

Features

  • Support recursive data types
  • Generate hashCode, equals and toString implementations with value semantics
  • Generate predicates, getters and "updaters" with additional annotations
  • Fully customizable API: custom names and access levels for generated methods
  • Optionally generate Comparable implementation with precise compile-time type-check if it is possible
  • Optionally generate serializable classes with precise compile-time type-check if it is possible
  • Sensible error messages
  • Support generated class extention through standard Java's inheritance.
  • Reasonably fast

Known Issues

License

ADT4J is under BSD 3-clause license.

Flattr

Flattr this git repo

Installation

Use maven dependency to use ADT4J:

<dependency>
  <groupId>com.github.sviperll</groupId>
  <artifactId>adt4j</artifactId>
  <version>3.2</version>
</dependency>

You can use adt4j-shaded artifact to simplify deployment and to avoid dependencies' conflicts. adt4j-shaded has no dependencies and does not pollute classpath. All java-packages provided by adt4j-shaded are rooted at com.github.sviperll.adt4j package.

<dependency>
  <groupId>com.github.sviperll</groupId>
  <artifactId>adt4j-shaded</artifactId>
  <version>3.2</version>
</dependency>

Changelog

See NEWS file.

Usage

See Tutorial

Build

$ git clone [email protected]:sviperll/adt4j.git
$ cd adt4j
$ mvn test

Check for errors and warnings.

ADT4J is built to be compatible with Java 7. See universal-maven-parent project's documentation for instructions about building projects compatible with JDK7.

Comments
  • HashCode improvements

    HashCode improvements

    The default value for valueClassHashCodeBase should probably be a prime number (currently 27). (I suggest using 1000005, since autovalue (from google) use 1000003 and adt4j is strictly superior ;) Also maybe ^ should be used instead of + for a more uniform distribution of hashcodes.

    fixed 
    opened by jbgi 23
  • Unable to compile

    Unable to compile

    I notice that the project can no longer be compiled:

    <parent>
        <groupId>com.github.sviperll</groupId>
        <artifactId>sviperll-maven-parent-6</artifactId>
        <version>3.2-SNAPSHOT</version>
    </parent>
    

    Where can we clone this parent POM to get the required SNAPSHOT, switching to use 3.1 works, but then the project itself fails.

    [ERROR] Failed to execute goal on project adt4j: Could not resolve dependencies for project com.github.sviperll:adt4j:jar:0.15-SNAPSHOT: Could not find artifact
     com.github.sviperll:metachicory:jar:0.19-SNAPSHOT in Nexus (http://nexus.smxemail.com/nexus/content/groups/public/) -> [Help 1]
    

    Cloning the chicory repo ( and changing its parent ) allows everything to compile. Is there anything preventing the parent from being released?

    fixed 
    opened by talios 17
  • Mixing ADT4j and Immutables: Strange jcodemodel issue mixing generated classes

    Mixing ADT4j and Immutables: Strange jcodemodel issue mixing generated classes

    For some reason, when I updated one of our ADT4j (3.1) based types to include a reference to an interface that's built using immutables.github.io ( generated in the same project ) the following deep internal error occurs.

    If I use the ImmutableNNNN generated variant of the class the problem goes away, but then just causes issues further in the code base.

    It looks like ADT4j may not be not liking that Immutables use inner-interfaces.

    [ERROR] java.lang.IllegalStateException: Inner class should always be defined if outer class is defined: inner class org.immutables.value.Value.Immutable, enclosing class com.helger.jcodemodel.JDefinedClass(org.immutables.value.Value) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.getClass(DecidedErrorTypesModelsAdapter.java:177) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.ref(DecidedErrorTypesModelsAdapter.java:289) [ERROR] at com.helger.jcodemodel.meta.TypeMirrorToJTypeVisitor.visitDeclared(TypeMirrorToJTypeVisitor.java:143) [ERROR] at com.helger.jcodemodel.meta.TypeMirrorToJTypeVisitor.visitDeclared(TypeMirrorToJTypeVisitor.java:68) [ERROR] at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:944) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.toJType(DecidedErrorTypesModelsAdapter.java:298) [ERROR] at com.helger.jcodemodel.meta.Annotator.annotate(Annotator.java:97) [ERROR] at com.helger.jcodemodel.meta.Annotator.annotate(Annotator.java:89) [ERROR] at com.helger.jcodemodel.meta.ClassFiller.fillClass(ClassFiller.java:85) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.defineTopLevelClass(DecidedErrorTypesModelsAdapter.java:227) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.defineClass(DecidedErrorTypesModelsAdapter.java:191) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.getClass(DecidedErrorTypesModelsAdapter.java:161) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.ref(DecidedErrorTypesModelsAdapter.java:289) [ERROR] at com.helger.jcodemodel.meta.TypeMirrorToJTypeVisitor.visitDeclared(TypeMirrorToJTypeVisitor.java:143) [ERROR] at com.helger.jcodemodel.meta.TypeMirrorToJTypeVisitor.visitDeclared(TypeMirrorToJTypeVisitor.java:68) [ERROR] at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:944) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.toJType(DecidedErrorTypesModelsAdapter.java:298) [ERROR] at com.helger.jcodemodel.meta.TypeMirrorToJTypeVisitor.visitDeclared(TypeMirrorToJTypeVisitor.java:146) [ERROR] at com.helger.jcodemodel.meta.TypeMirrorToJTypeVisitor.visitDeclared(TypeMirrorToJTypeVisitor.java:68) [ERROR] at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:944) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.toJType(DecidedErrorTypesModelsAdapter.java:298) [ERROR] at com.helger.jcodemodel.meta.ClassFiller.fillClass(ClassFiller.java:143) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.defineTopLevelClass(DecidedErrorTypesModelsAdapter.java:227) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.defineClass(DecidedErrorTypesModelsAdapter.java:191) [ERROR] at com.helger.jcodemodel.meta.DecidedErrorTypesModelsAdapter.getClass(DecidedErrorTypesModelsAdapter.java:161) [ERROR] at com.helger.jcodemodel.meta.JCodeModelJavaxLangModelAdapter.getClass(JCodeModelJavaxLangModelAdapter.java:145) [ERROR] at com.helger.jcodemodel.meta.JCodeModelJavaxLangModelAdapter.getClassWithErrorTypes(JCodeModelJavaxLangModelAdapter.java:109) [ERROR] at com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor$ElementProcessor.processStage0(GenerateValueClassForVisitorProcessor.java:202) [ERROR] at com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor$ElementProcessor.generateClassesWithErrors(GenerateValueClassForVisitorProcessor.java:127) [ERROR] at com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor$ElementProcessor.generateClassesWithoutErrors(GenerateValueClassForVisitorProcessor.java:139) [ERROR] at com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor.process(GenerateValueClassForVisitorProcessor.java:109) [ERROR] at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794) [ERROR] at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705) [ERROR] at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91) [ERROR] at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035) [ERROR] at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176) [ERROR] at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170) [ERROR] at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856) [ERROR] at com.sun.tools.javac.main.Main.compile(Main.java:523) [ERROR] at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129) [ERROR] at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138) [ERROR] at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:125) [ERROR] at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:171) [ERROR] at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:886) [ERROR] at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129) [ERROR] at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134) [ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207) [ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153) [ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145) [ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116) [ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80) [ERROR] at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51) [ERROR] at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128) [ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307) [ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193) [ERROR] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106) [ERROR] at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863) [ERROR] at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288) [ERROR] at org.apache.maven.cli.MavenCli.main(MavenCli.java:199) [ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [ERROR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [ERROR] at java.lang.reflect.Method.invoke(Method.java:498) [ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) [ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) [ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) [ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) [ERROR] -> [Help 1]

    opened by talios 11
  • Support for default values

    Support for default values

    Often, I'm finding I'd like to define some default values, which would be used in conjunction with an @Updater annotation, which would be elided from the constructor method for a type, something like:

    R standard(String name, @Updater("titled") String title,
      @DefaultValue("false") @Updater("hidden") boolean hidden,
      @DefaultValue("false") @Updater("grouped") boolean grouped,
      @DefaultValue("FieldSortOrder.NATURAL") @Updater("sortedBy") FieldSortOrder sortOrder);
    

    Would generate a method to be called in a manner such as:

    MyValue.standard("name", "title")
                  .sortedBy(FieldSortOrder.ASCENDING);
    

    Currently, I'm writing wrapping functions in another class that do just this, and I'm torn between whether this should lifted into a generic facility of ADJ4J or not.

    Thoughts?

    wontfix no-api 
    opened by talios 11
  • Provide support for base interfaces/classes.

    Provide support for base interfaces/classes.

    This allows for providing abstractions over common disparate ADT values, and offering a simple way of providing extension methods directly on the generated value classes.

    I'm not 100% happy with using String's to refer to the baseClass or baseInterface attributes ( you can see the example in the BaseOptionalVisitor.java file, but it's been a long since I've use JCodeModel or written an annotation processor so not sure if it's possible to refer to the .class objects directly here ( and fall into the type mirrors API ) so maybe you have some better ideas/thoughts.

    Basically, this gives ADT4j the ability to declare a base/marker interface for the generated value class, which would allow for some common abstractions to be implemented. As part of this change the generic declaration for the exception type is moved down to the accept method, otherwise the base class can't provide an generified instance of of a visitor.

    All tests as they are continue to pass.

    opened by talios 7
  • Reuse visitor instances in getter methods

    Reuse visitor instances in getter methods

    String getName() {
        return this.accept(new UserVisitor<String>() {
            @Override
            public String of(String name, int age) {
                return name;
            }
        });
    }
    

    should probably become

    private static final UserVisitor<String> GET_NAME_VISITOR = new UserVisitor<String>() {
         @Override
         public String of(String name, int age) {
             return name;
         }
     };
    String getName() {
        return this.accept(GET_NAME_VISITOR);
    }
    

    in generated code

    fixed 
    opened by sviperll 7
  • java.lang.NoClassDefFoundError: javax/annotation/ParametersAreNonnullByDefault: javax.annotation.ParametersAreNonnullByDefault

    java.lang.NoClassDefFoundError: javax/annotation/ParametersAreNonnullByDefault: javax.annotation.ParametersAreNonnullByDefault

    When using the shaded artifact in a project with no other dependencies, the code generator says:

    Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-compile) on project adt4j_test: Fatal error compiling
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
    Caused by: org.apache.maven.plugin.MojoExecutionException: Fatal error compiling
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:836)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        ... 20 more
    Caused by: org.codehaus.plexus.compiler.CompilerException: java.lang.NoClassDefFoundError: javax/annotation/ParametersAreNonnullByDefault
        at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:172)
        at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:169)
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:825)
        ... 23 more
    Caused by: java.lang.RuntimeException: java.lang.NoClassDefFoundError: javax/annotation/ParametersAreNonnullByDefault
        at com.sun.tools.javac.main.Main.compile(Main.java:553)
        at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
        at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
        at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:125)
        ... 25 more
    Caused by: java.lang.NoClassDefFoundError: javax/annotation/ParametersAreNonnullByDefault
        at com.github.sviperll.adt4j.internal.com.github.sviperll.adt4j.model.ValueClassModelFactory.createValueClass(ValueClassModelFactory.java:149)
        at com.github.sviperll.adt4j.internal.com.github.sviperll.adt4j.model.ValueClassModelFactory.createValueClass(ValueClassModelFactory.java:67)
        at com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor.processElements(GenerateValueClassForVisitorProcessor.java:101)
        at com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor.process(GenerateValueClassForVisitorProcessor.java:85)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
        at com.sun.tools.javac.main.Main.compile(Main.java:523)
        ... 28 more
    Caused by: java.lang.ClassNotFoundException: javax.annotation.ParametersAreNonnullByDefault
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 40 more
    

    An example project here reproduces it:

    https://github.com/io7m/adt4j_test

    fixed 
    opened by io7m 5
  • Add support for multiple predicates

    Add support for multiple predicates

    I have a case where ideally I want to have multiple predicates defined for a value.

    I have a ResultVisitor with states such as succeed, succeedWithValue, noop, failure. And want to have predicates like isSuccess (noop, suceed, succeedWithValue) and hasRollback (suceed, suceedWithValue ).

    Currently I have to split these with an isFailure on the failure case.

    Thoughts?

    fixed 
    opened by talios 5
  • Generate sensible implementation of toString()

    Generate sensible implementation of toString()

    given visitor interface: interface ListVisitor<T, S, R> { R cons(T head, S tail); R nil();}

    I would like List.toString() to return:

    • "cons{head=<...>, tail=<...>}"
    • "nil{}" (or maybe just "nil")

    ...and capitalization of first letter could be a good idea (maybe?)

    fixed 
    opened by jbgi 5
  • Use JavaPoet instead of JCodeModel?

    Use JavaPoet instead of JCodeModel?

    I find JavaPoet - https://github.com/square/javapoet - API (much) easier, it is much more popular. I suspect using it in adt4j could simplify a great deal of code and should make life easier for external contributors (like me ;-). The only problem is that it require jdk 7. but now that even jdk7 is no more publicly supported by Oracle, I think it could be the right time to left out jdk6 support in a next major release or so. What do you think? // cc @talios

    wontfix too-hard 
    opened by jbgi 4
  • universal-maven-parent not deployed to Central

    universal-maven-parent not deployed to Central

    Hello.

    I attempted to use 3.0-rc1 today, but discovered that the parent of the adt4j-maven-parent project isn't in Maven Central yet, and so the package can't be used.

    Failed to collect dependencies at com.github.sviperll:adt4j-shaded:jar:3.0-rc1: Failed to read artifact descriptor for com.github.sviperll:adt4j-shaded:jar:3.0-rc1: Could not find artifact com.github.sviperll:universal-maven-parent:pom:0.18

    fixed 
    opened by io7m 3
  • Including adt4j on the annotation class path yields errors

    Including adt4j on the annotation class path yields errors

    Restructuring my build and when I add adt4j to the annotation class path I get the following error:

    [ERROR] Unexpected exception. This seems like a bug in ADT4J, please report it at 
    https://github.com/sviperll/adt4j/issues with the following details:
    [ERROR]   com.sun.tools.javac.code.Symbol$CompletionFailure: class file for 
    org.joda.convert.FromString not found
    

    My project doesn't include joda-convert anywhere, I tried including it's jar also on the annotation classpath to no joy, and also adding it as a direct dependency of the maven-compiler-plugin but also no joy.

    opened by talios 2
  • Deep pattern-matching

    Deep pattern-matching

    Following @nobeh comment in #15

    Let's consider this psuedo/modelling code:

    data Map<A, B> = EmptyMap | InsertAssoc(Pair<A, B>, Map<A, B>);
    

    which defines a Map data structure in ADT composed of an EmptyMap and an InsertAssoc operation. And, it is quite straightforward to map the above to:

    @GenerateValueClassForVisitor
    @Visitor(selfReferenceVariableName = "SELF", resultVariableName = "M")
    public interface MapVisitor<M,SELF,A,B> {
      M EmptyMap();
      M InsertAssoc(Pair<A, B> argPair, SELF argMap);
    }
    

    Now, I have a different challenge to deal with, which generally is under the class of "pattern matching" which is addressed in this library by using the visitor pattern. Consider the following:

    def Map<A, B> put(Map<A, B> ms, A k, B v) =
      case ms {
        EmptyMap => InsertAssoc(Pair(k, v), EmptyMap);
        InsertAssoc(Pair(k_, v_), ts) => if (k == k_)
          then
            InsertAssoc(Pair(k_, v), ts)     
          else 
            InsertAssoc(Pair(k_, v_), put_(ts, k, v))
          ;
      };
    

    The above is a put function that defines how to an insert operation to a Map. My question is how would you generally translate this example of pattern matching with deep matching structure to a visitor pattern?

    I thought that this might be relevant into this ticket but if not, please feel free to move into a new ticket.

    opened by sviperll 6
  • Support existential types

    Support existential types

    Allow definitions like this:

    interface SomeVisitor<T, R> {
        <U extends Callable<T> & Serializable> R callable(U callable);
        R immediate(T value);
    }
    

    So we can write

    int eval(SomeValue<Integer> value) {
        return value.accept(new SomeVisitor<Integer, Integer>() {
            <U extends Callable<Integer> & Serializable> Integer callable(U callable) {
                return callable.call();
            }
            Integer immediate(Integer value) {
                return value;
            }
        });
    }
    

    This will pave the way to GADT support #15

    opened by sviperll 0
  • Implement polymorphic updates

    Implement polymorphic updates

    This should work...

        Optional<Integer> i = flag ? Optional.present(5) : Optional.missing();
        Optional<String> m = i.withValue("5"); // Generated updater method
    
    opened by sviperll 0
  • Generate implementation of Isomorphism or TypeStructure[2,3,4] from chicory library

    Generate implementation of Isomorphism or TypeStructure[2,3,4] from chicory library

    Allow to optionally generate implementation of Isomorphism or TypeStructure[2,3,4] from chicory library to use for structure-generic transformations (like ORM or serialization) on generated value-classes.

    opened by sviperll 0
  • Implement nested-cases

    Implement nested-cases

    Suppose that you have a class that represents HTTP-endpoints

    Like this:

        interface URLVisitor<R> {
            R userIndex();
            R user(int id);
            R postIndex(int userID);
            R post(int postID);
        }
    

    During the application evolution it can be desired to refactor above visitor into nested visitors, like this:

        interface URLVisitor<R> {
            R userIndex();
            UserURLVisitor<R> user(int id);
        }
    
        interface UserURLVisitor<R> {
            R user();
            R postIndex();
            R post(int id);
        }
    

    We should probably allow such definitions for ADT4J and generate sensible factory and accept methods:

        URL url = URL.factory().user(123).post(1);
    
    opened by sviperll 0
Releases(adt4j-2.0.1)
  • adt4j-2.0.1(Aug 11, 2015)

  • adt4j-1.3(Jun 10, 2015)

    Add hashCodeCaching parameter to @GenerateValueClassForVisitor annotation to support hash code caching, see RecordVisitor, GroupNameVisitor, UserKeyVisitor and Expression examples.

    Source code(tar.gz)
    Source code(zip)
  • adt4j-1.2(Jun 10, 2015)

  • adt4j-1.1(Jun 10, 2015)

    • As little information from source code as possible is used during code generation. It's now possible to define fully customized single file data-type definitions, see Either example.
    • metachicory is not required at runtime, since @Visitor-annotation retention is set to SOURCE now. ADT4J has no run-time dependencies now.
    Source code(tar.gz)
    Source code(zip)
  • adt4j-1.0(Jun 10, 2015)

    • Add default names for generated getters, updaters and predicates. Allow to omit name parameter.
    • API-breaking change: rename value argument to name argument of @Getter, @Updater and @GeneratePredicate annotations
    • API-breaking change: use com.github.sviperll.meta.Visitor annotation from metachicory package.
    • Add dependency to metachicory package which provides some generic metaprogramming support.
    Source code(tar.gz)
    Source code(zip)
Owner
Victor Nazarov
I've actually started programming by writing BASIC programs for my dad's scientific calculator.
Victor Nazarov
A Java API for generating .java source files.

JavaPoet JavaPoet is a Java API for generating .java source files. Source file generation can be useful when doing things such as annotation processin

Square 10k Dec 29, 2022
A collection of source code generators for Java.

Auto A collection of source code generators for Java. Auto‽ Java is full of code that is mechanical, repetitive, typically untested and sometimes the

Google 10k Jan 5, 2023
Automatic generation of the Builder pattern for Java

FreeBuilder Automatic generation of the Builder pattern for Java 1.8+ The Builder pattern is a good choice when designing classes whose constructors o

inferred.org 797 Dec 19, 2022
Java library to provide an API for beans and properties.

Joda-Beans Joda-Beans provides a small framework that adds properties to Java, greatly enhancing JavaBeans. An API is provided that defines a bean and

Joda.org 137 Nov 25, 2022
Very spicy additions to the Java programming language.

Project Lombok Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another g

Reinier Zwitserloot 11.7k Jan 1, 2023
Source Code for BlueEagle jRAT & Release ☄ 📏☣✒Blue Eagle jRAT is a cross platform RAT tool (java RAT) / (jRAT)

Source Code for BlueEagle jRAT & Release ☄ ??☣✒Blue Eagle jRAT is a cross platform RAT tool (java RAT) / (jRAT) which is { [Windows RAT] [Linux RAT] [MAC RAT] } which is fully programmed in java be a user friendly and easy to use and builds out trojans (.jar) and controls the victims running those trojans on same port at same time ,this tool is fully in java (Client & Server in java) and this tool is now registerd to be free , and on the user responsibility

SaherBlueEagle 25 Sep 26, 2022
Java 8 annotation processor and framework for deriving algebraic data types constructors, pattern-matching, folds, optics and typeclasses.

Derive4J: Java 8 annotation processor for deriving algebraic data types constructors, pattern matching and more! tl;dr Show me how to write, say, the

null 543 Nov 23, 2022
Java 8 annotation processor and framework for deriving algebraic data types constructors, pattern-matching, folds, optics and typeclasses.

Derive4J: Java 8 annotation processor for deriving algebraic data types constructors, pattern matching and more! tl;dr Show me how to write, say, the

null 543 Nov 23, 2022
Generate Java types from JSON or JSON Schema and annotates those types for data-binding with Jackson, Gson, etc

jsonschema2pojo jsonschema2pojo generates Java types from JSON Schema (or example JSON) and can annotate those types for data-binding with Jackson 2.x

Joe Littlejohn 5.9k Jan 5, 2023
MathParser - a simple but powerful open-source math tool that parses and evaluates algebraic expressions written in pure java

MathParser is a simple but powerful open-source math tool that parses and evaluates algebraic expressions written in pure java. This projec

AmirHosseinAghajari 40 Dec 24, 2022
Rekex parser generator - grammar as algebraic datatypes

Rekex PEG parser generator for Java 17 grammar as algebraic datatypes A context-free grammar has the form of A = A1 | A2 A1 = B C ... which looks ex

Zhong Yu 41 Dec 18, 2022
A distributed data integration framework that simplifies common aspects of big data integration such as data ingestion, replication, organization and lifecycle management for both streaming and batch data ecosystems.

Apache Gobblin Apache Gobblin is a highly scalable data management solution for structured and byte-oriented data in heterogeneous data ecosystems. Ca

The Apache Software Foundation 2.1k Jan 4, 2023
A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back

A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back, with a transparent support of any kind of self-references and with a full Java 9 compatibility.

Andrey Mogilev 9 Dec 30, 2021
An annotation-based Java library for creating Thrift serializable types and services.

Drift Drift is an easy-to-use, annotation-based Java library for creating Thrift clients and serializable types. The client library is similar to JAX-

null 225 Dec 24, 2022
Tools for working with generic types

TypeTools A simple, zero-dependency library for working with types. Supports Java 1.6+ and Android. Introduction One of the sore points with Java invo

Jonathan Halterman 585 Jan 9, 2023
Hi, Spring fans! In this installment, we're going to look at some the C in M-V-C and their representation in Spring's `@Controller` types!

@Controllers Hi, Spring fans! In this installment, we're going to look at some the C in M-V-C and their representation in Spring's @Controller types!

Spring Tips 22 Nov 19, 2022
The Apache Commons CSV library provides a simple interface for reading and writing CSV files of various types.

Apache Commons CSV The Apache Commons CSV library provides a simple interface for reading and writing CSV files of various types. Documentation More i

The Apache Software Foundation 307 Dec 26, 2022
SpringBoot based return value types are supported by browsers

SpringBoot based return value types are supported by browsers

Elone Hoo 5 Jun 24, 2022