/* * ****************************************************************************** * 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.commons; import java.util.List; import java.util.Map; import java.util.Stack; import de.monticore.ast.ASTNode; import com.google.common.collect.Lists; import de.monticore.visitor.CommonVisitor; /** * We use the visit mechanism to map the AST to a list of showing the AST-Nodes * as tree. As a basis we use ast2idents that maps each node into a string in a * compact form. Result is store as list for print * * @author BR */ public class TreePrintVisitor implements CommonVisitor { private ReportingRepository repo; // output to be stored here: protected List<String> treeResult; Stack<String> indents; static final String INITALINDENT = ""; static final String INDENT1 = "+--"; static final String INDENT2 = "| "; static final String INDENT3 = " "; // contains possible decorations for each entry in the tree // printed at the end of the line // null is a valid value (= no decoration) Map<String, String> endLineDecoration; // contains possible extra infos for each entry in the tree // printed in individual lines (and indented) // null is a valid value (= no extra info) and no empty line Map<String, List<String>> astNodeExtraInfos; /* visits all nodes and prints them as one liner with correct indentation */ @Override public void visit(ASTNode a) { // prepare the output String nodeId = repo.getASTNodeNameFormatted(a); String out = indents.peek() + INDENT1 + nodeId; if (endLineDecoration != null && endLineDecoration.containsKey(nodeId)) { String decor = endLineDecoration.get(nodeId); out = Layouter.padleft(out, 60) + " " + decor; } treeResult.add(out); String nextIndent = (indents.size() == 1) ? INDENT3 : INDENT2; // care for potential children: indents.push(indents.peek() + nextIndent); // print the extra infos if (astNodeExtraInfos != null && astNodeExtraInfos.containsKey(nodeId)) { List<String> extras = astNodeExtraInfos.get(nodeId); for (String s : extras) { treeResult.add(Layouter.padleft(indents.peek(), 20) + " " + s); } } } @Override public void endVisit(ASTNode a) { // remove children stuff indents.pop(); } /** * produces the raw tree without any decoration * * @param ast2idents * @param treeResult */ public TreePrintVisitor() { this(null, null, null); } /** * produces the tree with an inline decoration (at the end of each line) * * @param ast2idents * @param treeResult * @param endLineDecoration */ public TreePrintVisitor(ReportingRepository repo, Map<String, String> endLineDecoration, Map<String, List<String>> astNodeExtraInfos) { super(); this.repo = repo; this.treeResult = Lists.newArrayList(); this.endLineDecoration = endLineDecoration; this.astNodeExtraInfos = astNodeExtraInfos; indents = new Stack<String>(); indents.add(INITALINDENT); } public List<String> getTreeResult() { return treeResult; } }