/* * ****************************************************************************** * MontiCore Language Workbench * Copyright (c) 2015, MontiCore, All rights reserved. * * This project is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this project. If not, see <http://www.gnu.org/licenses/>. * ****************************************************************************** */ package de.monticore.generating.templateengine.reporting.reporter; import java.io.File; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import de.monticore.ast.ASTNode; import de.monticore.generating.templateengine.CodeHookPoint; import de.monticore.generating.templateengine.HookPoint; import de.monticore.generating.templateengine.StringHookPoint; import de.monticore.generating.templateengine.TemplateHookPoint; import de.monticore.generating.templateengine.reporting.commons.AReporter; import de.monticore.generating.templateengine.reporting.commons.MapUtil; import de.monticore.generating.templateengine.reporting.commons.ReportingConstants; import de.monticore.generating.templateengine.reporting.commons.ReportingHelper; import de.monticore.generating.templateengine.reporting.commons.ReportingRepository; import de.monticore.generating.templateengine.reporting.commons.TreePrintVisitor; import de.se_rwth.commons.Names; /** * TODO: Write me! * * @author (last commit) $Author$ * @version $Revision$, $Date$ * @since TODO: add version number */ public class NodeTreeDecoratedReporter extends AReporter { final static String INSTANTIATE_JAVA_CLASS = "inst"; final static String GENERATES_FILE = "generates"; final static String USED_TEMPLATE = "template"; final static String TEMPLATE_HOOKPOINT = "THP"; final static String SPECIFIC_TEMPLATE_HOOKPOINT = "ATHP"; final static String SPECIFIC_STRING_HOOKPOINT = "ASHP"; final static String SPECIFIC_CODE_HOOKPOINT = "ACHP"; final static String SIMPLE_FILE_NAME = "11_NodeTreeDecorated"; private ReportingRepository repository; private Map<String, Integer> nodeVisits; private Map<String, List<String>> astNodeExtraInfos; private List<String> serializedTreeResult; public NodeTreeDecoratedReporter(String outputDir, String modelName, ReportingRepository repository) { super(outputDir + File.separator + ReportingConstants.REPORTING_DIR + File.separator + modelName, SIMPLE_FILE_NAME, ReportingConstants.REPORT_FILE_EXTENSION); this.repository = repository; nodeVisits = Maps.newHashMap(); astNodeExtraInfos = Maps.newHashMap(); serializedTreeResult = Lists.newArrayList(); } @Override protected void writeHeader() { writeLine("========================================================== Node Tree + Extra Infos"); } private void writeContent(ASTNode ast) { if (ast == null) { return; } deriveTreeStructureAST(ast); for (String s : serializedTreeResult) { writeLine(s); } } private void writeFooter() { writeLine("========================================================== Explanation"); writeLine("Node Tree: this is the extended form: one with extra infos"); writeLine("as sublines. The tree itself lists all AST nodes using their identifiers."); writeLine("Vertical line: list all the direct children of a node."); writeLine("Each node knows about:"); writeLine("- #Visits through templates (in the raw version) looks like: (2x)"); writeLine("- files generated originating from this node"); writeLine("- templates called on this node"); writeLine("Remark: a \"null\" as value in the tree means that the tree has been altered"); writeLine("after parsing. --> this is not yet reflected in the protocol"); writeLine("(EOF)"); } // @Override // public void reportExecuteStandardTemplate(String templatename, ASTNode ast) // { // String aident = compactStr(ast); // MapUtil.incMapValue(nodeVisits, aident); // MapUtil.addToListMap(astNodeExtraInfos, aident, USED_TEMPLATE + " " // + ReportingHelper.getTemplateName(templatename)); // // } /** * @see de.monticore.generating.templateengine.reporting.commons.DefaultReportEventHandler#reportCallHookPointStart(java.lang.String, * de.monticore.generating.templateengine.HookPoint, de.monticore.ast.ASTNode) */ @Override public void reportCallHookPointStart(String hookName, HookPoint hp, ASTNode ast) { callHP(hp, ast); } /** * @see de.monticore.generating.templateengine.reporting.commons.DefaultReportEventHandler#reportTemplateStart(java.lang.String, * de.monticore.ast.ASTNode) */ @Override public void reportTemplateStart(String templatename, ASTNode ast) { String aident = compactStr(ast); MapUtil.incMapValue(nodeVisits, aident); MapUtil.addToListMap(astNodeExtraInfos, aident, USED_TEMPLATE + " " + ReportingHelper.getTemplateName(templatename)); } /** * @see mc.codegen.reporting.commons.IReportEventHandler#reportFileCreation(java.lang.String, * java.lang.String, java.lang.String, de.monticore.ast.ASTNode) */ @Override public void reportFileCreation(String templatename, String qualifiedfilename, String fileextension, ASTNode ast) { String aident = compactStr(ast); if (qualifiedfilename != null) { qualifiedfilename = Names.getSimpleName(qualifiedfilename); } MapUtil.incMapValue(nodeVisits, aident); MapUtil.addToListMap(astNodeExtraInfos, aident, GENERATES_FILE + " \"" + qualifiedfilename + "." + fileextension + "\""); } /** * @see de.monticore.generating.templateengine.reporting.commons.DefaultReportEventHandler#reportCallAfterHookPoint(java.lang.String, * java.util.Collection, de.monticore.ast.ASTNode) */ @Override public void reportCallAfterHookPoint(String oldTemplate, Collection<HookPoint> afterHPs, ASTNode ast) { callHPS(oldTemplate, afterHPs, ast); } /** * @see de.monticore.generating.templateengine.reporting.commons.DefaultReportEventHandler#reportCallBeforeHookPoint(java.lang.String, * java.util.Collection, de.monticore.ast.ASTNode) */ @Override public void reportCallBeforeHookPoint(String oldTemplate, Collection<HookPoint> beforeHPs, ASTNode ast) { callHPS(oldTemplate, beforeHPs, ast); } /** * @see de.monticore.generating.templateengine.reporting.commons.DefaultReportEventHandler#reportCallReplacementHookPoint(java.lang.String, * java.util.List, de.monticore.ast.ASTNode) */ @Override public void reportCallReplacementHookPoint(String oldTemplate, List<HookPoint> hps, ASTNode ast) { callHPS(oldTemplate, hps, ast); } /** * @see de.monticore.generating.templateengine.reporting.commons.DefaultReportEventHandler#reportCallSpecificReplacementHookPoint(java.lang.String, * java.util.List, de.monticore.ast.ASTNode) */ @Override public void reportCallSpecificReplacementHookPoint(String oldTemplate, List<HookPoint> hps, ASTNode ast) { callSpecificHPS(oldTemplate, hps, ast); } /** * Uses ast2idents to print a compact version of the ASTNode * * @param ast * @return */ public String compactStr(ASTNode ast) { return repository.getASTNodeNameFormatted(ast); } /** * derive the tree structure of the AST using the ast idents + some decoration * coming from * * @param ast * @param ast2idents * @return */ private void deriveTreeStructureAST(ASTNode ast) { // this is a decoration of the tree at the lineend Map<String, String> endLineDecoration = Maps.newHashMap(); for (Entry<String, Integer> entry : nodeVisits.entrySet()) { endLineDecoration.put(entry.getKey(), "(" + entry.getValue() + "x)"); } TreePrintVisitor tpv = new TreePrintVisitor(repository, endLineDecoration, astNodeExtraInfos); tpv.handle(ast); serializedTreeResult = tpv.getTreeResult(); } private void resetVariables() { nodeVisits.clear(); astNodeExtraInfos.clear(); serializedTreeResult.clear(); } private void callSpecificHPS(String oldTemplate, List<HookPoint> hps, ASTNode ast) { for (HookPoint hp : hps) { callSpecificHP(hp, ast); } } private void callSpecificHP(HookPoint hp, ASTNode ast) { if (hp != null) { // if (hp instanceof StringHookPoint) { // String aident = compactStr(ast); // MapUtil.incMapValue(nodeVisits, aident); // MapUtil.addToListMap(astNodeExtraInfos, aident, SPECIFIC_STRING_HOOKPOINT + " " // + getHookPointValue(hp)); // } // else if (hp instanceof CodeHookPoint) { // String aident = compactStr(ast); // MapUtil.incMapValue(nodeVisits, aident); // MapUtil.addToListMap(astNodeExtraInfos, aident, SPECIFIC_CODE_HOOKPOINT + " " // + getHookPointValue(hp)); // } // else if (hp instanceof TemplateHookPoint) { String aident = compactStr(ast); MapUtil.incMapValue(nodeVisits, aident); MapUtil.addToListMap(astNodeExtraInfos, aident, SPECIFIC_TEMPLATE_HOOKPOINT + " " + getHookPointValue(hp)); } } } private void callHPS(String oldTemplate, Collection<HookPoint> hps, ASTNode ast) { for (HookPoint hp : hps) { callHP(hp, ast); } } private void callHP(HookPoint hp, ASTNode ast) { if (hp != null) { if (hp instanceof TemplateHookPoint) { String aident = compactStr(ast); MapUtil.incMapValue(nodeVisits, aident); MapUtil.addToListMap(astNodeExtraInfos, aident, TEMPLATE_HOOKPOINT + " " + getHookPointValue(hp)); } } } private String getHookPointValue(HookPoint hp) { String value = null; if (hp != null && hp instanceof TemplateHookPoint) { value = ((TemplateHookPoint) hp).getTemplateName(); value = ReportingHelper.getTemplateName(value); } else if (hp != null && hp instanceof StringHookPoint) { value = ((StringHookPoint) hp).getValue(); value = ReportingHelper.formatStringToReportingString(value, 50); } else if (hp != null && hp instanceof CodeHookPoint) { value = ((CodeHookPoint) hp).getClass().getName(); value = Names.getSimpleName(value); } return value; } @Override public void flush(ASTNode ast) { writeContent(ast); writeFooter(); resetVariables(); super.flush(ast); } }