Skip to content

Commit 3a4d4a2

Browse files
author
Leland Takamine
committed
Update SuperficialValidation to validate supertypes and superinterfaces recursively.
1 parent 9f36c57 commit 3a4d4a2

2 files changed

Lines changed: 125 additions & 1 deletion

File tree

common/src/main/java/com/google/auto/common/SuperficialValidation.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.List;
1919
import java.util.Map;
20+
import java.util.stream.Collectors;
2021
import javax.lang.model.element.AnnotationMirror;
2122
import javax.lang.model.element.AnnotationValue;
2223
import javax.lang.model.element.AnnotationValueVisitor;
@@ -63,10 +64,13 @@ public static boolean validateElements(Iterable<? extends Element> elements) {
6364
}
6465

6566
@Override public Boolean visitType(TypeElement e, Void p) {
67+
TypeMirror superclass = e.getSuperclass();
6668
return isValidBaseElement(e)
6769
&& validateElements(e.getTypeParameters())
6870
&& validateTypes(e.getInterfaces())
69-
&& validateType(e.getSuperclass());
71+
&& validateType(superclass)
72+
&& validateElements(e.getInterfaces().stream().map(MoreTypes::asElement).collect(Collectors.toList()))
73+
&& (superclass.getKind() == TypeKind.NONE || validateElement(MoreTypes.asElement(superclass)));
7074
}
7175

7276
@Override public Boolean visitVariable(VariableElement e, Void p) {

common/src/test/java/com/google/auto/common/SuperficialValidationTest.java

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,42 @@ public void handlesRecursiveType() {
199199
.compilesWithoutError();
200200
}
201201

202+
@Test
203+
public void handlesRecursiveSuperinterface() {
204+
JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
205+
"test.TestClass",
206+
"package test;",
207+
"",
208+
"interface TestClass implements TestClass {}");
209+
assertAbout(javaSource())
210+
.that(javaFileObject)
211+
.processedWith(new AssertingProcessor() {
212+
@Override
213+
void runAssertions() {
214+
assertWithMessage("Should not reach annotation processing.").fail();
215+
}
216+
})
217+
.failsToCompile();
218+
}
219+
220+
@Test
221+
public void handlesRecursiveSuperclass() {
222+
JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
223+
"test.TestClass",
224+
"package test;",
225+
"",
226+
"class TestClass extends TestClass {}");
227+
assertAbout(javaSource())
228+
.that(javaFileObject)
229+
.processedWith(new AssertingProcessor() {
230+
@Override
231+
void runAssertions() {
232+
assertWithMessage("Should not reach annotation processing.").fail();
233+
}
234+
})
235+
.failsToCompile();
236+
}
237+
202238
@Test
203239
public void missingWildcardBound() {
204240
JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
@@ -276,6 +312,90 @@ void runAssertions() {
276312
.failsToCompile();
277313
}
278314

315+
@Test
316+
public void missingSuperclass() {
317+
JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
318+
"test.TestClass",
319+
"package test;",
320+
"",
321+
"class TestClass extends Missing {}");
322+
assertAbout(javaSource())
323+
.that(javaFileObject)
324+
.processedWith(new AssertingProcessor() {
325+
@Override
326+
void runAssertions() {
327+
TypeElement testClassElement =
328+
processingEnv.getElementUtils().getTypeElement("test.TestClass");
329+
assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
330+
}
331+
})
332+
.failsToCompile();
333+
}
334+
335+
@Test
336+
public void missingSuperinterface() {
337+
JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
338+
"test.TestClass",
339+
"package test;",
340+
"",
341+
"class TestClass implements Missing {}");
342+
assertAbout(javaSource())
343+
.that(javaFileObject)
344+
.processedWith(new AssertingProcessor() {
345+
@Override
346+
void runAssertions() {
347+
TypeElement testClassElement =
348+
processingEnv.getElementUtils().getTypeElement("test.TestClass");
349+
assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
350+
}
351+
})
352+
.failsToCompile();
353+
}
354+
355+
@Test
356+
public void missingGrandparentSuperclass() {
357+
JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
358+
"test.TestClass",
359+
"package test;",
360+
"",
361+
"class Parent extends Missing {}",
362+
"",
363+
"class TestClass extends Parent {}");
364+
assertAbout(javaSource())
365+
.that(javaFileObject)
366+
.processedWith(new AssertingProcessor() {
367+
@Override
368+
void runAssertions() {
369+
TypeElement testClassElement =
370+
processingEnv.getElementUtils().getTypeElement("test.TestClass");
371+
assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
372+
}
373+
})
374+
.failsToCompile();
375+
}
376+
377+
@Test
378+
public void missingGrandparentSuperinterface() {
379+
JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
380+
"test.TestClass",
381+
"package test;",
382+
"",
383+
"interface Parent extends Missing {}",
384+
"",
385+
"class TestClass implements Parent {}");
386+
assertAbout(javaSource())
387+
.that(javaFileObject)
388+
.processedWith(new AssertingProcessor() {
389+
@Override
390+
void runAssertions() {
391+
TypeElement testClassElement =
392+
processingEnv.getElementUtils().getTypeElement("test.TestClass");
393+
assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
394+
}
395+
})
396+
.failsToCompile();
397+
}
398+
279399
private abstract static class AssertingProcessor extends AbstractProcessor {
280400
@Override
281401
public Set<String> getSupportedAnnotationTypes() {

0 commit comments

Comments
 (0)