From c541ef613537d24db7451995a692d1a2915760e1 Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Tue, 17 Dec 2019 18:02:52 +0100
Subject: [PATCH] construct CfgBranch with relational NTA

---
 reusablecfg/src/main/jastadd/CFG.relast       |  7 ++-
 reusablecfg/src/main/jastadd/PrintCfg.jrag    | 21 ++++---
 .../src/main/jastadd/PrintCfgTest.jrag        | 21 ++++---
 reusablecfg/src/main/jastadd/SimpleCFG.jrag   | 56 +++++++++++--------
 .../jastadd/VariableDeclarationScope.jrag     |  2 +-
 5 files changed, 64 insertions(+), 43 deletions(-)

diff --git a/reusablecfg/src/main/jastadd/CFG.relast b/reusablecfg/src/main/jastadd/CFG.relast
index 7a59542..312c6aa 100644
--- a/reusablecfg/src/main/jastadd/CFG.relast
+++ b/reusablecfg/src/main/jastadd/CFG.relast
@@ -27,8 +27,11 @@ CfgExit : CfgNode;
 CfgMethodCall : CfgNode;
 
 /** A conditional branch in the CFG.  */
-CfgBranch : CfgNode;
-rel CfgBranch.hostStatement -> Stmt;
+abstract CfgBranch : CfgNode;
+CfgStatementBranch : CfgBranch;
+rel CfgStatementBranch.hostStatement -> Stmt;
+CfgExpressionBranch : CfgBranch;
+rel CfgExpressionBranch.hostExpression -> ConditionalExpr;
 
 /** A branch in the CFG caused by potential thrown exceptions.  */
 CfgException : CfgNode;
