import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import java.util.function.Function;
import org.eclipse.jdt.annotation.NonNull;
final class ModifierImpl implements ModelActionBuilder {
private static final Logger LOG = LoggerFactory.getLogger(ModifierImpl.class);
- private final InferenceContext ctx = new InferenceContext() { };
-
private final Set<AbstractPrerequisite<?>> unsatisfied = new HashSet<>(1);
private final Set<AbstractPrerequisite<?>> mutations = new HashSet<>(1);
+ private final InferenceContext ctx = new InferenceContext() { };
+ private List<Runnable> bootstraps;
private InferenceAction action;
- private boolean actionApplied = false;
+ private boolean actionApplied;
private <D> AbstractPrerequisite<D> addReq(final AbstractPrerequisite<D> prereq) {
LOG.trace("Modifier {} adding prerequisite {}", this, prereq);
action = null;
}
- private void applyAction() {
- checkState(!actionApplied);
- action.apply(ctx);
- actionApplied = true;
- }
-
private <K, C extends StmtContext<?, ?, ?>, N extends StatementNamespace<K, ?, ?>> @NonNull AbstractPrerequisite<C>
requiresCtxImpl(final StmtContext<?, ?, ?> context, final Class<N> namespace, final K key,
final ModelProcessingPhase phase) {
checkState(action != null, "Action was not defined yet.");
if (removeSatisfied()) {
- applyAction();
+ if (!actionApplied) {
+ action.apply(ctx);
+ actionApplied = true;
+ }
return true;
}
return false;
addReq(ret);
addMutation(ret);
- ret.hookOnto(context, namespace);
+ if (bootstraps == null) {
+ bootstraps = new ArrayList<>(1);
+ }
+ bootstraps.add(() -> ret.hookOnto(context, namespace));
return ret;
}
public void apply(final InferenceAction action) {
checkState(this.action == null, "Action already defined to %s", this.action);
this.action = requireNonNull(action);
+ if (bootstraps != null) {
+ bootstraps.forEach(Runnable::run);
+ bootstraps = null;
+ }
}
private abstract class AbstractPrerequisite<T> implements Prerequisite<T> {
@Override
public boolean phaseFinished(final StatementContextBase<?, ?, ?> context,
final ModelProcessingPhase finishedPhase) {
- return resolvePrereq((C) context);
+ return resolvePrereq((C) context) || tryApply();
}
}
@Override
public boolean phaseFinished(final StatementContextBase<?, ?, ?> context,
final ModelProcessingPhase finishedPhase) {
- return resolvePrereq((C) context);
+ return resolvePrereq((C) context) || tryApply();
}
@Override
if (!it.hasNext()) {
// Last step: we are done
- resolvePrereq((C) value);
+ if (resolvePrereq((C) value)) {
+ tryApply();
+ }
return;
}