-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Large refactoring to simplify visitor behaviour for export functionality
- Loading branch information
1 parent
c0ca712
commit 0ee387f
Showing
16 changed files
with
278 additions
and
142 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
smojol-core/src/main/java/org/smojol/common/ast/BytecodeGeneratorVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.smojol.common.ast; | ||
|
||
public class BytecodeGeneratorVisitor extends FlowNodeASTVisitor<FlowNode> { | ||
public BytecodeGeneratorVisitor(FlowNode ancestor) { | ||
super(ancestor); | ||
} | ||
|
||
@Override | ||
public FlowNodeASTVisitor<FlowNode> visit(FlowNode node) { | ||
return this; | ||
} | ||
} |
13 changes: 10 additions & 3 deletions
13
smojol-core/src/main/java/org/smojol/common/ast/FlowNodeASTVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,14 @@ | ||
package org.smojol.common.ast; | ||
|
||
public abstract class FlowNodeASTVisitor<T> { | ||
protected final T ancestor; | ||
|
||
public interface FlowNodeASTVisitor<T> { | ||
T visit(FlowNode node, T parent); | ||
T root(); | ||
public FlowNodeASTVisitor(T ancestor) { | ||
this.ancestor = ancestor; | ||
} | ||
|
||
public abstract FlowNodeASTVisitor<T> visit(FlowNode node); | ||
public T root() { | ||
return ancestor; | ||
} | ||
} |
21 changes: 12 additions & 9 deletions
21
smojol-core/src/main/java/org/smojol/common/ast/SerialisableFlowNodeASTVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,20 @@ | ||
package org.smojol.common.ast; | ||
|
||
|
||
public class SerialisableFlowNodeASTVisitor implements FlowNodeASTVisitor<SerialisableASTFlowNode> { | ||
SerialisableASTFlowNode root = new SerialisableASTFlowNode(); | ||
@Override | ||
public SerialisableASTFlowNode visit(FlowNode node, SerialisableASTFlowNode parent) { | ||
SerialisableASTFlowNode child = new SerialisableASTFlowNode(node); | ||
parent.addChild(child); | ||
return child; | ||
public class SerialisableFlowNodeASTVisitor extends FlowNodeASTVisitor<SerialisableASTFlowNode> { | ||
public SerialisableFlowNodeASTVisitor(SerialisableASTFlowNode ancestorNode) { | ||
super(ancestorNode); | ||
} | ||
|
||
public SerialisableFlowNodeASTVisitor() { | ||
this(null); | ||
} | ||
|
||
@Override | ||
public SerialisableASTFlowNode root() { | ||
return root; | ||
public FlowNodeASTVisitor<SerialisableASTFlowNode> visit(FlowNode node) { | ||
SerialisableASTFlowNode child = new SerialisableASTFlowNode(node); | ||
if (ancestor == null) return new SerialisableFlowNodeASTVisitor(child); | ||
ancestor.addChild(child); | ||
return new SerialisableFlowNodeASTVisitor(child); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
...rc/main/java/org/smojol/toolkit/analysis/graph/graphml/JGraphTASTGraphBuilderVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.smojol.toolkit.analysis.graph.graphml; | ||
|
||
import org.smojol.common.ast.FlowNode; | ||
import org.smojol.common.ast.FlowNodeASTVisitor; | ||
import org.smojol.toolkit.analysis.graph.jgrapht.JGraphTCodeOperations; | ||
|
||
import static com.mojo.woof.NodeRelations.CONTAINS_CODE; | ||
|
||
public class JGraphTASTGraphBuilderVisitor extends FlowNodeASTVisitor<FlowNode> { | ||
private final JGraphTCodeOperations astGraphOperations; | ||
|
||
public JGraphTASTGraphBuilderVisitor(JGraphTCodeOperations astGraphOperations, FlowNode ancestor) { | ||
super(ancestor); | ||
this.astGraphOperations = astGraphOperations; | ||
} | ||
|
||
public JGraphTASTGraphBuilderVisitor(JGraphTCodeOperations astGraphOperations) { | ||
this(astGraphOperations, null); | ||
} | ||
|
||
@Override | ||
public FlowNodeASTVisitor<FlowNode> visit(FlowNode node) { | ||
astGraphOperations.addNode(node); | ||
if (ancestor == null) return new JGraphTASTGraphBuilderVisitor(astGraphOperations, node); | ||
astGraphOperations.connect(ancestor, node, CONTAINS_CODE); | ||
return new JGraphTASTGraphBuilderVisitor(astGraphOperations, node); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
...n/java/org/smojol/toolkit/analysis/graph/graphml/JGraphTDataDependencyBuilderVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package org.smojol.toolkit.analysis.graph.graphml; | ||
|
||
import org.apache.commons.lang3.tuple.ImmutablePair; | ||
import org.smojol.common.ast.FlowNode; | ||
import org.smojol.common.ast.FlowNodeASTVisitor; | ||
import org.smojol.common.vm.structure.CobolDataStructure; | ||
import org.smojol.toolkit.analysis.graph.DataDependencyPairComputer; | ||
import org.smojol.toolkit.analysis.graph.jgrapht.JGraphTDataOperations; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static com.mojo.woof.NodeRelations.*; | ||
import static com.mojo.woof.NodeRelations.FLOWS_INTO; | ||
|
||
public class JGraphTDataDependencyBuilderVisitor extends FlowNodeASTVisitor<CobolDataStructure> { | ||
private final JGraphTDataOperations dataGraphOperations; | ||
private final CobolDataStructure dataRoot; | ||
|
||
public JGraphTDataDependencyBuilderVisitor(JGraphTDataOperations jGraphTDataOperations, CobolDataStructure dataRoot) { | ||
this(jGraphTDataOperations, dataRoot, null); | ||
} | ||
|
||
public JGraphTDataDependencyBuilderVisitor(JGraphTDataOperations jGraphTDataOperations, CobolDataStructure dataRoot, CobolDataStructure ancestor) { | ||
super(ancestor); | ||
this.dataGraphOperations = jGraphTDataOperations; | ||
this.dataRoot = dataRoot; | ||
} | ||
|
||
@Override | ||
public FlowNodeASTVisitor<CobolDataStructure> visit(FlowNode node) { | ||
Map.Entry<List<CobolDataStructure>, List<CobolDataStructure>> pairs = DataDependencyPairComputer.dependencyPairs(node, dataRoot); | ||
if (ImmutablePair.nullPair().equals(pairs)) return this; | ||
if (pairs.getValue().isEmpty()) { | ||
accesses(node, pairs.getKey()); | ||
return this; | ||
} | ||
connect(pairs.getKey(), pairs.getValue(), node); | ||
return this; | ||
} | ||
|
||
private void accesses(FlowNode node, List<CobolDataStructure> accessedStructures) { | ||
accessedStructures.forEach(s -> { | ||
if (!dataGraphOperations.containsVertex(s)) dataGraphOperations.addNode(s); | ||
dataGraphOperations.connect(node, s, ACCESSES); | ||
}); | ||
} | ||
|
||
private void connect(List<CobolDataStructure> froms, List<CobolDataStructure> tos, FlowNode node) { | ||
tos.forEach(to -> { | ||
dataGraphOperations.connect(node, to, MODIFIES); | ||
froms.forEach(from -> { | ||
if (!dataGraphOperations.containsVertex(from)) dataGraphOperations.addNode(from); | ||
dataGraphOperations.connect(node, from, ACCESSES); | ||
dataGraphOperations.connect(from, to, FLOWS_INTO); | ||
}); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
...olkit/src/main/java/org/smojol/toolkit/analysis/graph/graphml/Neo4JASTBuilderVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.smojol.toolkit.analysis.graph.graphml; | ||
|
||
import com.mojo.woof.GraphSDK; | ||
import org.neo4j.driver.Record; | ||
import org.smojol.common.ast.FlowNode; | ||
import org.smojol.common.ast.FlowNodeASTVisitor; | ||
import org.smojol.toolkit.analysis.graph.NodeSpecBuilder; | ||
import org.smojol.toolkit.analysis.graph.neo4j.NodeReferenceStrategy; | ||
|
||
public class Neo4JASTBuilderVisitor extends FlowNodeASTVisitor<Record> { | ||
private final NodeReferenceStrategy astNodeReferenceStrategy; | ||
private final GraphSDK graphSDK; | ||
private final NodeSpecBuilder qualifier; | ||
|
||
public Neo4JASTBuilderVisitor(NodeReferenceStrategy astNodeReferenceStrategy, GraphSDK graphSDK, NodeSpecBuilder qualifier, Record ancestorRecord) { | ||
super(ancestorRecord); | ||
this.astNodeReferenceStrategy = astNodeReferenceStrategy; | ||
this.graphSDK = graphSDK; | ||
this.qualifier = qualifier; | ||
} | ||
|
||
public Neo4JASTBuilderVisitor(NodeReferenceStrategy astNodeReferenceStrategy, GraphSDK sdk, NodeSpecBuilder qualifier) { | ||
this(astNodeReferenceStrategy, sdk, qualifier, null); | ||
} | ||
|
||
@Override | ||
public FlowNodeASTVisitor<Record> visit(FlowNode node) { | ||
Record record = astNodeReferenceStrategy.reference(node, graphSDK, qualifier); | ||
if (ancestor == null) return new Neo4JASTBuilderVisitor(astNodeReferenceStrategy, graphSDK, qualifier, record); | ||
graphSDK.containsCodeNode(ancestor, record); | ||
return new Neo4JASTBuilderVisitor(astNodeReferenceStrategy, graphSDK, qualifier, record); | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
...ain/java/org/smojol/toolkit/analysis/graph/graphml/Neo4JDataDependencyBuilderVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package org.smojol.toolkit.analysis.graph.graphml; | ||
|
||
import com.mojo.woof.GraphSDK; | ||
import org.apache.commons.lang3.tuple.ImmutablePair; | ||
import org.neo4j.driver.Record; | ||
import org.smojol.common.ast.FlowNode; | ||
import org.smojol.common.ast.FlowNodeASTVisitor; | ||
import org.smojol.common.vm.structure.CobolDataStructure; | ||
import org.smojol.toolkit.analysis.graph.DataDependencyPairComputer; | ||
import org.smojol.toolkit.analysis.graph.NodeSpecBuilder; | ||
import org.smojol.toolkit.analysis.graph.NodeToWoof; | ||
import org.smojol.toolkit.analysis.graph.neo4j.NodeReferenceStrategy; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class Neo4JDataDependencyBuilderVisitor extends FlowNodeASTVisitor<Record> { | ||
|
||
private final GraphSDK sdk; | ||
private final NodeSpecBuilder qualifier; | ||
private final NodeReferenceStrategy dependencyAttachmentStrategy; | ||
private final CobolDataStructure dataRoot; | ||
|
||
public Neo4JDataDependencyBuilderVisitor(CobolDataStructure dataRoot, GraphSDK graphSDK, NodeSpecBuilder qualifier, NodeReferenceStrategy dependencyAttachmentStrategy, Record ancestor) { | ||
super(ancestor); | ||
this.sdk = graphSDK; | ||
this.qualifier = qualifier; | ||
this.dependencyAttachmentStrategy = dependencyAttachmentStrategy; | ||
this.dataRoot = dataRoot; | ||
} | ||
|
||
public Neo4JDataDependencyBuilderVisitor(CobolDataStructure dataRoot, GraphSDK sdk, NodeSpecBuilder qualifier, NodeReferenceStrategy dependencyAttachmentStrategy) { | ||
this(dataRoot, sdk, qualifier, dependencyAttachmentStrategy, null); | ||
} | ||
|
||
@Override | ||
public FlowNodeASTVisitor<Record> visit(FlowNode node) { | ||
Map.Entry<List<CobolDataStructure>, List<CobolDataStructure>> pairs = DataDependencyPairComputer.dependencyPairs(node, dataRoot); | ||
if (ImmutablePair.nullPair().equals(pairs)) return this; | ||
if (pairs.getValue().isEmpty()) { | ||
accesses(node, pairs.getKey()); | ||
return this; | ||
} | ||
connect(pairs.getKey(), pairs.getValue(), node); | ||
return this; | ||
} | ||
|
||
private void accesses(FlowNode attachmentNode, List<CobolDataStructure> dataNodes) { | ||
System.out.println("Attaching IF??? " + attachmentNode.type() + " " + dataNodes.size()); | ||
Record attachmentNodeRecord = dependencyAttachmentStrategy.reference(attachmentNode, sdk, qualifier); | ||
dataNodes.forEach(n -> { | ||
Record n4jFrom = sdk.newOrExisting(qualifier.dataNodeSearchSpec(n), NodeToWoof.dataStructureToWoof(n, qualifier)); | ||
sdk.accesses(attachmentNodeRecord, n4jFrom); | ||
}); | ||
} | ||
|
||
private void connect(List<CobolDataStructure> froms, List<CobolDataStructure> tos, FlowNode attachmentNode) { | ||
Record attachmentNodeRecord = dependencyAttachmentStrategy.reference(attachmentNode, sdk, qualifier); | ||
tos.forEach(to -> { | ||
froms.forEach(f -> System.out.println(f.name())); | ||
List<Record> nodes = sdk.findNodes(qualifier.dataNodeSearchSpec(to)); | ||
Record n4jTo = !nodes.isEmpty() ? nodes.getFirst() : sdk.createNode(NodeToWoof.dataStructureToWoof(to, qualifier)); | ||
sdk.modifies(attachmentNodeRecord, n4jTo); | ||
froms.forEach(from -> { | ||
Record n4jFrom = sdk.newOrExisting(qualifier.dataNodeSearchSpec(from), NodeToWoof.dataStructureToWoof(from, qualifier)); | ||
sdk.flowsInto(n4jFrom, n4jTo); | ||
sdk.accesses(attachmentNodeRecord, n4jFrom); | ||
}); | ||
}); | ||
} | ||
} |
Oops, something went wrong.