From 89b1d5656dc1ac30c95604a5cdfad57282fb0672 Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Mon, 16 Dec 2019 19:17:34 +0100
Subject: [PATCH] small test with if. added naive prettyPrint.

---
 reusablecfg/src/main/jastadd/PrintCfg.jrag    | 28 ++++++++++++++---
 reusablecfg/src/main/jastadd/ReusableCfg.jrag | 30 ++++++++++++-------
 .../inf/st/reusablecfg/PrintCfg.java          | 13 ++++----
 3 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/reusablecfg/src/main/jastadd/PrintCfg.jrag b/reusablecfg/src/main/jastadd/PrintCfg.jrag
index 9ee8b36..41c32a7 100644
--- a/reusablecfg/src/main/jastadd/PrintCfg.jrag
+++ b/reusablecfg/src/main/jastadd/PrintCfg.jrag
@@ -24,11 +24,31 @@ import java.util.Queue;
 /** Helper attributes used to print a CFG in dot graph format. */
 aspect PrintCfg {
 
-  @Override
-  public String CfgNode.toString() {
-    return name();
+//  @Override
+//  public String CfgNode.toString() {
+//    return name();
+//  }
+
+  syn String CFG.prettyPrint() {
+    StringBuilder sb = new StringBuilder();
+    for (CfgNode cfgNode : getCfgNodeList()) {
+      sb.append(cfgNode.prettyPrint());
+    }
+    return sb.toString();
   }
 
+  syn String CfgNode.prettyPrint() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("Node ").append(name()).append(" for\n");
+    sb.append(getStmt().prettyPrint()).append("\n");
+    for (CfgNode succ : getSuccessorList()) {
+      sb.append("| ").append(name()).append(" -succ-> ").append(succ.name()).append("\n");
+    }
+    return sb.toString();
+  }
+
+  // ======================== old implementation below ========================
+
   public void BodyDecl.printReverseCfg() {
     entry().initPredecessors();
     System.out.println("digraph " + graphName() + " {");
@@ -104,7 +124,7 @@ aspect PrintCfg {
   eq CfgException.dotAttributes() = " [label=\"" + name() + "\",shape=box]";
   eq CfgMarker.dotAttributes() = " [label=\"" + name() + "\",shape=box]";
 
-  syn String CfgNode.name() = "a node";
+  syn String CfgNode.name() = "CfgNode@" + hashCode();
   eq CfgBranch.name() = branchLabel();
   eq CfgEntry.name() = "entry";
   eq CfgExit.name() = "exit";
diff --git a/reusablecfg/src/main/jastadd/ReusableCfg.jrag b/reusablecfg/src/main/jastadd/ReusableCfg.jrag
index 791cf02..afe745e 100644
--- a/reusablecfg/src/main/jastadd/ReusableCfg.jrag
+++ b/reusablecfg/src/main/jastadd/ReusableCfg.jrag
@@ -1,29 +1,29 @@
 aspect ReusableCfg {
 
-  syn CfgNode BodyDecl.emptyCFG() = new CfgNode();
+  syn CFG BodyDecl.emptyCFG() = new CFG();
   /**
    * Get the relational NTA of the CFG. Empty by default.
    */
-  syn CfgNode BodyDecl.reusableCFG() = emptyCFG();
+  syn CFG BodyDecl.reusableCFG() = emptyCFG();
   eq MethodDecl.reusableCFG() = hasBlock() ? getBlock().buildReusableCFG() : emptyCFG();
   eq ConstructorDecl.reusableCFG() = getBlock().buildReusableCFG();
 
   /**
    * Build the relational NTA of the CFG for a Block.
    */
-  syn lazy CfgNode Block.buildReusableCFG() {
-//    CfgNode result = entry(); // TODO alternative: take first expression
-    CfgNode result = new CfgNode();
+  syn lazy CFG Block.buildReusableCFG() {
+    CFG result = new CFG();
     if (getNumStmt() == 0) {
-      // dangling link to a stmt :(
       return result;
     }
     Map<Stmt, CfgNode> cfgNodes = new HashMap<>();
+//    Stmt first = entry(); // TODO alternative: take first expression
     Stmt first = getStmt(0);
-    result.setStmt(first);
-    cfgNodes.put(first, result);
+    CfgNode cfgNodeForFirst = first.cfgMakeCfgNode();
+    result.addCfgNode(cfgNodeForFirst);
+    cfgNodes.put(first, cfgNodeForFirst);
     Map<CfgNode, Stmt> todo = new HashMap<>();
-    first.cfgSuccessors().forEach(succ -> todo.put(result, succ));
+    first.cfgSuccessors().forEach(succ -> todo.put(cfgNodeForFirst, succ));
     while (!todo.isEmpty()) {
 //      Stmt current = todo.pop(); // this should be an tuple (node, successor). to set the relation
       CfgNode cfgNodeForPredecessor = todo.entrySet().iterator().next().getKey();
@@ -36,6 +36,7 @@ aspect ReusableCfg {
       } else {
         cfgNodeForCurrent = current.cfgMakeCfgNode();
         cfgNodes.put(current, cfgNodeForCurrent);
+        result.addCfgNode(cfgNodeForCurrent);
         // add successors to be inspected
         current.cfgSuccessors().forEach(succ -> todo.put(cfgNodeForCurrent, succ));
       }
@@ -45,8 +46,15 @@ aspect ReusableCfg {
     return result;
   }
 
-  syn CfgNode Stmt.cfgMakeCfgNode() = null; // TODO implement
-  syn Set<Stmt> Stmt.cfgSuccessors() = null; // TODO implement
+  // TODO implement
+  syn CfgNode Stmt.cfgMakeCfgNode() {
+    CfgNode result = new CfgNode();
+    result.setStmt(this);
+    return result;
+  }
+  syn Set<Stmt> Stmt.cfgSuccessors() = Collections.emptySet(); // TODO implement
+
+  eq IfStmt.cfgSuccessors() = hasElse() ? smallSet(getThen(), getElse()) : Collections.singleton(getThen());
 
 
   // ======================== old implementation below ========================
diff --git a/reusablecfg/src/main/java/de/tudresden/inf/st/reusablecfg/PrintCfg.java b/reusablecfg/src/main/java/de/tudresden/inf/st/reusablecfg/PrintCfg.java
index eecee6c..3a96404 100644
--- a/reusablecfg/src/main/java/de/tudresden/inf/st/reusablecfg/PrintCfg.java
+++ b/reusablecfg/src/main/java/de/tudresden/inf/st/reusablecfg/PrintCfg.java
@@ -15,10 +15,7 @@
  */
 package de.tudresden.inf.st.reusablecfg;
 
-import org.extendj.ast.BodyDecl;
-import org.extendj.ast.CompilationUnit;
-import org.extendj.ast.Program;
-import org.extendj.ast.TypeDecl;
+import org.extendj.ast.*;
 import org.extendj.parser.JavaParser;
 
 import java.io.FileInputStream;
@@ -56,10 +53,10 @@ public class PrintCfg {
           unit = program.getCompilationUnit(0);
           for (TypeDecl type : unit.getTypeDeclList()) {
             for (BodyDecl bd : type.getBodyDeclList()) {
-              if (reverse) {
-                bd.printReverseCfg();
-              } else {
-                bd.printCfg();
+              CFG cfg = bd.reusableCFG();
+              System.out.println(cfg.prettyPrint());
+              if (cfg.getNumCfgNode() == 0) {
+                System.out.println("No nodes in the CFG for '" + path + "'!");
               }
             }
           }
-- 
GitLab