package org.overture.codegen.vdm2java; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.overture.ast.lex.Dialect; import org.overture.codegen.ir.IRInfo; import org.overture.codegen.ir.SExpIR; import org.overture.codegen.ir.SStmIR; import org.overture.codegen.ir.STypeIR; import org.overture.codegen.ir.declarations.AMethodDeclIR; import org.overture.codegen.ir.expressions.AApplyExpIR; import org.overture.codegen.ir.expressions.AIdentifierVarExpIR; import org.overture.codegen.ir.expressions.ASeqConcatBinaryExpIR; import org.overture.codegen.ir.statements.ACallObjectExpStmIR; import org.overture.codegen.ir.statements.APlainCallStmIR; import org.overture.codegen.ir.statements.AReturnStmIR; import org.overture.codegen.ir.types.AClassTypeIR; import org.overture.codegen.ir.types.AStringTypeIR; import org.overture.codegen.traces.ICallStmToStringMethodBuilder; import org.overture.codegen.traces.StoreAssistant; import org.overture.codegen.trans.assistants.TransAssistantIR; import org.overture.config.Settings; public class JavaCallStmToStringBuilder extends JavaClassCreatorBase implements ICallStmToStringMethodBuilder { private Logger log = Logger.getLogger(this.getClass().getName()); @Override public AMethodDeclIR consToString(IRInfo info, SStmIR callStm, Map<String, String> idConstNameMap, StoreAssistant storeAssistant, TransAssistantIR transAssistant) { AMethodDeclIR toStringMethod = consToStringSignature(); AReturnStmIR body = new AReturnStmIR(); if (callStm instanceof APlainCallStmIR) { APlainCallStmIR plainCall = (APlainCallStmIR) callStm; STypeIR type = plainCall.getClassType(); String name = plainCall.getName(); LinkedList<SExpIR> args = plainCall.getArgs(); String prefix = ""; if (type instanceof AClassTypeIR) { prefix = ((AClassTypeIR) type).getName() + "`"; } prefix += name; body.setExp(appendArgs(info, args, prefix, idConstNameMap, storeAssistant, transAssistant)); } else if (callStm instanceof ACallObjectExpStmIR) { ACallObjectExpStmIR callObj = (ACallObjectExpStmIR) callStm; SExpIR obj = callObj.getObj(); String field = callObj.getFieldName(); LinkedList<SExpIR> args = callObj.getArgs(); String prefix = obj.toString(); prefix += "." + field; body.setExp(appendArgs(info, args, prefix, idConstNameMap, storeAssistant, transAssistant)); } // The CallObjectStmIR node has been transformed out of the tree else { log.error("Expected statement to be a call statement or call object statement. Got: " + callStm); body.setExp(info.getExpAssistant().consStringLiteral("Unknown", false)); } toStringMethod.setBody(body); return toStringMethod; } private SExpIR appendArgs(IRInfo info, List<SExpIR> args, String prefix, Map<String, String> idConstNameMap, StoreAssistant storeAssistant, TransAssistantIR transAssistant) { if (args == null || args.isEmpty()) { return info.getExpAssistant().consStringLiteral(prefix + "()", false); } ASeqConcatBinaryExpIR str = new ASeqConcatBinaryExpIR(); str.setType(new AStringTypeIR()); str.setLeft(info.getExpAssistant().consStringLiteral(prefix + "(", false)); ASeqConcatBinaryExpIR next = str; for (SExpIR arg : args) { ASeqConcatBinaryExpIR tmp = new ASeqConcatBinaryExpIR(); tmp.setType(new AStringTypeIR()); AApplyExpIR utilsToStrCall = consUtilsToStringCall(); if (arg instanceof AIdentifierVarExpIR && idConstNameMap.containsKey(((AIdentifierVarExpIR) arg).getName())) { AIdentifierVarExpIR idVarExp = (AIdentifierVarExpIR) arg; if (Settings.dialect != Dialect.VDM_SL) { utilsToStrCall.getArgs().add(storeAssistant.consStoreLookup(idVarExp, true)); } else { utilsToStrCall.getArgs().add(idVarExp); } } else { utilsToStrCall.getArgs().add(arg.clone()); } tmp.setLeft(utilsToStrCall); next.setRight(tmp); next = tmp; } next.setRight(info.getExpAssistant().consStringLiteral(")", false)); return str; } @Override public AApplyExpIR toStringOf(SExpIR exp) { AApplyExpIR utilsToStrCall = consUtilsToStringCall(); utilsToStrCall.getArgs().add(exp); return utilsToStrCall; } }