package org.overture.codegen.trans; import org.apache.log4j.Logger; import org.overture.codegen.ir.SDeclIR; import org.overture.codegen.ir.SStmIR; import org.overture.codegen.ir.analysis.AnalysisException; import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor; import org.overture.codegen.ir.declarations.AMethodDeclIR; import org.overture.codegen.ir.expressions.AApplyExpIR; import org.overture.codegen.ir.expressions.APreCondRuntimeErrorExpIR; import org.overture.codegen.ir.statements.ABlockStmIR; import org.overture.codegen.ir.statements.AIfStmIR; import org.overture.codegen.ir.statements.ARaiseErrorStmIR; import org.overture.codegen.ir.types.AErrorTypeIR; import org.overture.codegen.trans.assistants.TransAssistantIR; public class PreCheckTrans extends DepthFirstAnalysisAdaptor { private TransAssistantIR transAssistant; private Object conditionalCallTag; private Logger log = Logger.getLogger(this.getClass().getName()); public PreCheckTrans(TransAssistantIR transAssistant, Object conditionalCallTag) { this.transAssistant = transAssistant; this.conditionalCallTag = conditionalCallTag; } @Override public void caseAMethodDeclIR(AMethodDeclIR node) throws AnalysisException { if (!transAssistant.getInfo().getSettings().generatePreCondChecks()) { return; } SDeclIR preCond = node.getPreCond(); if (preCond == null) { return; } if (!(preCond instanceof AMethodDeclIR)) { log.error("Expected pre condition to be a method declaration at this point. Got: " + preCond); return; } AMethodDeclIR preCondMethod = (AMethodDeclIR) preCond; AApplyExpIR preCondCall = transAssistant.consConditionalCall(node, preCondMethod); if (preCondCall == null) { return; } preCondCall.setTag(conditionalCallTag); SStmIR body = node.getBody(); APreCondRuntimeErrorExpIR runtimeError = new APreCondRuntimeErrorExpIR(); runtimeError.setType(new AErrorTypeIR()); runtimeError.setMessage(String.format("Precondition failure: pre_%s", node.getName())); ARaiseErrorStmIR raiseError = new ARaiseErrorStmIR(); raiseError.setError(runtimeError); AIfStmIR ifCheck = new AIfStmIR(); ifCheck.setIfExp(transAssistant.getInfo().getExpAssistant().negate(preCondCall)); ifCheck.setThenStm(raiseError); ABlockStmIR newBody = new ABlockStmIR(); newBody.getStatements().add(ifCheck); newBody.getStatements().add(body.clone()); transAssistant.replaceNodeWith(body, newBody); } }