The objective of this homework was to write an annotation processor that will verify whether a certain class, annotated with the packaged annotations, uses the said design pattern correctly.
My implementation consists of two annotation processors that verify the usage of the Iterator design pattern. Three example classes are provided that demonstrate the use of the iterator design pattern and also demonstrate the various cases that my annotation processor is able to handle. Furthermore, an exhaustive test suite is provided with the annotation processor to verify its correctness.
- Java 11 or above
-
Clone or download this repository onto your system
-
Open the Command Prompt (if using Windows) or the Terminal (if using Linux/Mac) and browse to the project directory
-
Build the project using Gradle; this will run the test cases and the annotation processor on the provided examples
gradlew clean build
-
If you want detailed debug messages to be printed during annotation processing, build the project using the following command
gradlew clean build -PdebugAnnotationProcessor
-
Run the project to see the output from the examples program
gradlew run
This project makes use of Gradle's multi-project build and is divided into 3 sub-projects:
annotations
: Contains all the annotations defined in the project. Tha annotations are written in Java.annotation-processor
: Contains all the annotation processors that verify correctness of classes annotated with the annotation from theannotations
sub-project. Also contains test cases for testing the annotation processors themselves. The annotation processors are written in Scala.examples
: Contains 3 example classes that implement the Iterator design pattern and are annotated with annotations from theannotations
project. A main program, written in Scala, demonstrates how these classes may be used. The example classes are written in Java.
According to the Gang Of Four Design Pattern Book, the iterator design pattern is a behavioral design pattern which "provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation".
There are two main participants in the implementation of the iterator design pattern:
- Aggregate: An aggregate object which provides a way of creating an iterator.
- Iterator: Provides a set of methods for accessing and traversing the elements of the aggregate. At minimum, an iterator should allow the consumer to get the next element and check the availability of more elements.
This project provides two main annotations for the two main participants of the iterator design pattern - @IterableAggregate
and @Iterator
. Both of these annotations contain child annotations which can be used to annotate the methods in the classes annotated with the two main annotations. These annotations collectively help implement the iterator design pattern.
All of these annotations have a retention policy of SOURCE
, meaning they are only available during compile-time annotation processing.
The @IterableAggregate
annotation can be used to annotate a class that represents an aggregate. Although an @IterableAggregate
can be applied on any TYPE
declaration, the annotation processor restricts its usage to annotate only class
declarations.
The value()
of the @IterableAggregate
annotation specifies the class of iterator object it exposes.
It provides a child annotation - @IteratorFactory
, which can be used to annotate a factory method that creates a new instance of an iterator for accessing elements of the parent iterable aggregate.
The @Iterator
annotation can be used to annotate an iterator which provides a way to sequentially extract elements from an underlying aggregate class. Although an @Iterator
can be applied on any TYPE
declaration, the annotation processor restricts its usage to annotate only class
declarations.
The value()
of the @Iterator
annotation specifies the class of the object that can be extracted from this iterator on each iteration. The treatWarningsAsErrors()
property denotes whether cases, which usually generate a warning, should raise errors instead or not.
It provides three child annotations:
@CurrentItem
: Can be used to annotate a method that returns the current item in the current state of iteration.@IsDone
: Can be used to annotate a method that tells the consumer whether the iterator has finished iterating through all its elements.@NextItem
: Can be used to annotate a method that returns the next item in the current state of iteration.
The project provides two concrete annotation processors for processing the two main participants of the iterator design pattern. These annotation processors operate on Java source files at compile-time to process elements annotated with the annotations mentioned above.
This is the abstract base class for the other two concrete annotation processors. It provides helper methods and convenience methods that can be used by child annotation processors for performing common tasks and easily print logs at the required level.
The AbstractAnnotationProcessor
provides a way of switching debugging mode on and off. If the annotation processor is passed the option AnnotationProcessor.debug
, irrespective of its value, debug messages are also logged during the annotation processing.
The gradle build task for the examples
project has been configured to pass this option to the annotation processor if the project property debugAnnotationProcessor
is specified.
gradlew clean build -PdebugAnnotationProcessor
This concrete annotation processor verifies the correct usage of @IterableAggregate
annotation and its child annotation - @IteratorFactory
.
It enforces the following rules during the processing:
- Only classes can be annotated with
@IterableAggregate
. @IterableAggregate
'svalue()
property must be a class annotated with@Iterator
.@IterableAggregate
must contain at least one method annotated with@IteratorFactory
.@IteratorFactory
must be enclosed within a class annotated with@IterableAggregate
.- The return type of a method annotated with
@IteratorFactory
must match thevalue()
property of its parent class's@IterableAggregate
annotation.
The test suite IterableAggregateAnnotationProcessorTest
tests that the IterableAggregateAnnotationProcessor
is able to catch violations of the above rules. Furthermore, it validates that the annotation processor doesn't produce any errors for a valid usage of the @IterableAggregate
annotation. For each test case, a Java source file, present in the src/test/resources
directory, is compiled and run through the IterableAggregateAnnotationProcessor
during the compilation. Google Compile Testing library is used to perform the compilation and perform assertions based on the compilation results.
This concrete annotation processor verifies the correct usage of @Iterator
annotation and its child annotations - @CurrentItem
, @IsDone
, and @NextItem
.
It enforces the following rules during the processing:
- Only classes can be annotated with
@Iterator
. @Iterator
can have only one method annotated with@CurrentItem
.@Iterator
can have only one method annotated with@IsDone
.@Iterator
can have only one method annotated with@NextItem
.@CurrentItem
must be enclosed within a class annotated with@Iterator
.- The return type of a method annotated with
@CurrentItem
must match thevalue()
property of its parent class's@Iterator
annotation. - A method annotated with
@CurrentItem
must not take any parameters. @IsDone
must be enclosed within a class annotated with@Iterator
.- The return type of a method annotated with
@IsDone
must be aboolean
. - A method annotated with
@IsDone
must not take any parameters. - A method annotated with
@IsDone
must generate a warning if it isprivate
. @NextItem
must be enclosed within a class annotated with@Iterator
.- The return type of a method annotated with
@NextItem
must match thevalue()
property of its parent class's@Iterator
annotation. - A method annotated with
@NextItem
must not take any parameters. - A method annotated with
@NextItem
must generate a warning if it isprivate
.
The test suite IteratorAnnotationProcessorTest
tests that the IteratorAnnotationProcessor
is able to catch violations of the above rules. Furthermore, it validates that the annotation processor doesn't produce any errors for a valid usage of the @Iterator
annotation. For each test case, a Java source file, present in the src/test/resources
directory, is compiled and run through the IteratorAnnotationProcessor
during the compilation. Google Compile Testing library is used to perform the compilation and perform assertions based on the compilation results.
This project provides 3 classes that demonstrate the use of the iterator pattern and are annotated with different variations of the @Iterator
and @IterableAggregate
(and their nested) annotations:
StudentCollection
: A class annotated with@IterableAggregate
that implementsjava.lang.Iterable
. It's iterator class is annotated with@Iterator
and implementsjava.util.Iterator
. This allows theStudent
s in this collection to be iterated using Java's "enhanced for-loop". The iterator returns aStudent
object during iteration.RangeGenerator
: A class annotated with@Iterator
that generates a primitiveint
value on each iteration within the range specified while constructing its object.Tree
: A class annotated with@IterableAggregate
that provides two methods annotated with@IteratorFactory
. The two methods return instances ofTree.TreeIterator
that allow the user to iterate the nodes of the tree in depth-first and breadth-first orders.
> Task :annotation-processor:compileScala
Pruning sources from previous analysis, due to incompatible CompileSetup.
> Task :annotation-processor:compileTestScala
Pruning sources from previous analysis, due to incompatible CompileSetup.
> Task :annotation-processor:test
com.mayankrastogi.cs474.hw2.annotations.processor.tests.IterableAggregateAnnotationProcessorTest
Test IterableAggregateAnnotationProcessor should succeed without warnings on valid usage. PASSED
Test @IterableAggregate must not be applicable on an interface. PASSED
Test @IterableAggregate's value property must be a class annotated with @Iterator. PASSED
Test @IterableAggregate must contain at least one method annotated with @IteratorFactory. PASSED
Test @IteratorFactory must be enclosed within a class annotated with @IterableAggregate. PASSED
Test Return type of a method annotated with @IteratorFactory must match the value property of its parent class's @IterableAggregate annotation. PASSED
com.mayankrastogi.cs474.hw2.annotations.processor.tests.IteratorAnnotationProcessorTest
Test IteratorAnnotationProcessor should succeed without warnings on valid usage. PASSED
Test @Iterator must not be applicable on an interface. PASSED
Test @Iterator must contain only one method annotated with @CurrentItem. PASSED
Test @Iterator must contain only one method annotated with @IsDone. PASSED
Test @Iterator must contain only one method annotated with @NextItem. PASSED
Test @CurrentItem must be enclosed within a class annotated with @Iterator. PASSED
Test Return type of method annotated with @CurrentItem must match the value property of its parent class's @Iterator annotation. PASSED
Test Method annotated with @CurrentItem must not take any parameters. PASSED
Test @IsDone must be enclosed within a class annotated with @Iterator PASSED
Test Return type of method annotated with @IsDone must be boolean. PASSED
Test Method annotated with @IsDone must not take any parameters. PASSED
Test Method annotated with @IsDone must generate a warning if it is private PASSED
Test @NextItem must be enclosed within a class annotated with @Iterator PASSED
Test Return type of method annotated with @NextItem must match the value property of its parent class's @Iterator annotation. PASSED
Test Method annotated with @NextItem must not take any parameters. PASSED
Test Method annotated with @NextItem must generate a warning if it is private PASSED
SUCCESS: Executed 22 tests in 4.3s
> Task :examples:compileJava
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate.IteratorFactory
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate.IteratorFactory
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem
> Task :examples:compileScala
Pruning sources from previous analysis, due to incompatible CompileSetup.
BUILD SUCCESSFUL in 13s
17 actionable tasks: 17 executed
> Configure project :examples
Debugging mode for annotation processor has been switched on.
> Task :annotation-processor:compileScala
Pruning sources from previous analysis, due to incompatible CompileSetup.
> Task :annotation-processor:compileTestScala
Pruning sources from previous analysis, due to incompatible CompileSetup.
> Task :annotation-processor:test
com.mayankrastogi.cs474.hw2.annotations.processor.tests.IterableAggregateAnnotationProcessorTest
Test IterableAggregateAnnotationProcessor should succeed without warnings on valid usage. PASSED
Test @IterableAggregate must not be applicable on an interface. PASSED
Test @IterableAggregate's value property must be a class annotated with @Iterator. PASSED
Test @IterableAggregate must contain at least one method annotated with @IteratorFactory. PASSED
Test @IteratorFactory must be enclosed within a class annotated with @IterableAggregate. PASSED
Test Return type of a method annotated with @IteratorFactory must match the value property of its parent class's @IterableAggregate annotation. PASSED
com.mayankrastogi.cs474.hw2.annotations.processor.tests.IteratorAnnotationProcessorTest
Test IteratorAnnotationProcessor should succeed without warnings on valid usage. PASSED
Test @Iterator must not be applicable on an interface. PASSED
Test @Iterator must contain only one method annotated with @CurrentItem. PASSED
Test @Iterator must contain only one method annotated with @IsDone. PASSED
Test @Iterator must contain only one method annotated with @NextItem. PASSED
Test @CurrentItem must be enclosed within a class annotated with @Iterator. PASSED
Test Return type of method annotated with @CurrentItem must match the value property of its parent class's @Iterator annotation. PASSED
Test Method annotated with @CurrentItem must not take any parameters. PASSED
Test @IsDone must be enclosed within a class annotated with @Iterator PASSED
Test Return type of method annotated with @IsDone must be boolean. PASSED
Test Method annotated with @IsDone must not take any parameters. PASSED
Test Method annotated with @IsDone must generate a warning if it is private PASSED
Test @NextItem must be enclosed within a class annotated with @Iterator PASSED
Test Return type of method annotated with @NextItem must match the value property of its parent class's @Iterator annotation. PASSED
Test Method annotated with @NextItem must not take any parameters. PASSED
Test Method annotated with @NextItem must generate a warning if it is private PASSED
SUCCESS: Executed 22 tests in 4.5s
> Task :examples:compileJava
Note: [DEBUG]process(annotations: [com.mayankrastogi.cs474.hw2.annotations.IterableAggregate, com.mayankrastogi.cs474.hw2.annotations.IterableAggregate.IteratorFactory], roundEnv: [errorRaised=false, rootElements=[com.mayankrastogi.cs474.hw2.examples.RangeGenerator, com.mayankrastogi.cs474.hw2.examples.Degree, com.mayankrastogi.cs474.hw2.examples.StudentCollection, com.mayankrastogi.cs474.hw2.examples.Student, com.mayankrastogi.cs474.hw2.examples.Tree, com.mayankrastogi.cs474.hw2.examples.Node], processingOver=false])
Note: [DEBUG]iterableAggregates: Set(com.mayankrastogi.cs474.hw2.examples.StudentCollection, com.mayankrastogi.cs474.hw2.examples.Tree)
Note: [DEBUG]iteratorFactories: Set(iterator(), dfsIterator(), bfsIterator())
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\StudentCollection.java:25: Note: [DEBUG]Processing iterableAggregateElement
public class StudentCollection implements Iterable<Student> {
^
Note: [DEBUG]assertIterableAggregateElementIsAppliedOnClass...
Note: [DEBUG]assertIterableAggregateElementIsAppliedOnClass: true
Note: [DEBUG]assertIterableAggregateAnnotationValueIsAnnotatedWithIterator...
Note: [DEBUG]assertIterableAggregateAnnotationValueIsAnnotatedWithIterator: true
Note: [DEBUG]assertIterableAggregateElementContainsAtLeastOneIteratorFactory...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate.IteratorFactory within iterable aggregate
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\Tree.java:20: Note: [DEBUG]Processing iterableAggregateElement
public class Tree<T> {
^
Note: [DEBUG]assertIterableAggregateElementIsAppliedOnClass...
Note: [DEBUG]assertIterableAggregateElementIsAppliedOnClass: true
Note: [DEBUG]assertIterableAggregateAnnotationValueIsAnnotatedWithIterator...
Note: [DEBUG]assertIterableAggregateAnnotationValueIsAnnotatedWithIterator: true
Note: [DEBUG]assertIterableAggregateElementContainsAtLeastOneIteratorFactory...
Note: [DEBUG]Found 2 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate.IteratorFactory within iterable aggregate
Note: [DEBUG]Processing successful: true
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate.IteratorFactory
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\StudentCollection.java:59: Note: [DEBUG]Processing iteratorFactoryMethod
public java.util.Iterator<Student> iterator() {
^
Note: [DEBUG]assertIteratorFactoryMethodIsEnclosedWithinIterableAggregate...
Note: [DEBUG]Iterable factory method is enclosed within an iterable aggregate
Note: [DEBUG]assertIteratorFactoryMethodReturnsTypeSpecifiedInIterableAggregateAnnotationValue...
Note: [DEBUG]iterableAggregateAnnotationValue: com.mayankrastogi.cs474.hw2.examples.StudentCollection.StudentCollectionIterator
Note: [DEBUG]The return type of the iterator factory method is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\Tree.java:42: Note: [DEBUG]Processing iteratorFactoryMethod
public TreeIterator dfsIterator() {
^
Note: [DEBUG]assertIteratorFactoryMethodIsEnclosedWithinIterableAggregate...
Note: [DEBUG]Iterable factory method is enclosed within an iterable aggregate
Note: [DEBUG]assertIteratorFactoryMethodReturnsTypeSpecifiedInIterableAggregateAnnotationValue...
Note: [DEBUG]iterableAggregateAnnotationValue: com.mayankrastogi.cs474.hw2.examples.Tree.TreeIterator
Note: [DEBUG]The return type of the iterator factory method is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\Tree.java:52: Note: [DEBUG]Processing iteratorFactoryMethod
public TreeIterator bfsIterator() {
^
Note: [DEBUG]assertIteratorFactoryMethodIsEnclosedWithinIterableAggregate...
Note: [DEBUG]Iterable factory method is enclosed within an iterable aggregate
Note: [DEBUG]assertIteratorFactoryMethodReturnsTypeSpecifiedInIterableAggregateAnnotationValue...
Note: [DEBUG]iterableAggregateAnnotationValue: com.mayankrastogi.cs474.hw2.examples.Tree.TreeIterator
Note: [DEBUG]The return type of the iterator factory method is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate
Note: [DEBUG]Processing successful: true
Note: [DEBUG]process(annotations: [com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem, com.mayankrastogi.cs474.hw2.annotations.Iterator, com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem, com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone], roundEnv: [errorRaised=false, rootElements=[com.mayankrastogi.cs474.hw2.examples.RangeGenerator, com.mayankrastogi.cs474.hw2.examples.Degree, com.mayankrastogi.cs474.hw2.examples.StudentCollection, com.mayankrastogi.cs474.hw2.examples.Student, com.mayankrastogi.cs474.hw2.examples.Tree, com.mayankrastogi.cs474.hw2.examples.Node], processingOver=false])
Note: [DEBUG]iterators: Set(com.mayankrastogi.cs474.hw2.examples.RangeGenerator, com.mayankrastogi.cs474.hw2.examples.StudentCollection.StudentCollectionIterator, com.mayankrastogi.cs474.hw2.examples.Tree.TreeIterator)
Note: [DEBUG]currentItems: Set(currentValue(), current(), currentNode())
Note: [DEBUG]isDones: Set(isDone(), hasNext(), isDone())
Note: [DEBUG]nextItems: Set(next(), next(), next())
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\RangeGenerator.java:11: Note: [DEBUG]Processing iteratorElement
public class RangeGenerator {
^
Note: [DEBUG]assertIteratorElementIsValid...
Note: [DEBUG]assertIteratorElementIsValid: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\StudentCollection.java:70: Note: [DEBUG]Processing iteratorElement
public class StudentCollectionIterator implements java.util.Iterator<Student> {
^
Note: [DEBUG]assertIteratorElementIsValid...
Note: [DEBUG]assertIteratorElementIsValid: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\Tree.java:65: Note: [DEBUG]Processing iteratorElement
public class TreeIterator {
^
Note: [DEBUG]assertIteratorElementIsValid...
Note: [DEBUG]assertIteratorElementIsValid: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith...
Note: [DEBUG]Found 1 element(s) annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem within iterator
Note: [DEBUG]assertIteratorElementContainsOnlyOneMethodAnnotatedWith: true
Note: [DEBUG]Processing successful: true
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\RangeGenerator.java:28: Note: [DEBUG]Processing currentItemMethod
private int currentValue() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]CurrentItem is enclosed within an iterator
Note: [DEBUG]assertMethodReturnsTypeSpecifiedInIteratorAnnotationValue...
Note: [DEBUG]iteratorAnnotationValue: int
Note: [DEBUG]The return type of the method annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\StudentCollection.java:85: Note: [DEBUG]Processing currentItemMethod
public Student current() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]CurrentItem is enclosed within an iterator
Note: [DEBUG]assertMethodReturnsTypeSpecifiedInIteratorAnnotationValue...
Note: [DEBUG]iteratorAnnotationValue: com.mayankrastogi.cs474.hw2.examples.Student
Note: [DEBUG]The return type of the method annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\Tree.java:90: Note: [DEBUG]Processing currentItemMethod
public Node<T> currentNode() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]CurrentItem is enclosed within an iterator
Note: [DEBUG]assertMethodReturnsTypeSpecifiedInIteratorAnnotationValue...
Note: [DEBUG]iteratorAnnotationValue: com.mayankrastogi.cs474.hw2.examples.Node
Note: [DEBUG]The return type of the method annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]Processing successful: true
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\RangeGenerator.java:38: Note: [DEBUG]Processing isDoneMethod
public boolean isDone() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]IsDone is enclosed within an iterator
Note: [DEBUG]assertIsDoneMethodReturnsBooleanType...
Note: [DEBUG]assertIsDoneMethodReturnsBooleanType: true
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]warnIfMethodIsPrivate...
Note: [DEBUG]shouldTreatWarningsAsErrors...
Note: [DEBUG]shouldTreatWarningsAsErrors: false
Note: [DEBUG]isPrivate: false
Note: [DEBUG]operationSuccessful: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\StudentCollection.java:96: Note: [DEBUG]Processing isDoneMethod
public boolean hasNext() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]IsDone is enclosed within an iterator
Note: [DEBUG]assertIsDoneMethodReturnsBooleanType...
Note: [DEBUG]assertIsDoneMethodReturnsBooleanType: true
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]warnIfMethodIsPrivate...
Note: [DEBUG]shouldTreatWarningsAsErrors...
Note: [DEBUG]shouldTreatWarningsAsErrors: false
Note: [DEBUG]isPrivate: false
Note: [DEBUG]operationSuccessful: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\Tree.java:100: Note: [DEBUG]Processing isDoneMethod
public boolean isDone() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]IsDone is enclosed within an iterator
Note: [DEBUG]assertIsDoneMethodReturnsBooleanType...
Note: [DEBUG]assertIsDoneMethodReturnsBooleanType: true
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]warnIfMethodIsPrivate...
Note: [DEBUG]shouldTreatWarningsAsErrors...
Note: [DEBUG]shouldTreatWarningsAsErrors: false
Note: [DEBUG]isPrivate: false
Note: [DEBUG]operationSuccessful: true
Note: [DEBUG]Processing successful: true
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\RangeGenerator.java:50: Note: [DEBUG]Processing nextItemMethod
public int next() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]NextItem is enclosed within an iterator
Note: [DEBUG]assertMethodReturnsTypeSpecifiedInIteratorAnnotationValue...
Note: [DEBUG]iteratorAnnotationValue: int
Note: [DEBUG]The return type of the method annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]warnIfMethodIsPrivate...
Note: [DEBUG]shouldTreatWarningsAsErrors...
Note: [DEBUG]shouldTreatWarningsAsErrors: false
Note: [DEBUG]isPrivate: false
Note: [DEBUG]operationSuccessful: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\StudentCollection.java:110: Note: [DEBUG]Processing nextItemMethod
public Student next() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]NextItem is enclosed within an iterator
Note: [DEBUG]assertMethodReturnsTypeSpecifiedInIteratorAnnotationValue...
Note: [DEBUG]iteratorAnnotationValue: com.mayankrastogi.cs474.hw2.examples.Student
Note: [DEBUG]The return type of the method annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]warnIfMethodIsPrivate...
Note: [DEBUG]shouldTreatWarningsAsErrors...
Note: [DEBUG]shouldTreatWarningsAsErrors: false
Note: [DEBUG]isPrivate: false
Note: [DEBUG]operationSuccessful: true
Note: [DEBUG]Processing successful: true
examples\src\main\java\com\mayankrastogi\cs474\hw2\examples\Tree.java:113: Note: [DEBUG]Processing nextItemMethod
public Node<T> next() {
^
Note: [DEBUG]assertMethodIsEnclosedWithinIterator...
Note: [DEBUG]NextItem is enclosed within an iterator
Note: [DEBUG]assertMethodReturnsTypeSpecifiedInIteratorAnnotationValue...
Note: [DEBUG]iteratorAnnotationValue: com.mayankrastogi.cs474.hw2.examples.Node
Note: [DEBUG]The return type of the method annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem is assignable to the type specified as value on its enclosing @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: [DEBUG]assertMethodTakesNoParameters...
Note: [DEBUG]assertMethodTakesNoParameters: true
Note: [DEBUG]warnIfMethodIsPrivate...
Note: [DEBUG]shouldTreatWarningsAsErrors...
Note: [DEBUG]shouldTreatWarningsAsErrors: false
Note: [DEBUG]isPrivate: false
Note: [DEBUG]operationSuccessful: true
Note: [DEBUG]Processing successful: true
Note: [DEBUG]process(annotations: [], roundEnv: [errorRaised=false, rootElements=[], processingOver=true])
Note: [DEBUG]iterableAggregates: Set()
Note: [DEBUG]iteratorFactories: Set()
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.IterableAggregate.IteratorFactory
Note: [DEBUG]process(annotations: [], roundEnv: [errorRaised=false, rootElements=[], processingOver=true])
Note: [DEBUG]iterators: Set()
Note: [DEBUG]currentItems: Set()
Note: [DEBUG]isDones: Set()
Note: [DEBUG]nextItems: Set()
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.CurrentItem
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.IsDone
Note: Processing elements annotated with @com.mayankrastogi.cs474.hw2.annotations.Iterator.NextItem
> Task :examples:compileScala
Pruning sources from previous analysis, due to incompatible CompileSetup.
BUILD SUCCESSFUL in 13s
17 actionable tasks: 17 executed
> Task :examples:run
=================================================================================================================
Design Pattern Verifier - Iterator Design Pattern Example Programs
=================================================================================================================
The iterator design pattern provides a way to access the elements of an aggregate object sequentially without
exposing its underlying representation.
This application demonstrates 3 classes that use the iterator pattern and are annotated with different variations
of the @Iterator and @IterableAggregate (and their nested) annotations:
1. StudentCollection: A class annotated with @IterableAggregate that implements `java.lang.Iterable`. It's
iterator class is annotated with @Iterator and implements `java.util.Iterator`. The iterator returns a
`Student` object during iteration.
2. RangeGenerator: A class annotated with @Iterator that generates a primitive `int` value on each iteration
within the range specified while constructing its object.
3. Tree: A class annotated with @IterableAggregate that provides two methods annotated with @IteratorFactory.
The two methods return instances of `Tree.TreeIterator` that allow the user to iterate the nodes of the
tree in depth-first and breadth-first orders.
-----------------------------------------------------------------------------------------------------------------
Student Collection Iteration Example
-----------------------------------------------------------------------------------------------------------------
23:13:35.800 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Creating StudentCollection...
23:13:35.803 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Iterating StudentCollection...
Name: Alex
Age: 20
Degree: Bachelors
GPA: 3.2
Name: Bob
Age: 25
Degree: Masters
GPA: 3.6
Name: Chuck
Age: 28
Degree: PhD
GPA: 3.5
23:13:35.815 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - StudentCollection Iteration Example Finished.
-----------------------------------------------------------------------------------------------------------------
RangeGenerator Iteration Example
-----------------------------------------------------------------------------------------------------------------
23:13:35.823 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Creating a RangeGenerator(from: 1, to: 10)...
23:13:35.823 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Iterating RangeGenerator...
1
2
3
4
5
6
7
8
9
10
23:13:35.823 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - RangeGenerator Iteration Example Finished.
-----------------------------------------------------------------------------------------------------------------
Tree Iteration Example
-----------------------------------------------------------------------------------------------------------------
Sample Tree:
-----------
1
_______________________________|_______________________________
| | |
2 3 4
_______|_______ _______|_______ _______|_______
| | | | | |
5 6 7 8 9 10
23:13:35.824 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Creating 10 nodes...
23:13:35.828 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - allNodes: Vector(Node(data: 1, children: []), Node(data: 2, children: []), Node(data: 3, children: []), Node(data: 4, children: []), Node(data: 5, children: []), Node(data: 6, children: []), Node(data: 7, children: []), Node(data: 8, children: []), Node(data: 9, children: []), Node(data: 10, children: []))
23:13:35.828 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Creating Sample Tree...
23:13:35.841 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - tree: Tree(root: Node(data: 1, children: [Node(data: 2, children: [Node(data: 5, children: []), Node(data: 6, children: [])]), Node(data: 3, children: [Node(data: 7, children: []), Node(data: 8, children: [])]), Node(data: 4, children: [Node(data: 9, children: []), Node(data: 10, children: [])])]))
23:13:35.841 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Iterating tree using `dfsIterator()`...
Depth-first tree traversal:
1 2 5 6 3 7 8 4 9 10
23:13:35.842 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Iterating tree using `bfsIterator()`...
Breadth-first tree traversal:
1 2 3 4 5 6 7 8 9 10
23:13:35.843 [main] DEBUG com.mayankrastogi.cs474.hw2.examples.IteratorExamplesMain$ - Tree Iteration Example Finished.
BUILD SUCCESSFUL in 1s
8 actionable tasks: 1 executed, 7 up-to-date