Skip navigation links

Package org.paninij.proc

@PaniniJ's annotation processing is actually performed using a pair of annotation processors.

See: Description

Package org.paninij.proc Description

@PaniniJ's annotation processing is actually performed using a pair of annotation processors. The idea is that the `RoundZeroProcessor` generates capsule and signature interfaces, while the `RoundOneProcessor` subsequently generates all of the other sources.

This split was motivated by a problem that we have been having since the static checks were first implemented: how can our annotation processor fully check a core if includes class definitions which haven't been created yet? To explain this chicken-and-egg problem, consider this code snippet,


 @Capsule
 public class ConsoleCore {
     @Local Stream stream;
 }
 

where `Stream` is a signature interface generated by the annotation processor from some `StreamCore` signature core. With our original annotation processor design, our annotation processor would, during just one round of processing,

This meant that when performing checks over `ConsoleCore`, the `Stream` type would not yet exist. That makes it a bit tricker to check.

This absence of a type in some element is actually a normal part of annotation processing; it is meant to handle the case that some class definition might be missing in earlier rounds. To quote the OpenJDK's Compilation Overview,

Normally, if any errors occur during the overall compilation process, the process is stopped at the next convenient point. However, an exception is made if any missing symbols were detected during the Enter phase, because definitions for these symbols may be generated as a result of calling annotation processors.

When some Java code uses some symbol whose definition cannot be found, the annotation processing API encodes this fact using type mirrors of kind `TypeKind.ERROR`. Previously, we dealt with our problem of missing capsule/signature interfaces by implemented a number of crude workarounds which expected to find `TypeKind.ERROR` under certain conditions. However, we believed that this would not be a sensible solution for Issue #152, and that we needed a better approach.

The annotation processing infrastructure is designed so that types generated in prior rounds are referred to in elements in subsequent rounds of processing. This is even the case if previously an element contained some reference to a `TypeKind.ERROR`.

So, the solution offered here is that we initially generate just the capsule and signature interfaces during an initial round of processing. This way, during the next round of processing, there should be no `TypeKind.ERROR` values which appear in the fields of capsule cores (unless of course the user has given a type which actually doesn't exist on the source path or class path).

Skip navigation links