Skip to content
Snippets Groups Projects
Commit 1a2e33a6 authored by Martin Zloch's avatar Martin Zloch
Browse files

Merge branch 'master' of build.se.informatik.uni-kiel.de:chw/integration-project

parents 4f570e88 d8e4f0b2
No related branches found
No related tags found
No related merge requests found
package de.johl;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import model.ParallelizationPattern;
import model.Pattern;
import model.Query;
public class PatternTester {
private static final String UPDATE = "update";
private static final String MATCH = "match";
public static void main(String[] args) throws IOException {
if (args.length < 3)
return;
final String matchOrUpdate = args[0];
final String patternXmlFilePath = args[1];
final String inputDatabaseFilePath = args[2];
if (matchOrUpdate.equals(UPDATE) && args.length < 5) {
System.err.println(
"'update' requires a fourth and fith argument: output directory and index of match to update");
return;
}
Pattern pattern = new Pattern(new File(patternXmlFilePath));
TempNeo4jInstance neo4j = new TempNeo4jInstance();
neo4j.load(new File(inputDatabaseFilePath));
final GraphDatabaseService database = neo4j.getService();
if (matchOrUpdate.equals(MATCH)) {
runMatchQuery(database, pattern);
} else if (matchOrUpdate.equals(UPDATE)) {
final int index = Integer.parseInt(args[4]);
runUpdateQuery(database, pattern, index);
database.shutdown();
final String outputDir = args[3];
neo4j.save(outputDir);
} else {
System.err.println("unknown command: " + matchOrUpdate);
}
}
private static void printResultStatistics(Result result) {
org.neo4j.graphdb.QueryStatistics stats = result.getQueryStatistics();
System.out.println("deleted nodes: " + stats.getNodesDeleted());
System.out.println("create nodes: " + stats.getNodesCreated());
System.out.println("deleted relations: " + stats.getRelationshipsDeleted());
System.out.println("create relations: " + stats.getRelationshipsCreated());
}
private static void printResult(Result result) {
System.out.println("result:");
while (result.hasNext()) {
Map<String, Object> bar = result.next();
for (Map.Entry<String, Object> entry : bar.entrySet()) {
System.out.println(" " + entry.getKey() + ":" + entry.getValue());
}
System.out.println(" ---");
}
}
@SuppressWarnings("unused")
private static void runTestQuery(GraphDatabaseService database, final Map<String, Object> params) {
try (final Transaction transaction = database.beginTx()) {
String q = "MATCH (prev)-[in:CONTROL_FLOW]->(mc1)-[to:CONTROL_FLOW]->(mc2)-[out:CONTROL_FLOW]->(next) where ID(mc1)=10698 and ID(mc2)=10699 return in,to,out";
String q2 = "MATCH (mc1) where ID(mc1)=10698 return mc1.fqn";
String q3 = "MATCH (prev)-[in:CONTROL_FLOW]->(mc1)-[to:CONTROL_FLOW]->(mc2)-[out:CONTROL_FLOW]->(next) where ID(mc1)={mc1} and ID(mc2)={mc2} return in,to,out";
System.out.println("Running test query...");
try (final Result result = database.execute(q3, params)) {
printResultStatistics(result);
printResult(result);
}
transaction.success();
transaction.close();
}
}
private static void runUpdateQuery(GraphDatabaseService database, Pattern pattern, int index) {
String candidatePattern = pattern.getCandidateQuery().generateQueryString();
System.out.println("Canidate Query: " + candidatePattern);
List<Map<String, Object>> matches = null;
System.out.println("Running match query...");
try (Result result = database.execute(candidatePattern)) {
printResultStatistics(result);
matches = retrieveResultAsList(result);
System.out.println("found " + matches.size() + " matches");
if (index >= matches.size()) {
throw new IllegalArgumentException("index of out range");
}
}
// runTestQuery(database, params);
runUpdate(database, pattern, matches.get(index));
}
private static void runUpdate(final GraphDatabaseService database, final Pattern pattern,
final Map<String, Object> match) {
List<ParallelizationPattern> queries = pattern.getUpdatePatterns();
for (Query q : queries.get(0).getQueries()) {
String text = q.generateQueryString();
System.out.println("query:----------------------------------------");
System.out.println(text);
System.out.println("----------------------------------------");
try (final Transaction transaction = database.beginTx()) {
try (Result result = database.execute(text, match)) {
printResultStatistics(result);
transaction.success();
transaction.close();
}
}
}
}
private static void runMatchQuery(GraphDatabaseService database, Pattern pattern) {
try (Result result = database.execute(pattern.getCandidateQuery().generateQueryString())) {
List<Map<String, Object>> matches = retrieveResultAsList(result);
for (int i = 0; i < matches.size(); ++i) {
System.out.println("" + i + ": " + getDisplayString(matches.get(i)));
}
}
}
private static String getDisplayString(final Map<String, Object> match) {
String display = "?";
Object object = match.get("display");
if (object != null)
return object.toString();
return display;
}
private static List<Map<String, Object>> retrieveResultAsList(Result result) {
List<Map<String, Object>> list = new ArrayList<>();
while (result.hasNext()) {
Map<String, Object> nodes = result.next();
for (Map.Entry<String, Object> entry : nodes.entrySet()) {
System.out.println(" " + entry.getKey() + ":" + entry.getValue());
}
System.out.println(" ---");
list.add(nodes);
}
return list;
}
}
package de.johl;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.CopyOption;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseBuilder;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.io.fs.FileUtils;
import logging.Logger;
public class TempNeo4jInstance {
private GraphDatabaseService databaseService = null;
private Path tempDatabasePath = null;
private Thread shutdownHook = null;
private void close() {
if (databaseService != null) {
databaseService.shutdown();
databaseService = null;
tempDatabasePath = null;
Runtime.getRuntime().removeShutdownHook(shutdownHook);
}
}
private void open(final Path path) {
GraphDatabaseFactory graphDatabaseFactory = new GraphDatabaseFactory();
GraphDatabaseBuilder builder = graphDatabaseFactory.newEmbeddedDatabaseBuilder(path.toFile());
builder.setConfig(GraphDatabaseSettings.allow_store_upgrade, "true");
final GraphDatabaseService service = builder.newGraphDatabase();
shutdownHook = new Thread() {
@Override
public void run() {
service.shutdown();
try {
deleteRecursive(path.toFile());
} catch (FileNotFoundException e) {
Logger.exception(e);
}
}
};
Runtime.getRuntime().addShutdownHook(shutdownHook);
this.databaseService = service;
this.tempDatabasePath = path;
}
private Path createTempDatabaseDirectory() throws IOException {
final Path systemTempDir = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"));
final Path databaseTempDir = Files.createTempDirectory(systemTempDir, "neosuit");
return databaseTempDir;
}
private static boolean deleteRecursive(final File path) throws FileNotFoundException {
if (!path.exists()) {
throw new FileNotFoundException(path.getAbsolutePath());
}
boolean ret = true;
if (path.isDirectory()) {
for (File f : path.listFiles()) {
ret = ret && deleteRecursive(f);
}
}
return ret && path.delete();
}
private void copyFolder(final File source, final File dest, CopyOption... options) throws IOException {
if (!dest.exists()) {
dest.mkdirs();
}
File[] contents = source.listFiles();
if (contents != null) {
for (File f : contents) {
String p = dest.getAbsolutePath() + File.separator + f.getName();
File newFile = new File(p);
if (f.isDirectory()) {
copyFolder(f, newFile, options);
} else {
Files.copy(f.toPath(), newFile.toPath(), options);
}
}
}
}
public void load(final Path path) throws IOException {
load(path.toFile());
}
public void load(final String path) throws IOException {
load(new File(path));
}
public void load(final File sourceDatabaseDirectory) throws IOException {
close();
if (!sourceDatabaseDirectory.isDirectory()) {
throw new FileNotFoundException(sourceDatabaseDirectory.toString());
}
Path tempDatabasePath = createTempDatabaseDirectory();
File tempDatabaseDirectory = tempDatabasePath.toFile();
copyFolder(sourceDatabaseDirectory, tempDatabaseDirectory);
open(tempDatabasePath);
}
public void save(final String path) throws IOException {
if (this.databaseService == null || this.tempDatabasePath == null) {
throw new IllegalStateException("No database loaded");
}
File destDatabaseFile = new File(path);
if (destDatabaseFile.isDirectory()) {
FileUtils.deleteRecursively(new File(path));
}
if (!destDatabaseFile.exists() && !destDatabaseFile.mkdirs()) {
throw new IOException("failed to create destination directory: " + path);
}
// close the database, so we have no open file handles that could cause
// trouble. Save current temp path, so we can copy and re-open the
// database
final Path currentPath = this.tempDatabasePath;
close();
try {
copyFolder(currentPath.toFile(), destDatabaseFile);
} finally {
open(currentPath);
}
}
public String getTempDirectoryName() {
if (databaseService == null || tempDatabasePath == null) {
return null;
}
return tempDatabasePath.toString();
}
public TempNeo4jInstance duplicate() throws IOException {
if (this.databaseService == null || this.tempDatabasePath == null) {
throw new IllegalStateException("No database loaded");
}
final Path currentPath = tempDatabasePath;
close();
try {
TempNeo4jInstance dup = new TempNeo4jInstance();
dup.load(currentPath);
return dup;
} finally {
open(currentPath);
}
}
public GraphDatabaseService getService() {
return databaseService;
}
public static void main(String... args) throws IOException {
String src = args[0];
String dst = args[1];
TempNeo4jInstance instance = new TempNeo4jInstance();
instance.load(src);
System.out.println("database '" + instance.getTempDirectoryName() + "' loaded (origin: '" + src + "')");
instance.save(dst);
System.out.println("database '" + dst + "' saved");
instance.save(dst + "2");
System.out.println("database '" + dst + "' saved");
}
}
......@@ -187,6 +187,9 @@ public class ExpertScreenController extends ConnectedControl {
"Applying selected Candidate Pattern");
updatePatternComboBox.setItems(pNew.getUpdatePatterns());
sequentialTextArea.setText("");
parallelizedTextArea.setText("");
transformButton.setDisable(true);
final QueryTask queryTask = new QueryTask(pNew);
......
......@@ -7,8 +7,7 @@
<![CDATA[
//just for debugging, find control flow starting at main: MATCH (n)-[cf:CONTROL_FLOW*]->() where n.fqn=~'.*main.*' return n, cf
MATCH p=(mc1:MethodCall)-[:CONTROL_FLOW]->(mc2:MethodCall)
where mc1.fqn=~'de\\.johl\\..*' AND
MATCH p=(mc1:MethodCall)-[:CONTROL_FLOW]->(mc2:MethodCall) WHERE
NOT EXISTS(mc1-[:AGGREGATED_CALLS|CALLS*]->()-[:AGGREGATED_FIELD_WRITE]->(:Field)<-[:AGGREGATED_FIELD_WRITE|AGGREGATED_FIELD_READ]-()<-[:AGGREGATED_CALLS|CALLS*]-(mc2)) AND
NOT EXISTS(mc2-[:AGGREGATED_CALLS|CALLS*]->()-[:AGGREGATED_FIELD_WRITE]->(:Field)<-[:AGGREGATED_FIELD_WRITE|AGGREGATED_FIELD_READ]-()<-[:AGGREGATED_CALLS|CALLS*]-(mc1))
MATCH (class:Class)-[:CONTAINS_METHOD]->(:Method)-[:CONTROL_FLOW*]->(mc1)
......
<?xml version="1.0" encoding="UTF-8"?>
<pattern>
<name>Parallel Methods</name>
<name>Parallel Methods (Value)</name>
<description>No return value, no arguments</description>
<cp>
<query>
......@@ -26,25 +26,25 @@ MATCH (mc1:MethodCall)-[:CALLS]->(:Method)<-[CONTAINS_METHOD]-(parentClass:Class
MATCH (class:Class)-[:CONTAINS_METHOD]->(:Method)-[:CONTROL_FLOW*]->(mc1)
//delete old control flow edges around method calls
MATCH (prev)-[in:CONTROL_FLOW]->(mc1)-[to:CONTROL_FLOW]->(mc2)-[out:CONTROL_FLOW]->(next) where ID(mc2)={mc2ID}
MATCH (mc2) where ID(mc2)={mc2ID}
MATCH (prev)-[in:CONTROL_FLOW]->(mc1)
MATCH (mc1)-[in2:CONTROL_FLOW]->(ma1)
MATCH (ma1)-[in3:CONTROL_FLOW]->(mc2)
MATCH (ma1)-[in4:DATA_FLOW]->(nextUsage)
MATCH (prevNextUsage)-[nextUsageCF:CONTROL_FLOW]->(nextUsage)
MATCH (nextUsage)-[:CONTROL_FLOW]->(nextNextUsage)
match (javaObjectConstructor:Constructor) where javaObjectConstructor.fqn='java.lang.Object.<init>()'
//The Java Runnable node does propably already exist.
MERGE (javaRunnableInterface:Class {
fqn : 'java.lang.Runnable',
MERGE (javaCallableInterface:Class {
fqn : 'java.util.concurrent.Callable',
origin : 'JAVA',
name : 'Runnable',
name : 'Callable',
type : 'Interface',
visibility: 'public'
})
//============================================================
// Declare Task Type
//============================================================
......@@ -59,7 +59,7 @@ CREATE (taskClass:Class {
})
CREATE (parentPackage)-[:CONTAINS_TYPE]->(taskClass)
CREATE (parentClass)-[:CONTAINS]->(taskClass)
CREATE (taskClass)-[:IMPLEMENTS]->(javaRunnableInterface)
CREATE (taskClass)-[:IMPLEMENTS]->(javaCallableInterface)
//==================== Constructor 1 ==========================
CREATE (ctorMethod:Method:Constructor {
......@@ -118,7 +118,7 @@ CREATE (ctor_2)-[:CONTROL_FLOW]->(ctor_3)
//WTF? why do we need this?
CREATE (ctorMethod2:Method:Constructor {
p0 : parentClass.fqn + '$%{Task}$0',
fqn : parentClass.fqn + '$%{Task}}.<init>(' + parentClass.fqn + '$%{Task$0)',
fqn : parentClass.fqn + '$%{Task__.<init>(' + parentClass.fqn + '$__Task}$0)',
visibility : 'public',
returntype : 'void',
isabstract : false,
......@@ -171,7 +171,7 @@ CREATE (ctor3:MethodCall:ConstructorCall {
})
CREATE (ctor2)-[:CONTROL_FLOW]->(ctor3)
CREATE (ctor2)-[:CALLS]->(ctor_2)
CREATE (ctor3)-[:CALLS]->(ctorMethod)
CREATE( ctor4:ReturnStmt {
......@@ -181,13 +181,13 @@ CREATE( ctor4:ReturnStmt {
CREATE (ctor3)-[:CONTROL_FLOW]->(ctor4)
//==================== Run Method ==========================
CREATE (taskRun:Method {
fqn : parentClass.fqn + '$%{Task}.run()',
name : 'run' ,
displayname : 'run()',
//==================== Call1 Method ==========================
CREATE (taskCall1:Method {
fqn : parentClass.fqn + '$%{Task}.call()',
name : 'call' ,
displayname : 'call()',
visibility : 'public',
returntype : 'void',
returntype : mc1.returntype,
isabstract : false,
isnative : false,
istatic : false,
......@@ -197,9 +197,9 @@ CREATE (taskRun:Method {
type : 'Method'
})
CREATE (taskClass)-[:CONTAINS_METHOD]->(taskRun)
CREATE (taskClass)-[:CONTAINS_METHOD]->(taskCall1)
CREATE (run1:Assignment {
CREATE (call1_1:Assignment {
vartype : parentClass.fqn + '$%{Task}',
var : 'this',
displayname : 'this = @this: ' + parentClass.fqn + '$%{Task}',
......@@ -208,68 +208,89 @@ CREATE (run1:Assignment {
operation : 'thisdeclaration'
})
CREATE (taskRun)-[:CONTROL_FLOW]->(run1)
CREATE (taskCall1)-[:CONTROL_FLOW]->(call1_1)
CREATE( run2:MethodCall {
CREATE( call1_2:Assignment:MethodCall {
args : [],
fqn : mc1.fqn,
caller : 'void',
caller : parentClass.fqn,
vartype : mc1.vartype,
argumentscount : 0,
var : mc1.var,
displayname : mc1.displayname,
returntype : 'void',
returntype : mc1.returntype,
name : mc1.name,
type : 'MethodCall'
type : 'Assignment',
operation : 'MethodCall',
rightValue : 'staticInvoke <' + parentClass.fqn + ': ' + mc1.returntype + ' ' + mc1.name + '()>()'
})
CREATE (run1)-[:CONTROL_FLOW]->(run2)
CREATE (call1_1)-[:CONTROL_FLOW]->(call1_2)
CREATE( run3:ReturnStmt {
CREATE( call1_3:ReturnStmt {
name : 'return',
type : 'ReturnStmt'
})
CREATE (run2)-[:CONTROL_FLOW]->(run3)
CREATE (call1_2)-[:CONTROL_FLOW]->(call1_3)
//============================================================
// Create Task Object
//============================================================
CREATE (taskTempAssign:Assignment {
operation : 'new',
var : 'temp$0',
//==================== Call2 Method ==========================
CREATE (taskCall2:Method {
fqn : parentClass.fqn + '$%{Task}.call()',
name : 'call' ,
displayname : 'call()',
visibility : 'public',
returntype : 'java.lang.Object',
isabstract : false,
isnative : false,
istatic : false,
isdeclared: true,
parameterscount : 0,
throws : 'java.lang.Exception',
type : 'Method'
})
CREATE (taskClass)-[:CONTAINS_METHOD]->(taskCall2)
CREATE (call2_1:Assignment {
vartype : parentClass.fqn + '$%{Task}',
var : 'this',
displayname : 'this = @this: ' + parentClass.fqn + '$%{Task}',
rightValue : '@this: ' + parentClass.fqn + '$%{Task}',
type : 'Assignment',
rightValue : 'new ' + parentClass.fqn + '$%{Task}',
displayname : 'temp$0 = new ' + parentClass.fqn + '$%{Task}'
operation : 'thisdeclaration'
})
CREATE (prev)-[:CONTROL_FLOW]->(taskTempAssign)
CREATE (taskCall2)-[:CONTROL_FLOW]->(call2_1)
CREATE( taskTempCtor:MethodCall:ConstructorCall {
fqn : parentClass.fqn + '$%{Task}}.<init>(' + parentClass.fqn + '$%{Task)',
caller : 'temp$0',
argumentscount : 1,
CREATE( call2_2:Assignment:MethodCall {
args : [],
name : '<init>',
type : 'MethodCall',
displayname : '<init>(null)',
returntype : 'void'
fqn : parentClass.fqn + '$%{Task}.call()',
caller : parentClass.fqn,
vartype : mc1.vartype,
argumentscount : 0,
var : 'temp$0',
displayname : 'temp$0 = call()',
returntype : mc1.returntype,
name : 'call',
type : 'Assignment',
operation : 'MethodCall',
rightValue : 'virtualinvoke this.<' + parentClass.fqn + ' ' + mc1.returntype + ' call()>()'
})
CREATE (taskTempAssign)-[:CONTROL_FLOW]->(taskTempCtor)
CREATE (taskTempCtor)-[:CALLS]->(ctorMethod2)
CREATE( taskVarAssign:Assignment {
vartype : parentClass.fqn + '$%{Task}',
var : 'TaskVar',
rightValue : 'temp$0',
type : 'Assignment',
operation : 'value',
isdeclaration: true,
displayname : 'TaskVar = temp$0'
CREATE (call2_1)-[:CONTROL_FLOW]->(call2_2)
CREATE (call2_2)-[:CALLS]->(taskCall1)
CREATE( call2_3:ReturnStmt {
name : 'return temp$0',
type : 'ReturnStmt',
rightValue : 'temp$0'
})
CREATE (taskTempCtor)-[:CONTROL_FLOW]->(taskVarAssign)
CREATE (call2_2)-[:CONTROL_FLOW]->(call2_3)
//============================================================
......@@ -285,7 +306,7 @@ CREATE (poolTempAssign:Assignment {
displayname : 'temp$1 = new java.util.concurrent.ForkJoinPool'
})
CREATE (taskVarAssign)-[:CONTROL_FLOW]->(poolTempAssign)
CREATE (prev)-[:CONTROL_FLOW]->(poolTempAssign)
CREATE( poolTempCtor:MethodCall:ConstructorCall {
fqn : 'java.util.concurrent.ForkJoinPool.<init>()',
......@@ -313,6 +334,48 @@ CREATE( poolVarAssign:Assignment {
CREATE (poolTempCtor)-[:CONTROL_FLOW]->(poolVarAssign)
//============================================================
// Create Task Object
//============================================================
CREATE (taskTempAssign:Assignment {
operation : 'new',
var : 'temp$0',
vartype : parentClass.fqn + '$%{Task}',
type : 'Assignment',
rightValue : 'new ' + parentClass.fqn + '$%{Task}',
displayname : 'temp$0 = new ' + parentClass.fqn + '$%{Task}'
})
CREATE (poolVarAssign)-[:CONTROL_FLOW]->(taskTempAssign)
CREATE( taskTempCtor:MethodCall:ConstructorCall {
fqn : parentClass.fqn + '$%{Task__.<init>(' + parentClass.fqn + '$__Task}',
caller : 'temp$0',
argumentscount : 1,
args: [],
name : '<init>',
type : 'MethodCall',
displayname : '<init>(null)',
returntype : 'void'
})
CREATE (taskTempAssign)-[:CONTROL_FLOW]->(taskTempCtor)
CREATE (taskTempCtor)-[:CALLS]->(ctorMethod2)
CREATE( taskVarAssign:Assignment {
vartype : parentClass.fqn + '$%{Task}',
var : '%{TaskVar}',
rightValue : 'temp$0',
type : 'Assignment',
operation : 'value',
isdeclaration: true,
displayname : '%{TaskVar} = temp$0'
})
CREATE (taskTempCtor)-[:CONTROL_FLOW]->(taskVarAssign)
//============================================================
// Submit task to pool
//============================================================
......@@ -322,17 +385,17 @@ CREATE( submitTemp:Assignment:MethodCall {
fqn : 'java.util.concurrent.ForkJoinPool.submit(java.lang.Runnable)',
operation : 'MethodCall',
var : 'temp$2',
args : [ 'TaskVar' ],
args : [ '%{TaskVar}' ],
name : 'submit',
vartype : 'java.util.concurrent.ForkJoinTask',
type : 'Assignment',
rightValue : 'virtualinvoke pool.<java.util.concurrent.ForkJoinPool: java.util.concurrent.ForkJoinTask submit(java.lang.Runnable)>(TaskVar)',
rightValue : 'virtualinvoke pool.<java.util.concurrent.ForkJoinPool: java.util.concurrent.ForkJoinTask submit(java.lang.Runnable)>(%{TaskVar})',
argumentscount : 1,
displayname : '%{PoolVar} = temp$1',
returntype : 'java.util.concurrent.ForkJoinTask'
})
CREATE (poolVarAssign)-[:CONTROL_FLOW]->(submitTemp)
CREATE (taskVarAssign)-[:CONTROL_FLOW]->(submitTemp)
CREATE( submitVar:Assignment {
operation : 'value',
......@@ -348,32 +411,56 @@ CREATE( submitVar:Assignment {
CREATE (submitTemp)-[:CONTROL_FLOW]->(submitVar)
//============================================================
// Call second function in this thread
//============================================================
CREATE (submitVar)-[:CONTROL_FLOW]->(mc2)
//============================================================
// Join submitted task
//============================================================
CREATE( join:MethodCall {
CREATE( join:MethodCall:Assignment {
caller : '%{SubmitVar}',
fqn : 'java.util.concurrent.ForkJoinTask.join()',
args : [],
name : 'join',
type : 'MethodCall',
argumentscount : 0,
displayname : 'join()',
returntype : 'java.lang.Object'
displayname : mc1.var + ' = join()',
returntype : 'java.lang.Object',
operation : 'MethodCall' ,
var : mc1.var,
vartype : 'java.lang.Object',
type : 'Assignment',
rightValue : 'virtualinvoke %{SubmitVar}.<java.util.concurrent.ForkJoinTask: java.lang.Object join()>()'
})
CREATE( joinCast:MethodCall:Assignment {
operation : 'cast',
var : 'temp$%{unique1}',
vartype : ma1.vartype,
type : 'Assignment',
rightValue : '(java.lang.Integer) ' + mc1.var,
displayname : ma1.var + ' = (java.lang.Integer)' + mc1.var
})
CREATE( joinAssign:Assignment {
operation : 'value',
var : ma1.var,
vartype : ma1.vartype,
type : 'Assignment',
rightValue : 'temp$%{unique1}',
displayname : ma1.var + ' = temp$%{unique1}',
isdeclaration : ma1.isdeclaration
})
CREATE (mc2)-[:CONTROL_FLOW]->(join)
CREATE (join)-[:CONTROL_FLOW]->(next)
CREATE (prevNextUsage)-[:CONTROL_FLOW]->(join)
CREATE (join)-[:CONTROL_FLOW]->(joinCast)
CREATE (joinCast)-[:CONTROL_FLOW]->(joinAssign)
CREATE (joinAssign)-[:CONTROL_FLOW]->(nextUsage)
DELETE in,to,out
delete nextUsageCF, in, in, in3, in4
return mc1 as display
]]>
......
//get parent class and parent package
MATCH (mc1:MethodCall)-[:CALLS]->(:Method)<-[CONTAINS_METHOD]-(parentClass:Class)<-[:CONTAINS_TYPE]-(parentPackage:Package) where ID(mc1)={mc1ID}
MATCH (mc1:MethodCall)-[:CALLS]->(:Method)<-[CONTAINS_METHOD]-(parentClass:Class)<-[:CONTAINS_TYPE]-(parentPackage:Package) where ID(mc1)=24
MATCH (class:Class)-[:CONTAINS_METHOD]->(:Method)-[:CONTROL_FLOW*]->(mc1)
//delete old control flow edges around method calls
MATCH (prev)-[in:CONTROL_FLOW]->(mc1)-[to:CONTROL_FLOW]->(mc2)-[out:CONTROL_FLOW]->(next) where ID(mc2)={mc2ID}
MATCH (mc2) where ID(mc2)=26
MATCH (prev)-[in:CONTROL_FLOW]->(mc1)
MATCH (mc1)-[in2:CONTROL_FLOW]->(ma1)
MATCH (ma1)-[in3:CONTROL_FLOW]->(mc2)
MATCH (ma1)-[in4:DATA_FLOW]->(nextUsage)
MATCH (prevNextUsage)-[nextUsageCF:CONTROL_FLOW]->(nextUsage)
MATCH (nextUsage)-[:CONTROL_FLOW]->(nextNextUsage)
match (javaObjectConstructor:Constructor) where javaObjectConstructor.fqn='java.lang.Object.<init>()'
......@@ -18,18 +22,14 @@ MERGE (javaCallableInterface:Class {
visibility: 'public'
})
//============================================================
// Declare Task Type
//============================================================
//==================== Task Class ============================
CREATE (taskClass:Class {
fqn : parentClass.fqn + '$%{Task}',
name : parentClass.name + '$%{Task}',
fqn : parentClass.fqn + '$__Task__',
name : parentClass.name + '$__Task__',
visibility: 'public',
origin: 'APP',
type: 'Class'
......@@ -40,7 +40,7 @@ CREATE (taskClass)-[:IMPLEMENTS]->(javaCallableInterface)
//==================== Constructor 1 ==========================
CREATE (ctorMethod:Method:Constructor {
fqn : parentClass.fqn + '$%{Task}.<init>()',
fqn : parentClass.fqn + '$__Task__.<init>()',
visibility : 'private',
returntype : 'void',
parameterscount : 0,
......@@ -58,11 +58,11 @@ CREATE (ctorMethod:Method:Constructor {
CREATE (taskClass)-[:CONTAINS_CONSTRUCTOR]->(ctorMethod)
CREATE (ctor_1:Assignment {
vartype : parentClass.fqn + '$%{Task}',
vartype : parentClass.fqn + '$__Task__',
var : 'this',
rightValue : '@this: ' + parentClass.fqn + '$%{Task}',
displayname : '@this: ' + parentClass.fqn + '$%{Task}',
name : 'this = @this: ' + parentClass.fqn + '$%{Task}',
rightValue : '@this: ' + parentClass.fqn + '$__Task__',
displayname : '@this: ' + parentClass.fqn + '$__Task__',
name : 'this = @this: ' + parentClass.fqn + '$__Task__',
type : 'Assignment',
operation : 'thisdeclaration'
})
......@@ -94,8 +94,8 @@ CREATE (ctor_2)-[:CONTROL_FLOW]->(ctor_3)
//==================== Constructor 2 ==========================
//WTF? why do we need this?
CREATE (ctorMethod2:Method:Constructor {
p0 : parentClass.fqn + '$%{Task}$0',
fqn : parentClass.fqn + '$%{Task}}.<init>(' + parentClass.fqn + '$%{Task$0)',
p0 : parentClass.fqn + '$__Task__$0',
fqn : parentClass.fqn + '$__Task__.<init>(' + parentClass.fqn + '$__Task__$0)',
visibility : 'public',
returntype : 'void',
isabstract : false,
......@@ -106,7 +106,7 @@ CREATE (ctorMethod2:Method:Constructor {
istatic : false,
isdeclared : true,
isfinal : false,
displayname : 'ctor(' + parentClass.fqn + '$%{Task}$0)',
displayname : 'ctor(' + parentClass.fqn + '$__Task__$0)',
name : 'ctor',
returntype: 'void'
})
......@@ -114,10 +114,10 @@ CREATE (ctorMethod2:Method:Constructor {
CREATE (taskClass)-[:CONTAINS_CONSTRUCTOR]->(ctorMethod2)
CREATE (ctor1:Assignment {
vartype : parentClass.fqn + '$%{Task}',
vartype : parentClass.fqn + '$__Task__',
var : 'this',
rightValue : '@this: ' + parentClass.fqn + '$%{Task}',
displayname : 'this = @this: ' + parentClass.fqn + '$%{Task}',
rightValue : '@this: ' + parentClass.fqn + '$__Task__',
displayname : 'this = @this: ' + parentClass.fqn + '$__Task__',
type : 'Assignment',
operation : 'thisdeclaration'
})
......@@ -125,11 +125,11 @@ CREATE (ctor1:Assignment {
CREATE (ctorMethod2)-[:CONTROL_FLOW]->(ctor1)
CREATE (ctor2:Assignment {
vartype : parentClass.fqn + '$%{Task}$0',
vartype : parentClass.fqn + '$__Task__$0',
var : 'p0',
displayname : 'p0 = @parameter0: ' + parentClass.fqn + '$%{Task}$0',
rightValue : '@parameter0: ' + parentClass.fqn + '$%{Task}$0',
name : 'p0 = @parameter0: ' + parentClass.fqn + '$%{Task}',
displayname : 'p0 = @parameter0: ' + parentClass.fqn + '$__Task__$0',
rightValue : '@parameter0: ' + parentClass.fqn + '$__Task__$0',
name : 'p0 = @parameter0: ' + parentClass.fqn + '$__Task__',
type : 'Assignment',
operation : 'parameterdeclaration'
})
......@@ -138,7 +138,7 @@ CREATE (ctor1)-[:CONTROL_FLOW]->(ctor2)
CREATE (ctor3:MethodCall:ConstructorCall {
args : [],
fqn : parentClass.fqn + '$%{Task}.<init>()',
fqn : parentClass.fqn + '$__Task__.<init>()',
caller : 'this',
argumentscount : 0,
displayname : '<init>()',
......@@ -148,7 +148,7 @@ CREATE (ctor3:MethodCall:ConstructorCall {
})
CREATE (ctor2)-[:CONTROL_FLOW]->(ctor3)
CREATE (ctor2)-[:CALLS]->(ctor_2)
CREATE (ctor3)-[:CALLS]->(ctorMethod)
CREATE( ctor4:ReturnStmt {
......@@ -160,7 +160,7 @@ CREATE (ctor3)-[:CONTROL_FLOW]->(ctor4)
//==================== Call1 Method ==========================
CREATE (taskCall1:Method {
fqn : parentClass.fqn + '$%{Task}.call()',
fqn : parentClass.fqn + '$__Task__.call()',
name : 'call' ,
displayname : 'call()',
visibility : 'public',
......@@ -177,10 +177,10 @@ CREATE (taskCall1:Method {
CREATE (taskClass)-[:CONTAINS_METHOD]->(taskCall1)
CREATE (call1_1:Assignment {
vartype : parentClass.fqn + '$%{Task}',
vartype : parentClass.fqn + '$__Task__',
var : 'this',
displayname : 'this = @this: ' + parentClass.fqn + '$%{Task}',
rightValue : '@this: ' + parentClass.fqn + '$%{Task}',
displayname : 'this = @this: ' + parentClass.fqn + '$__Task__',
rightValue : '@this: ' + parentClass.fqn + '$__Task__',
type : 'Assignment',
operation : 'thisdeclaration'
})
......@@ -199,7 +199,7 @@ CREATE( call1_2:Assignment:MethodCall {
name : mc1.name,
type : 'Assignment',
operation : 'MethodCall',
rightValue : 'staticInvoke <' + parentClass.fqn +
rightValue : 'staticInvoke <' + parentClass.fqn + ': ' + mc1.returntype + ' ' + mc1.name + '()>()'
})
CREATE (call1_1)-[:CONTROL_FLOW]->(call1_2)
......@@ -214,7 +214,7 @@ CREATE (call1_2)-[:CONTROL_FLOW]->(call1_3)
//==================== Call2 Method ==========================
CREATE (taskCall2:Method {
fqn : parentClass.fqn + '$%{Task}.call()',
fqn : parentClass.fqn + '$__Task__.call()',
name : 'call' ,
displayname : 'call()',
visibility : 'public',
......@@ -231,10 +231,10 @@ CREATE (taskCall2:Method {
CREATE (taskClass)-[:CONTAINS_METHOD]->(taskCall2)
CREATE (call2_1:Assignment {
vartype : parentClass.fqn + '$%{Task}',
vartype : parentClass.fqn + '$__Task__',
var : 'this',
displayname : 'this = @this: ' + parentClass.fqn + '$%{Task}',
rightValue : '@this: ' + parentClass.fqn + '$%{Task}',
displayname : 'this = @this: ' + parentClass.fqn + '$__Task__',
rightValue : '@this: ' + parentClass.fqn + '$__Task__',
type : 'Assignment',
operation : 'thisdeclaration'
})
......@@ -243,7 +243,7 @@ CREATE (taskCall2)-[:CONTROL_FLOW]->(call2_1)
CREATE( call2_2:Assignment:MethodCall {
args : [],
fqn : parentClass.fqn + '$%{Task}.call()',
fqn : parentClass.fqn + '$__Task__.call()',
caller : parentClass.fqn,
vartype : mc1.vartype,
argumentscount : 0,
......@@ -258,7 +258,7 @@ CREATE( call2_2:Assignment:MethodCall {
CREATE (call2_1)-[:CONTROL_FLOW]->(call2_2)
CREATE (call2_1)-[:CALLS]->(taskCall1)
CREATE (call2_2)-[:CALLS]->(taskCall1)
CREATE( call2_3:ReturnStmt {
name : 'return temp$0',
......@@ -267,3 +267,174 @@ CREATE( call2_3:ReturnStmt {
})
CREATE (call2_2)-[:CONTROL_FLOW]->(call2_3)
//============================================================
// Create Pool Object
//============================================================
CREATE (poolTempAssign:Assignment {
operation : 'new',
var : 'temp$1',
vartype : 'java.util.concurrent.ForkJoinPool',
type : 'Assignment',
rightValue : 'new java.util.concurrent.ForkJoinPool',
displayname : 'temp$1 = new java.util.concurrent.ForkJoinPool'
})
CREATE (prev)-[:CONTROL_FLOW]->(poolTempAssign)
CREATE( poolTempCtor:MethodCall:ConstructorCall {
fqn : 'java.util.concurrent.ForkJoinPool.<init>()',
caller : 'temp$1',
args: [],
argumentscount : 0,
name : '<init>',
type : 'MethodCall',
displayname : '<init>()',
returntype : 'void'
})
CREATE (poolTempAssign)-[:CONTROL_FLOW]->(poolTempCtor)
CREATE( poolVarAssign:Assignment {
vartype : 'java.util.concurrent.ForkJoinPool',
var : '__PoolVar__',
rightValue : 'temp$1',
type : 'Assignment',
operation : 'value',
isdeclaration: true,
displayname : '__PoolVar__ = temp$1'
})
CREATE (poolTempCtor)-[:CONTROL_FLOW]->(poolVarAssign)
//============================================================
// Create Task Object
//============================================================
CREATE (taskTempAssign:Assignment {
operation : 'new',
var : 'temp$0',
vartype : parentClass.fqn + '$__Task__',
type : 'Assignment',
rightValue : 'new ' + parentClass.fqn + '$__Task__',
displayname : 'temp$0 = new ' + parentClass.fqn + '$__Task__'
})
CREATE (poolVarAssign)-[:CONTROL_FLOW]->(taskTempAssign)
CREATE( taskTempCtor:MethodCall:ConstructorCall {
fqn : parentClass.fqn + '$__Task__.<init>(' + parentClass.fqn + '$__Task__',
caller : 'temp$0',
argumentscount : 1,
args: [],
name : '<init>',
type : 'MethodCall',
displayname : '<init>(null)',
returntype : 'void'
})
CREATE (taskTempAssign)-[:CONTROL_FLOW]->(taskTempCtor)
CREATE (taskTempCtor)-[:CALLS]->(ctorMethod2)
CREATE( taskVarAssign:Assignment {
vartype : parentClass.fqn + '$__Task__',
var : '__TaskVar__',
rightValue : 'temp$0',
type : 'Assignment',
operation : 'value',
isdeclaration: true,
displayname : '__TaskVar__ = temp$0'
})
CREATE (taskTempCtor)-[:CONTROL_FLOW]->(taskVarAssign)
//============================================================
// Submit task to pool
//============================================================
CREATE( submitTemp:Assignment:MethodCall {
caller : '__PoolVar__',
fqn : 'java.util.concurrent.ForkJoinPool.submit(java.lang.Runnable)',
operation : 'MethodCall',
var : 'temp$2',
args : [ '__TaskVar__' ],
name : 'submit',
vartype : 'java.util.concurrent.ForkJoinTask',
type : 'Assignment',
rightValue : 'virtualinvoke pool.<java.util.concurrent.ForkJoinPool: java.util.concurrent.ForkJoinTask submit(java.lang.Runnable)>(__TaskVar__)',
argumentscount : 1,
displayname : '__PoolVar__ = temp$1',
returntype : 'java.util.concurrent.ForkJoinTask'
})
CREATE (taskVarAssign)-[:CONTROL_FLOW]->(submitTemp)
CREATE( submitVar:Assignment {
operation : 'value',
var : '__SubmitVar__',
vartype: 'java.util.concurrent.ForkJoinTask',
isdeclaration : true,
type : 'Assignment',
rightValue: 'temp$2',
lefttypearguments: [ '?' ],
displayname : '__SubmitVar__ = temp$2'
})
CREATE (submitTemp)-[:CONTROL_FLOW]->(submitVar)
CREATE (submitVar)-[:CONTROL_FLOW]->(mc2)
//============================================================
// Join submitted task
//============================================================
CREATE( join:MethodCall:Assignment {
caller : '__SubmitVar__',
fqn : 'java.util.concurrent.ForkJoinTask.join()',
args : [],
name : 'join',
type : 'MethodCall',
argumentscount : 0,
displayname : mc1.var + ' = join()',
returntype : 'java.lang.Object',
operation : 'MethodCall' ,
var : mc1.var,
vartype : 'java.lang.Object',
type : 'Assignment',
rightValue : 'virtualinvoke __SubmitVar__.<java.util.concurrent.ForkJoinTask: java.lang.Object join()>()'
})
CREATE( joinCast:MethodCall:Assignment {
operation : 'cast',
var : 'temp$__unique1__',
vartype : ma1.vartype,
type : 'Assignment',
rightValue : '(java.lang.Integer) ' + mc1.var,
displayname : ma1.var + ' = (java.lang.Integer)' + mc1.var
})
CREATE( joinAssign:Assignment {
operation : 'value',
var : ma1.var,
vartype : ma1.vartype,
type : 'Assignment',
rightValue : 'temp$__unique1__',
displayname : ma1.var + ' = temp$__unique1__',
isdeclaration : ma1.isdeclaration
})
CREATE (prevNextUsage)-[:CONTROL_FLOW]->(join)
CREATE (join)-[:CONTROL_FLOW]->(joinCast)
CREATE (joinCast)-[:CONTROL_FLOW]->(joinAssign)
CREATE (joinAssign)-[:CONTROL_FLOW]->(nextUsage)
delete nextUsageCF, in, in, in3, in4
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment