Skip to content

Commit e9f235e

Browse files
authored
Merge pull request #38 from andyglow/super-interfaces
allow ADT members to implement extra interfaces
2 parents 7a91307 + 475e915 commit e9f235e

7 files changed

Lines changed: 229 additions & 4 deletions

File tree

dataenum-processor/src/main/java/com/spotify/dataenum/processor/data/OutputSpec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class OutputSpec extends Spec {
3131
private final Iterable<OutputValue> outputValues;
3232

3333
public OutputSpec(Spec input, ClassName outputClass, Iterable<OutputValue> outputValues) {
34-
super(input.specClass(), input.typeVariables(), input.values());
34+
super(input.specClass(), input.typeVariables(), input.superInterfaces(), input.values());
3535
this.outputClass = outputClass;
3636
this.outputValues = outputValues;
3737
}

dataenum-processor/src/main/java/com/spotify/dataenum/processor/data/Spec.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,17 @@
3232
public class Spec {
3333
private final ClassName specClass;
3434
private final Iterable<TypeVariableName> typeVariables;
35+
private final Iterable<ClassName> interfaces;
3536
private final Iterable<Value> values;
3637

3738
public Spec(
38-
ClassName specClass, Iterable<TypeVariableName> typeVariables, Iterable<Value> values) {
39+
ClassName specClass,
40+
Iterable<TypeVariableName> typeVariables,
41+
Iterable<ClassName> interfaces,
42+
Iterable<Value> values) {
3943
this.specClass = specClass;
4044
this.typeVariables = typeVariables;
45+
this.interfaces = interfaces;
4146
this.values = values;
4247
}
4348

@@ -49,6 +54,10 @@ public Iterable<TypeVariableName> typeVariables() {
4954
return typeVariables;
5055
}
5156

57+
public Iterable<ClassName> superInterfaces() {
58+
return interfaces;
59+
}
60+
5261
public boolean hasTypeVariables() {
5362
return !Iterables.isEmpty(typeVariables());
5463
}

dataenum-processor/src/main/java/com/spotify/dataenum/processor/generator/spec/SpecTypeFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public static TypeSpec create(
7777
"value", CodeBlock.of("$S", DataEnumProcessor.class.getCanonicalName()))
7878
.build())
7979
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
80-
.addTypeVariables(spec.typeVariables());
80+
.addTypeVariables(spec.typeVariables())
81+
.addSuperinterfaces(spec.superInterfaces());
8182

8283
// add constructor with correct access
8384
enumBuilder.addMethod(

dataenum-processor/src/main/java/com/spotify/dataenum/processor/parser/SpecParser.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@
2525
import com.squareup.javapoet.TypeVariableName;
2626
import java.util.ArrayList;
2727
import java.util.List;
28+
import java.util.stream.Collectors;
2829
import javax.annotation.processing.Messager;
2930
import javax.annotation.processing.ProcessingEnvironment;
3031
import javax.lang.model.element.Element;
3132
import javax.lang.model.element.ElementKind;
3233
import javax.lang.model.element.TypeElement;
3334
import javax.lang.model.element.TypeParameterElement;
35+
import javax.lang.model.type.DeclaredType;
3436
import javax.tools.Diagnostic;
3537

3638
public final class SpecParser {
@@ -53,12 +55,17 @@ public static Spec parse(Element element, ProcessingEnvironment processingEnv) {
5355
typeVariableNames.add(TypeVariableName.get(typeParameterElement));
5456
}
5557

58+
List<ClassName> interfaces =
59+
dataEnum.getInterfaces().stream()
60+
.map(x -> ClassName.get((TypeElement) ((DeclaredType) x).asElement()))
61+
.collect(Collectors.toList());
62+
5663
List<Value> values = ValuesParser.parse(dataEnum, processingEnv);
5764
if (values == null) {
5865
return null;
5966
}
6067

6168
ClassName enumInterface = ClassName.get(dataEnum);
62-
return new Spec(enumInterface, typeVariableNames, values);
69+
return new Spec(enumInterface, typeVariableNames, interfaces, values);
6370
}
6471
}

dataenum-processor/src/test/java/com/spotify/dataenum/processor/IntegrationTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,9 @@ public void shouldCopyDocFromCaseSourceToJavadocCommentOnFactoryMethod() {
279279
public void shouldCopyAnnotationsFromCaseSourceToFactoryMethod() {
280280
assertThatEnumGeneratedMatchingFile("annotation/Annotation", "annotation/MyAnnotation.java");
281281
}
282+
283+
@Test
284+
public void superInterfaces() {
285+
assertThatEnumGeneratedMatchingFile("SuperInterfaces");
286+
}
282287
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
* -\-\-
3+
* DataEnum
4+
* --
5+
* Copyright (c) 2017 Spotify AB
6+
* --
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* -/-/-
19+
*/
20+
import static com.spotify.dataenum.DataenumUtils.checkNotNull;
21+
22+
import com.spotify.dataenum.function.Consumer;
23+
import com.spotify.dataenum.function.Function;
24+
import java.io.Serializable;
25+
import java.lang.Integer;
26+
import java.lang.Object;
27+
import java.lang.Override;
28+
import java.lang.String;
29+
import java.lang.StringBuilder;
30+
import javax.annotation.Generated;
31+
import javax.annotation.Nonnull;
32+
33+
/**
34+
* Generated from {@link SuperInterfaces_dataenum}
35+
*/
36+
@Generated("com.spotify.dataenum.processor.DataEnumProcessor")
37+
public abstract class SuperInterfaces implements Serializable {
38+
SuperInterfaces() {
39+
}
40+
41+
/**
42+
* @return a {@link Value1} (see {@link SuperInterfaces_dataenum#Value1} for source)
43+
*/
44+
public static SuperInterfaces value1(@Nonnull String msg) {
45+
return new Value1(msg);
46+
}
47+
48+
/**
49+
* @return a {@link Value2} (see {@link SuperInterfaces_dataenum#Value2} for source)
50+
*/
51+
public static SuperInterfaces value2(@Nonnull String msg, int code) {
52+
return new Value2(msg, code);
53+
}
54+
55+
public final boolean isValue1() {
56+
return (this instanceof Value1);
57+
}
58+
59+
public final boolean isValue2() {
60+
return (this instanceof Value2);
61+
}
62+
63+
public final Value1 asValue1() {
64+
return (Value1) this;
65+
}
66+
67+
public final Value2 asValue2() {
68+
return (Value2) this;
69+
}
70+
71+
public abstract void match(@Nonnull Consumer<Value1> value1, @Nonnull Consumer<Value2> value2);
72+
73+
public abstract <R_> R_ map(@Nonnull Function<Value1, R_> value1,
74+
@Nonnull Function<Value2, R_> value2);
75+
76+
public static final class Value1 extends SuperInterfaces {
77+
private final String msg;
78+
79+
Value1(String msg) {
80+
this.msg = checkNotNull(msg);
81+
}
82+
83+
@Nonnull
84+
public final String msg() {
85+
return msg;
86+
}
87+
88+
@Override
89+
public boolean equals(Object other) {
90+
if (other == this) return true;
91+
if (!(other instanceof Value1)) return false;
92+
Value1 o = (Value1) other;
93+
return o.msg.equals(this.msg);
94+
}
95+
96+
@Override
97+
public int hashCode() {
98+
int result = 0;
99+
return result * 31 + this.msg.hashCode();
100+
}
101+
102+
@Override
103+
public String toString() {
104+
StringBuilder builder = new StringBuilder();
105+
builder.append("Value1{msg=").append(this.msg);
106+
return builder.append('}').toString();
107+
}
108+
109+
@Override
110+
public final void match(@Nonnull Consumer<Value1> value1, @Nonnull Consumer<Value2> value2) {
111+
value1.accept(this);
112+
}
113+
114+
@Override
115+
public final <R_> R_ map(@Nonnull Function<Value1, R_> value1,
116+
@Nonnull Function<Value2, R_> value2) {
117+
return value1.apply(this);
118+
}
119+
}
120+
121+
public static final class Value2 extends SuperInterfaces {
122+
private final String msg;
123+
124+
private final int code;
125+
126+
Value2(String msg, int code) {
127+
this.msg = checkNotNull(msg);
128+
this.code = code;
129+
}
130+
131+
@Nonnull
132+
public final String msg() {
133+
return msg;
134+
}
135+
136+
public final int code() {
137+
return code;
138+
}
139+
140+
@Override
141+
public boolean equals(Object other) {
142+
if (other == this) return true;
143+
if (!(other instanceof Value2)) return false;
144+
Value2 o = (Value2) other;
145+
return o.code == code
146+
&& o.msg.equals(this.msg);
147+
}
148+
149+
@Override
150+
public int hashCode() {
151+
int result = 0;
152+
result = result * 31 + this.msg.hashCode();
153+
return result * 31 + Integer.valueOf(this.code).hashCode();
154+
}
155+
156+
@Override
157+
public String toString() {
158+
StringBuilder builder = new StringBuilder();
159+
builder.append("Value2{msg=").append(this.msg);
160+
builder.append(", code=").append(this.code);
161+
return builder.append('}').toString();
162+
}
163+
164+
@Override
165+
public final void match(@Nonnull Consumer<Value1> value1, @Nonnull Consumer<Value2> value2) {
166+
value2.accept(this);
167+
}
168+
169+
@Override
170+
public final <R_> R_ map(@Nonnull Function<Value1, R_> value1,
171+
@Nonnull Function<Value2, R_> value2) {
172+
return value2.apply(this);
173+
}
174+
}
175+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* -\-\-
3+
* DataEnum
4+
* --
5+
* Copyright (c) 2017 Spotify AB
6+
* --
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* -/-/-
19+
*/
20+
import com.spotify.dataenum.DataEnum;
21+
import com.spotify.dataenum.dataenum_case;
22+
import java.io.Serializable;
23+
24+
@DataEnum
25+
interface SuperInterfaces_dataenum extends Serializable {
26+
dataenum_case Value1(String msg);
27+
dataenum_case Value2(String msg, int code);
28+
}

0 commit comments

Comments
 (0)