diff --git a/reusablecfg/src/main/jastadd/PrintCfg.jrag b/reusablecfg/src/main/jastadd/PrintCfg.jrag
index 45651f3..4c94b4e 100644
--- a/reusablecfg/src/main/jastadd/PrintCfg.jrag
+++ b/reusablecfg/src/main/jastadd/PrintCfg.jrag
@@ -115,17 +115,22 @@ aspect PrintCfg {
   inh String CfgMethodCall.callLabel();
   eq MethodAccess.call().callLabel() = name() + "()";
 
-  inh String CfgBranch.branchLabel();
-  eq IfStmt.branch().branchLabel() = "if (" + getCondition().prettyPrint() + ")";
-  eq ConditionalExpr.branch().branchLabel() = "if (" + getCondition().prettyPrint() + ")";
-  eq ForStmt.branch().branchLabel() = "for (" + getCondition().prettyPrint() + ")";
-  eq WhileStmt.branch().branchLabel() = "while (" + getCondition().prettyPrint() + ")";
-  eq DoStmt.branch().branchLabel() = "do_while (" + getCondition().prettyPrint() + ")";
-  eq EnhancedForStmt.branch().branchLabel() = String.format("for (%s %s : %s)",
+  syn String CfgBranch.branchLabel();
+  eq CfgStatementBranch.branchLabel() = getHostStatement().branchLabel();
+  eq CfgExpressionBranch.branchLabel() = getHostExpression().branchLabel();
+
+  syn String Stmt.branchLabel() = "";
+  eq IfStmt.branchLabel() = "if (" + getCondition().prettyPrint() + ")";
+  eq ForStmt.branchLabel() = "for (" + getCondition().prettyPrint() + ")";
+  eq WhileStmt.branchLabel() = "while (" + getCondition().prettyPrint() + ")";
+  eq DoStmt.branchLabel() = "do_while (" + getCondition().prettyPrint() + ")";
+  eq EnhancedForStmt.branchLabel() = String.format("for (%s %s : %s)",
       getVariableDecl().getTypeAccess().prettyPrint(),
       getVariableDecl().getID(),
       getExpr().prettyPrint());
-  eq SwitchStmt.branch().branchLabel() = "switch (" + getExpr().prettyPrint() + ")";
+  eq SwitchStmt.branchLabel() = "switch (" + getExpr().prettyPrint() + ")";
+
+  syn String ConditionalExpr.branchLabel() = "if (" + getCondition().prettyPrint() + ")";
 
   inh String CfgMarker.markerName();
   eq BreakStmt.marker().markerName() = "break";
diff --git a/reusablecfg/src/main/jastadd/PrintCfgTest.jrag b/reusablecfg/src/main/jastadd/PrintCfgTest.jrag
index d8f8c36..9fe1c1a 100644
--- a/reusablecfg/src/main/jastadd/PrintCfgTest.jrag
+++ b/reusablecfg/src/main/jastadd/PrintCfgTest.jrag
@@ -152,14 +152,19 @@ aspect PrintCfgTest {
   eq CfgMarker.varName() = markerVarName();
   eq CfgMethodCall.varName() = methodAccess().getID();
 
-  inh String CfgBranch.branchKind();
-  eq IfStmt.branch().branchKind() = "if";
-  eq ConditionalExpr.branch().branchKind() = "if";
-  eq ForStmt.branch().branchKind() = "for";
-  eq WhileStmt.branch().branchKind() = "while";
-  eq DoStmt.branch().branchKind() = "doWhile";
-  eq EnhancedForStmt.branch().branchKind() = "for";
-  eq SwitchStmt.branch().branchKind() = "switch";
+  syn String CfgBranch.branchKind();
+  eq CfgStatementBranch.branchKind() = getHostStatement().branchKind();
+  eq CfgExpressionBranch.branchKind() = getHostExpression().branchKind();
+
+  syn String Stmt.branchKind() = "";
+  eq IfStmt.branchKind() = "if";
+  eq ForStmt.branchKind() = "for";
+  eq WhileStmt.branchKind() = "while";
+  eq DoStmt.branchKind() = "doWhile";
+  eq EnhancedForStmt.branchKind() = "for";
+  eq SwitchStmt.branchKind() = "switch";
+
+  syn String ConditionalExpr.branchKind() = "if";
 
   inh String CfgMarker.markerVarName();
   eq BreakStmt.marker().markerVarName() = "breakMarker";
diff --git a/reusablecfg/src/main/jastadd/SimpleCFG.jrag b/reusablecfg/src/main/jastadd/SimpleCFG.jrag
index 40c66bc..ab68075 100644
--- a/reusablecfg/src/main/jastadd/SimpleCFG.jrag
+++ b/reusablecfg/src/main/jastadd/SimpleCFG.jrag
@@ -60,7 +60,16 @@ aspect SimpleCFG {
   eq CfgMarker.successors() = succ();
 
   /** Successors to this branch node. */
-  inh Set<? extends CfgNode> CfgBranch.succ();
+  syn Set<? extends CfgNode> CfgBranch.succ();
+  eq CfgStatementBranch.succ() = getHostStatement().branchSucc();
+  eq CfgExpressionBranch.succ() = getHostExpression().branchSucc();
+
+  /** Successors of a Stmt */
+  syn Set<? extends CfgNode> Stmt.branchSucc() = Collections.emptySet();
+
+
+  /** Successors of a Stmt */
+  syn Set<? extends CfgNode> ConditionalExpr.branchSucc();
 
   /** Successors to this method call node. */
   inh Set<? extends CfgNode> CfgMethodCall.succ();
@@ -440,9 +449,9 @@ aspect SimpleCFG {
   eq Dot.getLeft().follow() = getRight().entry();
 
   /** The branch node for this conditional expression. */
-  syn nta CfgBranch ConditionalExpr.branch() {
-    CfgBranch branch = new CfgBranch();
-    branch.setHostStatement(hostStatement());
+  syn lazy CfgExpressionBranch ConditionalExpr.branch() {
+    CfgExpressionBranch branch = new CfgExpressionBranch();
+    branch.setHostExpression(this);
     return branch;
   }
 
@@ -467,12 +476,12 @@ aspect SimpleCFG {
   eq ConditionalExpr.thenEndMarker().succ() = Collections.singleton(follow());
   eq ConditionalExpr.elseEndMarker().succ() = Collections.singleton(follow());
 
-  eq ConditionalExpr.branch().succ() =
+  eq ConditionalExpr.branchSucc() =
       smallSet(getTrueExpr().entry(), getFalseExpr().entry());
 
   /** The branch node for this statement. */
-  syn nta CfgBranch IfStmt.branch() {
-    CfgBranch branch = new CfgBranch();
+  syn lazy CfgStatementBranch IfStmt.branch() {
+    CfgStatementBranch branch = new CfgStatementBranch();
     branch.setHostStatement(this);
     return branch;
   }
@@ -493,14 +502,14 @@ aspect SimpleCFG {
   eq IfStmt.thenEndMarker().succ() = Collections.singleton(follow());
   eq IfStmt.elseEndMarker().succ() = Collections.singleton(follow());
 
-  eq IfStmt.branch().succ() =
+  eq IfStmt.branchSucc() =
       hasElse()
       ? smallSet(getThen().entry(), getElse().entry())
       : smallSet(getThen().entry(), follow());
 
   /** The branch node for this statement. */
-  syn nta CfgBranch ForStmt.branch() {
-    CfgBranch branch = new CfgBranch();
+  syn lazy CfgStatementBranch ForStmt.branch() {
+    CfgStatementBranch branch = new CfgStatementBranch();
     branch.setHostStatement(this);
     return branch;
   }
@@ -537,7 +546,7 @@ aspect SimpleCFG {
       ? Collections.singleton(getUpdateStmt(0).entry())
       : Collections.singleton(getCondition().entry());
 
-  eq ForStmt.branch().succ() {
+  eq ForStmt.branchSucc() {
     if (getCondition().isTrue()) {
       return Collections.singleton(getStmt().entry());
     } else if (getCondition().isFalse()) {
@@ -548,8 +557,8 @@ aspect SimpleCFG {
   }
 
   /** The branch node for this statement. */
-  syn nta CfgBranch EnhancedForStmt.branch() {
-    CfgBranch branch = new CfgBranch();
+  syn lazy CfgStatementBranch EnhancedForStmt.branch() {
+    CfgStatementBranch branch = new CfgStatementBranch();
     branch.setHostStatement(this);
     return branch;
   }
@@ -557,8 +566,7 @@ aspect SimpleCFG {
   /** The CFG end marker for this loop. */
   syn nta CfgMarker EnhancedForStmt.loopEndMarker() = new CfgMarker();
 
-  eq EnhancedForStmt.branch().succ() =
-      smallSet(getStmt().entry(), follow());
+  eq EnhancedForStmt.branchSucc() = smallSet(getStmt().entry(), follow());
 
   eq EnhancedForStmt.entry() = getExpr().entry();
 
@@ -571,8 +579,8 @@ aspect SimpleCFG {
   eq EnhancedForStmt.loopEndMarker().succ() = Collections.singleton(entry());
 
   /** The branch node for this statement. */
-  syn nta CfgBranch WhileStmt.branch() {
-    CfgBranch branch = new CfgBranch();
+  syn lazy CfgStatementBranch WhileStmt.branch() {
+    CfgStatementBranch branch = new CfgStatementBranch();
     branch.setHostStatement(this);
     return branch;
   }
@@ -590,7 +598,7 @@ aspect SimpleCFG {
 
   eq WhileStmt.loopEndMarker().succ() = Collections.singleton(entry());
 
-  eq WhileStmt.branch().succ() {
+  eq WhileStmt.branchSucc() {
     if (getCondition().isTrue()) {
       return Collections.singleton(getStmt().entry());
     } else if (getCondition().isFalse()) {
@@ -601,8 +609,8 @@ aspect SimpleCFG {
   }
 
   /** The branch node for this statement. */
-  syn nta CfgBranch DoStmt.branch() {
-    CfgBranch branch = new CfgBranch();
+  syn lazy CfgStatementBranch DoStmt.branch() {
+    CfgStatementBranch branch = new CfgStatementBranch();
     branch.setHostStatement(this);
     return branch;
   }
@@ -621,7 +629,7 @@ aspect SimpleCFG {
   eq DoStmt.getCondition().follow() = branch();
 
   // Loop back.
-  eq DoStmt.branch().succ() {
+  eq DoStmt.branchSucc() {
     if (getCondition().isTrue()) {
       return Collections.singleton(entry());
     } else if (getCondition().isFalse()) {
@@ -631,8 +639,8 @@ aspect SimpleCFG {
     }
   }
 
-  syn nta CfgBranch SwitchStmt.branch() {
-    CfgBranch branch = new CfgBranch();
+  syn lazy CfgStatementBranch SwitchStmt.branch() {
+    CfgStatementBranch branch = new CfgStatementBranch();
     branch.setHostStatement(this);
     return branch;
   }
@@ -641,7 +649,7 @@ aspect SimpleCFG {
 
   eq SwitchStmt.getExpr().follow() = branch();
 
-  eq SwitchStmt.branch().succ() {
+  eq SwitchStmt.branchSucc() {
     Set<CfgNode> set = Collections.newSetFromMap(
         new IdentityHashMap<CfgNode, Boolean>());
     boolean hasDefault = false;
diff --git a/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag b/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag
index 501017f..d48e114 100644
--- a/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag
+++ b/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag
@@ -27,7 +27,7 @@ aspect VariableDeclarationScope {
    */
   syn boolean CfgNode.isDeclarationOf(Variable var) = false;
 
-  eq CfgBranch.isDeclarationOf(Variable var) =
+  eq CfgStatementBranch.isDeclarationOf(Variable var) =
       getHostStatement().declaresVariable(var)
       || getHostStatement().variableDeclaredInside(var);
 
-- 
GitLab