- // Step 1c: ... finally establish linkage along the reverse uses/augment axis. This is needed to route generated
- // type manifestations (isAddedByUses/isAugmenting) to their type generation sites. Since generator
- // tree iteration order does not match dependencies, we may need to perform multiple passes.
- long unlinkedOriginals = Long.MAX_VALUE;
- do {
- long remaining = 0;
- for (ModuleGenerator module : children) {
- remaining += module.linkOriginalGenerator();
+ // Step 1c: Establish linkage along the reverse uses/augment axis. This is needed to route generated type
+ // manifestations (isAddedByUses/isAugmenting) to their type generation sites. Since generator tree
+ // iteration order does not match dependencies, we may need to perform multiple passes.
+ for (ModuleGenerator module : children) {
+ verify(module.linkOriginalGenerator(), "Module %s failed to link", module);
+ }
+
+ final var unlinkedModules = new ArrayList<>(children);
+ while (true) {
+ final boolean progress =
+ progressAndClean(unlinkedModules, ModuleGenerator::linkOriginalGeneratorRecursive)
+ // not '||' because we need the side-effects, which would get short-circuited
+ | progressAndClean(augments, AugmentRequirement::resolve);
+
+ if (augments.isEmpty() && unlinkedModules.isEmpty()) {
+ break;