Annotation suggestion @Generator

Skip to first unread message

storycraft

unread,
Mar 6, 2023, 5:37:50 AM3/6/23
to Project Lombok
Hello. It would be great if there is @Generator annotation, which creates generator(lazily evaluated iterator). It already exists in many other languages like Javascript, Kotlin, Python, C#, etc. While it provides a way to create custom iterators easily, it is very hard to create manually.

I already have made working javac handler, feature page including detailed explanations, and tests in my fork.
https://github.com/storycraft/lombok

Here is example code
@Generator
public static Iterable<Integer> range(int from, int to) {
    for (int i = from; i < to; i++) {
        yieldThis(i);
    }
}

User can use yieldThis or yieldAll statement to yield values from generator. Calling hasNext or next method will resume generator until next yieldThis or yieldAll statement.

The handler converts method like below.
public static Iterable<Integer> range(int from, int to) {
    class __Generator implements java.lang.Iterable<Integer>, java.util.Iterator<Integer> {
        private int $state;
        private Integer $nextVal;
        private int gen238$i;
       
        @java.lang.Override
        public java.util.Iterator<Integer> iterator() {
            return this;
        }
       
        @java.lang.SuppressWarnings("unchecked")
        private <$THROW extends java.lang.Throwable>void __next() throws $THROW {
            try {
                while (true) switch ($state) {
                case 0:
                    gen238$i = from;
               
                case 1:
                    if (!(gen238$i < to)) {
                        $state = 8;
                        continue;
                    }
                    $state = 5;
                    $nextVal = gen238$i;
                    return;
               
                case 5:
                    gen238$i++;
                    $state = 1;
                    continue;
               
                case 8:
                    $state = 9;
               
                case 9:
                    return;
               
                default:
                    throw new java.lang.RuntimeException("Unreachable generator state");
               
                }
            } catch (final java.lang.Throwable t) {
                $state = 9;
                throw t;
            }
        }
       
        @java.lang.Override
        public boolean hasNext() {
            if ($nextVal == null) this.<java.lang.RuntimeException>__next();
            return $nextVal != null;
        }
       
        @java.lang.Override
        public Integer next() {
            if ($nextVal == null) {
                this.<java.lang.RuntimeException>__next();
                if ($nextVal == null) throw new java.util.NoSuchElementException("Called next on finished generator");
            }
            try {
                return $nextVal;
            } finally {
                $nextVal = null;
            }
        }
    }
    return new __Generator();
}

So user can use range method like this
for (int i : range(0, 5)) {
    System.out.println(i);
}

This code prints
0
1
2
3
4

Mat Jaggard

unread,
Mar 6, 2023, 6:34:39 AM3/6/23
to project-lombok
Java already has this.

IntStream.range(0, 5).iterator()



--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/ddc66ea3-f4d3-474f-b0a6-8c00a3442d93n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages