Move logging code generation to ftl

parent 1714d2e4
Pipeline #119590 passed with stages
in 32 minutes and 38 seconds
......@@ -26,7 +26,8 @@ import de.monticore.lang.monticar.generator.*;
import de.monticore.lang.monticar.generator.cpp.converter.ComponentConverter;
import de.monticore.lang.monticar.generator.cpp.converter.MathConverter;
import de.monticore.lang.monticar.generator.cpp.instruction.ConnectInstructionCPP;
import de.monticore.lang.monticar.generator.order.ImplementExecutionOrder;
import de.monticore.lang.monticar.generator.cpp.template.AllTemplates;
import de.monticore.lang.monticar.generator.cpp.viewmodel.LoggingViewModel;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
......@@ -229,6 +230,10 @@ public class LanguageUnitCPP extends LanguageUnit {
//method body start
resultString += "{\n";
if (generatorCPP.isExecutionLoggingActive && method.getName().equals("execute")) {
resultString += "logStart();\n";
}
for (Instruction instruction : method.getInstructions()) {
if (instruction instanceof ConnectInstructionCPP) {
ConnectInstructionCPP connectInstructionCPP = (ConnectInstructionCPP) instruction;
......@@ -243,65 +248,20 @@ public class LanguageUnitCPP extends LanguageUnit {
}
if (generatorCPP.isExecutionLoggingActive && method.getName().equals("execute")) {
resultString += "log();\n";
resultString += "}\n\n";
resultString += "void log(){\n";
resultString += "std::ofstream __LogExecutionFile;\n";
resultString += "std::ofstream __StacktraceFile;\n";
resultString += "__LogExecutionFile.open(\"execution\" + std::to_string(__EXECCOUNTER) + \""+bluePrint.getOriginalSymbol().getPackageName()+"."+bluePrint.getOriginalSymbol().getName() +".res\");\n";
resultString += "__StacktraceFile.open(\"stacktrace.log\", std::ios_base::out | std::ios_base::app);\n";
resultString += "__StacktraceFile << \"Breakpoint reached\" << std::endl;\n";
EMAComponentInstanceSymbol curSym = bluePrint.getOriginalSymbol();
while (curSym != null) {
String res = "\\tat " + curSym.getFullName() + "(";
res += curSym
.getComponentType()
.getReferencedSymbol()
.getFullName().replace(".","/") + ".emam";
res += ":1)";
resultString += "__StacktraceFile << \""+ res + "\" << std::endl;\n";
curSym = curSym.getParent().orElse(null);
}
resultString += "__StacktraceFile << \"#tick \" << __EXECCOUNTER << std::endl;\n";
resultString += "addVariablesToStream(__StacktraceFile, true);\n";
resultString += "__StacktraceFile << \"endBreakpoint\" << std::endl;\n";
resultString += "addVariablesToStream(__LogExecutionFile, false);\n";
resultString += "__StacktraceFile.close();\n";
resultString += "__LogExecutionFile.close();\n";
resultString += "__EXECCOUNTER = __EXECCOUNTER + 1;\n";
resultString += "logEnd();\n";
}
if (generatorCPP.isExecutionLoggingActive && method.getName().equals("init")) {
resultString += "__EXECCOUNTER = 0;\n";
}
//method body end
resultString += "}\n";
if(generatorCPP.isExecutionLoggingActive && method.getName().equals("execute")){
resultString += "\nvoid addVariablesToStream(std::ofstream& stream, bool type){\n";
for (Variable v : bluePrint.getVariables()) {
if (v.hasAdditionalInformation(Variable.ORIGINPORT)) {
String varMontiCoreType = "var";
if(v.hasAdditionalInformation(Variable.INCOMING)){
varMontiCoreType = "in";
}else if(v.hasAdditionalInformation(Variable.OUTGOING)){
varMontiCoreType = "out";
}
resultString += "\tstream << (type ? \""+ varMontiCoreType + " " +v.getVariableType().getTypeNameMontiCar() +" \" : \"\");\n";
resultString += "\tstream << \"" + v.getNameTargetLanguageFormat() + " : \";\n";
resultString += "\ttoFileString(stream, " + v.getNameTargetLanguageFormat() + ");\n";
resultString += "\tstream << \"\\n\";\n";
}
}
resultString += "}\n";
if (generatorCPP.isExecutionLoggingActive && method.getName().equals("execute")) {
resultString += AllTemplates.generateLogMethods(LoggingViewModel.fromBluePrint(bluePrint));
}
return resultString;
}
}
......@@ -20,13 +20,7 @@
*/
package de.monticore.lang.monticar.generator.cpp.template;
import de.monticore.lang.monticar.generator.cpp.viewmodel.AutopilotAdapterViewModel;
import de.monticore.lang.monticar.generator.cpp.viewmodel.ComponentStreamTestViewModel;
import de.monticore.lang.monticar.generator.cpp.viewmodel.EnumViewModel;
import de.monticore.lang.monticar.generator.cpp.viewmodel.ServerWrapperViewModel;
import de.monticore.lang.monticar.generator.cpp.viewmodel.StructViewModel;
import de.monticore.lang.monticar.generator.cpp.viewmodel.TestsMainEntryViewModel;
import de.monticore.lang.monticar.generator.cpp.viewmodel.ViewModelBase;
import de.monticore.lang.monticar.generator.cpp.viewmodel.*;
import de.se_rwth.commons.logging.Log;
import freemarker.template.Configuration;
import freemarker.template.Template;
......@@ -48,6 +42,7 @@ public final class AllTemplates {
private static final Template DYNAMICS_EVENT_PortValueCheker;
private static final Template DYNAMICS_EVENT_DynamicHelper;
private static final Template LOG_METHODS;
static {
Configuration conf = new Configuration(Configuration.VERSION_2_3_23);
......@@ -64,6 +59,7 @@ public final class AllTemplates {
SERVER_WRAPPER = conf.getTemplate("/serverwrapper/ServerWrapper.ftl");
DYNAMICS_EVENT_PortValueCheker = conf.getTemplate("/dynamics/events_port_value_check_h.ftl");
DYNAMICS_EVENT_DynamicHelper = conf.getTemplate("/dynamics/dynamic_port_request_connect_helper_h.ftl");
LOG_METHODS = conf.getTemplate("logging/Log.ftl");
} catch (IOException e) {
String msg = "could not load templates";
Log.error(msg, e);
......@@ -106,6 +102,9 @@ public final class AllTemplates {
return generateWithoutData(DYNAMICS_EVENT_DynamicHelper);
}
public static String generateLogMethods(LoggingViewModel model){
return generate(LOG_METHODS, model);
}
private static String generate(Template template, ViewModelBase viewModelBase) {
return generate(template, TemplateHelper.getDataForTemplate(viewModelBase));
......
package de.monticore.lang.monticar.generator.cpp.viewmodel;
import de.monticore.ast.ASTNode;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.BluePrint;
import de.monticore.lang.monticar.generator.Variable;
import de.se_rwth.commons.SourcePosition;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class LoggingViewModel extends ViewModelBase {
public List<Variable> variables;
public List<EMAComponentInstanceSymbol> instanceStack;
public EMAComponentInstanceSymbol originalSymbol;
public List<Variable> getVariables() {
return variables;
}
public List<EMAComponentInstanceSymbol> getInstanceStack() {
return instanceStack;
}
public EMAComponentInstanceSymbol getOriginalSymbol() {
return originalSymbol;
}
public static LoggingViewModel fromBluePrint(BluePrint bluePrint){
LoggingViewModel res = new LoggingViewModel();
res.originalSymbol = bluePrint.getOriginalSymbol();
res.variables = bluePrint.getVariables().stream()
.filter(v -> v.hasAdditionalInformation(Variable.ORIGINPORT))
.collect(Collectors.toList());
res.instanceStack = new ArrayList<>();
EMAComponentInstanceSymbol curSym = bluePrint.getOriginalSymbol();
while(curSym != null){
res.instanceStack.add(curSym);
curSym = curSym.getParent().orElse(null);
}
return res;
}
public int getLastLineOfInstance(){
return originalSymbol.getComponentType()
.getReferencedSymbol()
.getAstNode()
.map(ASTNode::get_SourcePositionEnd)
.map(SourcePosition::getLine)
.orElse(1000);
}
public String getTypeStringForVar(Variable var){
String varMontiCoreType = "var";
if(var.hasAdditionalInformation(Variable.INCOMING)){
varMontiCoreType = "in";
}else if(var.hasAdditionalInformation(Variable.OUTGOING)){
varMontiCoreType = "out";
}
return varMontiCoreType;
}
}
void logStart(){
std::ofstream __StacktraceFile;
__StacktraceFile.open("stacktrace.log", std::ios_base::out | std::ios_base::app);
__StacktraceFile << "Breakpoint reached" << std::endl;
<#list viewModel.getInstanceStack() as curSym>
__StacktraceFile << "\tat ${curSym.getFullName()}(${curSym.getComponentType().getReferencedSymbol().getFullName()?replace(".","/")}).emam:1" << std::endl;
</#list>
__StacktraceFile << "#tick " << __EXECCOUNTER << std::endl;
addVariablesToStream(__StacktraceFile, true, true);
__StacktraceFile << "endBreakpoint" << std::endl;
__StacktraceFile.close();
}
void logEnd(){
std::ofstream __LogExecutionFile;
std::ofstream __StacktraceFile;
__LogExecutionFile.open("execution" + std::to_string(__EXECCOUNTER) + "${viewModel.getOriginalSymbol().getPackageName()}.${viewModel.getOriginalSymbol().getName()}.res");
__StacktraceFile.open("stacktrace.log", std::ios_base::out | std::ios_base::app);
__StacktraceFile << "Breakpoint reached" << std::endl;
<#list viewModel.getInstanceStack() as curSym>
<#if curSym == viewModel.getOriginalSymbol()>
<#assign line=viewModel.getLastLineOfInstance()/>
<#else>
<#assign line="1"/>
</#if>
__StacktraceFile << "\tat ${curSym.getFullName()}(${curSym.getComponentType().getReferencedSymbol().getFullName()?replace(".","/")}).emam:${line}" << std::endl;
</#list>
__StacktraceFile << "#tick " << __EXECCOUNTER << std::endl;
addVariablesToStream(__StacktraceFile, true, false);
__StacktraceFile << "endBreakpoint" << std::endl;
addVariablesToStream(__LogExecutionFile, false, false);
__StacktraceFile.close();
__LogExecutionFile.close();
__EXECCOUNTER = __EXECCOUNTER + 1;
}
void addVariablesToStream(std::ofstream& stream, bool type, bool onlyIncoming){
<#list viewModel.getVariables() as var>
<#assign type=viewModel.getTypeStringForVar(var)/>
<#if type != "in">
if(!onlyIncoming){
</#if>
stream << (type ? "${type} ${var.getVariableType().getTypeNameMontiCar()} " : "");
stream << "${var.getNameTargetLanguageFormat()} : ";
toFileString(stream, ${var.getNameTargetLanguageFormat()});
stream << std::endl;
<#if type != "in">
}
</#if>
</#list>
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment