options.get("referenceToCodebase"),
"Inverse translation requires key 'referenceToCodebase'.");
Deque<Codebase> forwardTranslationStack = makeForwardTranslationStack(options, context);
Codebase refFrom;
// For the first reference from-codebase, use the 'referenceFromCodebase' option if given,
// otherwise use the top of the forward-translation stack.
if (options.get("referenceFromCodebase") != null) {
try {
refFrom =
Parser.parseExpression(options.get("referenceFromCodebase")).createCodebase(context);
} catch (ParseError e) {
throw new CodebaseCreationError("Couldn't parse referenceFromCodebase '"
+ options.get("referenceFromCodebase") + "': " + e);
}
// Discard the "default" reference from-codebase, i.e. the top of the forward-trans stack.
forwardTranslationStack.pop();
} else {
refFrom = forwardTranslationStack.pop();
}
Codebase refTo = forwardTranslationStack.peek();
Codebase inverseTranslated = toTranslate;
for (InverseTranslatorStep inverseStep : inverseSteps) {
Task task = AppContext.RUN.ui.pushTask("inverseEdit", String.format(
"Inverse-translating step %s by merging codebase %s onto %s",
inverseStep.getName(), refTo, refFrom));
inverseTranslated = inverseStep.getInverseEditor().inverseEdit(
inverseTranslated, refFrom, refTo, context, options);
AppContext.RUN.ui.popTaskAndPersist(task, inverseTranslated.getPath());
refFrom = forwardTranslationStack.pop();
refTo = forwardTranslationStack.peek();
}
return inverseTranslated;