diff --git a/.gitignore b/.gitignore
index d627c53c44b41750991e76b0b5c0a6300840fa36..ac48bd7604e2575a2691a9ffde715b5b1b4667c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,176 @@
+# Created by https://www.gitignore.io/api/java,linux,macos,maven,intellij
+# Edit at https://www.gitignore.io/?templates=java,linux,macos,maven,intellij
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+.idea
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+.idea/modules.xml
+.idea/*.iml
+.idea/modules
*.iml
-.idea/
-target/
+*.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
out/
-.settings
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator/
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Maven ###
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+.flattened-pom.xml
+
+# End of https://www.gitignore.io/api/java,linux,macos,maven,intellij
.attach*
diff --git a/.gitmodules b/.gitmodules
index 46394f31083b0e1b8c7e764a168cf31eca891e60..ee5ecc4b02d0fb2fde48ac80e034d213d2fe97c9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "src/test/res/java-slicing-benchmarks"]
- path = src/test/res/java-slicing-benchmarks
- url = kaz:repos/java-slicing-benchmarks.git
+[submodule "sdg-core/src/test/res/java-slicing-benchmarks"]
+ path = sdg-core/src/test/res/java-slicing-benchmarks
+ url = https://kaz.dsic.upv.es/git/program-slicing/java-benchmarks.git
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..2f4b56835b31b2d541d1edbb0aee718d72852d0e
--- /dev/null
+++ b/META-INF/MANIFEST.MF
@@ -0,0 +1 @@
+Manifest-Version: 1.0
diff --git a/pom.xml b/pom.xml
index 44ab23ebfbcf34e8a6194830a1a9285f0ec4a27d..ebed3bf8b38659dec4eb6d51d2c217077142e64d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,50 +7,14 @@
tfm
tfm
1.0-SNAPSHOT
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
- 8
-
-
-
-
-
-
- com.github.javaparser
- javaparser-symbol-solver-core
- 3.9.1
-
+
+ 11
+ 11
+
-
- org.jetbrains
- annotations-java5
- RELEASE
- compile
-
-
-
- org.jgrapht
- jgrapht-core
- 1.3.0
-
-
-
- org.jgrapht
- jgrapht-io
- 1.3.0
-
-
-
- org.junit.jupiter
- junit-jupiter
- RELEASE
- test
-
-
-
\ No newline at end of file
+
+ sdg-core
+ sdg-cli
+
+
diff --git a/sdg-cli/pom.xml b/sdg-cli/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..09842784ad5ed95b0c83a4ca5d0b39f06f7bc49a
--- /dev/null
+++ b/sdg-cli/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ tfm
+ sdg-cli
+ 1.0-SNAPSHOT
+
+
+ 11
+ 11
+
+
+
+
+ commons-cli
+ commons-cli
+ 1.4
+
+
+ com.github.javaparser
+ javaparser-core
+ 3.9.1
+
+
+ tfm
+ sdg-core
+ 1.0-SNAPSHOT
+ compile
+
+
+
diff --git a/src/main/java/tfm/exec/CFGLog.java b/sdg-cli/src/main/java/tfm/cli/CFGLog.java
similarity index 90%
rename from src/main/java/tfm/exec/CFGLog.java
rename to sdg-cli/src/main/java/tfm/cli/CFGLog.java
index 396953513ab30e0b159c91827699ac9bcda04345..af8cf106ce08c098e7832e757db369335c8c25c1 100644
--- a/src/main/java/tfm/exec/CFGLog.java
+++ b/sdg-cli/src/main/java/tfm/cli/CFGLog.java
@@ -1,4 +1,4 @@
-package tfm.exec;
+package tfm.cli;
import tfm.graphs.cfg.CFG;
diff --git a/src/main/java/tfm/exec/GraphLog.java b/sdg-cli/src/main/java/tfm/cli/GraphLog.java
similarity index 99%
rename from src/main/java/tfm/exec/GraphLog.java
rename to sdg-cli/src/main/java/tfm/cli/GraphLog.java
index 0fc1fe2851c2101872fe19290919456190c286ea..baaa4c84415528067dfb4dfaea5a1616dd36a1f9 100644
--- a/src/main/java/tfm/exec/GraphLog.java
+++ b/sdg-cli/src/main/java/tfm/cli/GraphLog.java
@@ -1,4 +1,4 @@
-package tfm.exec;
+package tfm.cli;
import tfm.graphs.Graph;
import tfm.utils.FileUtil;
diff --git a/src/main/java/tfm/exec/PDGLog.java b/sdg-cli/src/main/java/tfm/cli/PDGLog.java
similarity index 98%
rename from src/main/java/tfm/exec/PDGLog.java
rename to sdg-cli/src/main/java/tfm/cli/PDGLog.java
index af36803c54f5cf8db6137d44411f37f351ef6278..a50a51ca7d0ef9f24d604de32a9b06ecf951b77c 100644
--- a/src/main/java/tfm/exec/PDGLog.java
+++ b/sdg-cli/src/main/java/tfm/cli/PDGLog.java
@@ -1,4 +1,4 @@
-package tfm.exec;
+package tfm.cli;
import tfm.graphs.pdg.PDG;
import tfm.nodes.GraphNode;
diff --git a/src/main/java/tfm/exec/SDGLog.java b/sdg-cli/src/main/java/tfm/cli/SDGLog.java
similarity index 90%
rename from src/main/java/tfm/exec/SDGLog.java
rename to sdg-cli/src/main/java/tfm/cli/SDGLog.java
index cdeae275973139a049d4ddd741318af161a46e24..6c8e3e9fc6ce0beab0858cfc16f232eca7ec3f98 100644
--- a/src/main/java/tfm/exec/SDGLog.java
+++ b/sdg-cli/src/main/java/tfm/cli/SDGLog.java
@@ -1,4 +1,4 @@
-package tfm.exec;
+package tfm.cli;
import tfm.graphs.sdg.SDG;
diff --git a/sdg-cli/src/main/java/tfm/cli/Slicer.java b/sdg-cli/src/main/java/tfm/cli/Slicer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6c46c9a1a30fc42bd801be041cf412d7e6bb071
--- /dev/null
+++ b/sdg-cli/src/main/java/tfm/cli/Slicer.java
@@ -0,0 +1,258 @@
+package tfm.cli;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.symbolsolver.JavaSymbolSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.apache.commons.cli.*;
+import tfm.graphs.sdg.SDG;
+import tfm.slicing.FileLineSlicingCriterion;
+import tfm.slicing.Slice;
+import tfm.slicing.SlicingCriterion;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Slicer {
+ protected static final Pattern SC_PATTERN;
+ protected static final File DEFAULT_OUTPUT_DIR = new File("./slice/");
+ protected static final Options OPTIONS = new Options();
+
+ static {
+ String fileRe = "(?[^#]+\\.java)";
+ String lineRe = "(?[1-9]\\d*)";
+ String varsRe = "(?[a-zA-Z_]\\w*(?:,[a-zA-Z_]\\w*)*)";
+ String numsRe = "(?[1-9]\\d*(?:,[1-9]\\d*)*)";
+ SC_PATTERN = Pattern.compile(fileRe + "#" + lineRe + "(?::" + varsRe + "(?:!" + numsRe + ")?)?");
+ }
+
+ static {
+ OptionGroup criterionOptionGroup = new OptionGroup();
+ criterionOptionGroup.addOption(Option
+ .builder("f").longOpt("file")
+ .hasArg().argName("CriterionFile.java").type(File.class)
+ .desc("The file that contains the slicing criterion.")
+ .build());
+ criterionOptionGroup.addOption(Option
+ .builder("l").longOpt("line")
+ .hasArg().argName("lineNumber").type(Integer.class)
+ .desc("The line that contains the statement of the slicing criterion.")
+ .build());
+ criterionOptionGroup.addOption(Option
+ .builder("v").longOpt("var")
+ .hasArgs().argName("variableName").valueSeparator(',')
+ .desc("The name of the variable of the slicing criterion. Not setting this option is" +
+ " equivalent to selecting an empty set; setting multiple variables is allowed," +
+ " separated by commas")
+ .build());
+ criterionOptionGroup.addOption(Option
+ .builder("n").longOpt("number")
+ .hasArgs().argName("occurrenceNumber").valueSeparator(',')
+ .desc("The occurrence number of the variable(s) selected. If this argument is not set, it will" +
+ " default to the first appearance of each variable. If the occurrence number must be set" +
+ " for every variable in the same order.")
+ .build());
+ OPTIONS.addOptionGroup(criterionOptionGroup);
+ OPTIONS.addOption(Option
+ .builder("c").longOpt("criterion")
+ .hasArg().argName("file#line[:var[!occurrence]]")
+ .desc("The slicing criterion, in the format \"file#line:var\". Optionally, the occurrence can be" +
+ " appended as \"!occurrence\". This option replaces \"-f\", \"-l\", \"-v\" and \"-n\", and" +
+ " functions in a similar way: the variable and occurrence may be skipped or declared multiple times.")
+ .build());
+ OPTIONS.addOption(Option
+ .builder("i").longOpt("include")
+ .hasArgs().argName("directory[,directory,...]").valueSeparator(',')
+ .desc("Includes the directories listed in the search for methods called from the slicing criterion " +
+ "(directly or transitively). Methods that are not included here or part of the JRE, including" +
+ " third party libraries will not be analyzed, resulting in less precise slicing.")
+ .build());
+ OPTIONS.addOption(Option
+ .builder("o").longOpt("output")
+ .hasArg().argName("outputDir")
+ .desc("The directory where the sliced source code should be placed. By default, it is placed at " +
+ DEFAULT_OUTPUT_DIR)
+ .build());
+ OPTIONS.addOption(Option
+ .builder("h").longOpt("help")
+ .desc("Shows this text")
+ .build());
+ }
+
+ private final Set dirIncludeSet = new HashSet<>();
+ private File outputDir = DEFAULT_OUTPUT_DIR;
+ private File scFile;
+ private int scLine;
+ private final List scVars = new ArrayList<>();
+ private final List scVarOccurrences = new ArrayList<>();
+
+ public Slicer(String... cliArgs) throws ParseException {
+ CommandLine cl = new DefaultParser().parse(OPTIONS, cliArgs);
+ if (cl.hasOption('h'))
+ throw new ParseException(OPTIONS.toString());
+ if (cl.hasOption('c')) {
+ Matcher matcher = SC_PATTERN.matcher(cl.getOptionValue("criterion"));
+ if (!matcher.matches())
+ throw new ParseException("Invalid format for slicing criterion, see --help for more details");
+ setScFile(matcher.group("file"));
+ setScLine(Integer.parseInt(matcher.group("line")));
+ String vars = matcher.group("vars");
+ String nums = matcher.group("nums");
+ if (vars != null) {
+ if (nums != null)
+ setScVars(vars.split(","), nums.split(","));
+ else
+ setScVars(vars.split(","));
+ }
+ } else if (cl.hasOption('f') && cl.hasOption('l')) {
+ setScFile(cl.getOptionValue('f'));
+ setScLine((Integer) cl.getParsedOptionValue("l"));
+ if (cl.hasOption('v')) {
+ if (cl.hasOption('n'))
+ setScVars(cl.getOptionValues('v'), cl.getOptionValues('n'));
+ else
+ setScVars(cl.getOptionValues('v'));
+ }
+ } else {
+ throw new ParseException("Slicing criterion not specified: either use \"-c\" or \"-f\" and \"l\".");
+ }
+
+ if (cl.hasOption('o'))
+ outputDir = (File) cl.getParsedOptionValue("o");
+
+ if (cl.hasOption('i')) {
+ for (String str : cl.getOptionValues('i')) {
+ File dir = new File(str);
+ if (!dir.isDirectory())
+ throw new ParseException("One of the include directories is not a directory or isn't accesible: " + str);
+ dirIncludeSet.add(dir);
+ }
+ }
+ }
+
+ private void setScFile(String fileName) throws ParseException {
+ File file = new File(fileName);
+ if (!(file.exists() && file.isFile()))
+ throw new ParseException("Slicing criterion file is not an existing file.");
+ scFile = file;
+ }
+
+ private void setScLine(int line) throws ParseException {
+ if (line <= 0)
+ throw new ParseException("The line of the slicing criterion must be strictly greater than zero.");
+ scLine = line;
+ }
+
+ private void setScVars(String[] scVars) throws ParseException {
+ String[] array = new String[scVars.length];
+ Arrays.fill(array, "1");
+ setScVars(scVars, array);
+ }
+
+ private void setScVars(String[] scVars, String[] scOccurrences) throws ParseException {
+ if (scVars.length != scOccurrences.length)
+ throw new ParseException("If the number of occurrence is specified, it must be specified once per variable.");
+ try {
+ for (int i = 0; i < scVars.length; i++) {
+ this.scVars.add(scVars[i]);
+ int n = Integer.parseUnsignedInt(scOccurrences[i]);
+ if (n <= 0)
+ throw new ParseException("The number of occurrence must be larger than 0.");
+ this.scVarOccurrences.add(n);
+ }
+ } catch (NumberFormatException e) {
+ throw new ParseException(e.getMessage());
+ }
+ }
+
+ public Set getDirIncludeSet() {
+ return Collections.unmodifiableSet(dirIncludeSet);
+ }
+
+ public File getOutputDir() {
+ return outputDir;
+ }
+
+ public File getScFile() {
+ return scFile;
+ }
+
+ public int getScLine() {
+ return scLine;
+ }
+
+ public List getScVars() {
+ return Collections.unmodifiableList(scVars);
+ }
+
+ public List getScVarOccurrences() {
+ return Collections.unmodifiableList(scVarOccurrences);
+ }
+
+ public void slice() throws ParseException {
+ // Configure JavaParser
+ CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+ combinedTypeSolver.add(new ReflectionTypeSolver(true));
+ for (File directory : dirIncludeSet)
+ combinedTypeSolver.add(new JavaParserTypeSolver(directory));
+ JavaParser.getStaticConfiguration().setSymbolResolver(new JavaSymbolSolver(combinedTypeSolver));
+ JavaParser.getStaticConfiguration().setAttributeComments(false);
+
+ // Build the SDG
+ NodeList units = new NodeList<>();
+ try {
+ for (File directory : dirIncludeSet)
+ units.add(JavaParser.parse(directory));
+ CompilationUnit scUnit = JavaParser.parse(scFile);
+ if (!units.contains(scUnit))
+ units.add(scUnit);
+ } catch (FileNotFoundException e) {
+ throw new ParseException(e.getMessage());
+ }
+ SDG sdg = new SDG();
+ sdg.build(units);
+
+ // Slice the SDG
+ SlicingCriterion sc = new FileLineSlicingCriterion(scFile, scLine);
+ Slice slice = sdg.slice(sc);
+
+ // Convert the slice to code and output the result to `outputDir`
+ for (CompilationUnit cu : slice.toAst()) {
+ if (cu.getStorage().isEmpty())
+ throw new IllegalStateException("A synthetic CompilationUnit was discovered, with no file associated to it.");
+ String packagePath = cu.getPackageDeclaration().map(NodeWithName::getNameAsString).orElse("").replace(".", "/");
+ File packageDir = new File(outputDir, packagePath);
+ packageDir.mkdirs();
+ File javaFile = new File(packageDir, cu.getStorage().get().getFileName());
+ try (PrintWriter pw = new PrintWriter(javaFile)) {
+ pw.print(new BlockComment(getDisclaimer(cu.getStorage().get())));
+ pw.print(cu);
+ } catch (FileNotFoundException e) {
+ System.err.println("Could not write file " + javaFile);
+ }
+ }
+ }
+
+ protected String getDisclaimer(CompilationUnit.Storage s) {
+ return String.format("\n\tThis file was automatically generated as part of a slice with criterion" +
+ "\n\tfile: %s, line: %d, variable(s): %s\n\tOriginal file: %s\n",
+ scFile, scLine, String.join(", ", scVars), s.getPath());
+ }
+
+ public static void main(String... args) {
+ try {
+ new Slicer(args).slice();
+ } catch (ParseException e) {
+ System.err.println("Error parsing the arguments!\n" + e.getMessage());
+ }
+ }
+}
diff --git a/cfg/Eval_1_main.ff3 b/sdg-core/cfg/Eval_1_main.ff3
similarity index 100%
rename from cfg/Eval_1_main.ff3
rename to sdg-core/cfg/Eval_1_main.ff3
diff --git a/sdg-core/pom.xml b/sdg-core/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..88d56ba6630f6db693fb2fe869b28477da5ec9bc
--- /dev/null
+++ b/sdg-core/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+
+ tfm
+ sdg-core
+ 1.0-SNAPSHOT
+
+
+ 11
+ 11
+
+
+
+
+ com.github.javaparser
+ javaparser-symbol-solver-core
+ 3.9.1
+
+
+
+ org.jetbrains
+ annotations-java5
+ RELEASE
+ compile
+
+
+
+ org.jgrapht
+ jgrapht-core
+ 1.3.0
+
+
+
+ org.jgrapht
+ jgrapht-io
+ 1.3.0
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ RELEASE
+ test
+
+
+
diff --git a/src/main/java/tfm/arcs/Arc.java b/sdg-core/src/main/java/tfm/arcs/Arc.java
similarity index 96%
rename from src/main/java/tfm/arcs/Arc.java
rename to sdg-core/src/main/java/tfm/arcs/Arc.java
index ef0ffd55e98bc6b6301fa8dde9726c8fbd9eca5f..e9ecd300639910508c20d6e3cb6ea8d61e87e23b 100644
--- a/src/main/java/tfm/arcs/Arc.java
+++ b/sdg-core/src/main/java/tfm/arcs/Arc.java
@@ -64,6 +64,14 @@ public abstract class Arc extends DefaultEdge {
throw new UnsupportedOperationException("Not a DataDependencyArc");
}
+ public boolean isInterproceduralInputArc() {
+ return false;
+ }
+
+ public boolean isInterproceduralOutputArc() {
+ return false;
+ }
+
/** @see CallArc */
public final boolean isCallArc() {
return this instanceof CallArc;
diff --git a/src/main/java/tfm/arcs/cfg/ControlFlowArc.java b/sdg-core/src/main/java/tfm/arcs/cfg/ControlFlowArc.java
similarity index 100%
rename from src/main/java/tfm/arcs/cfg/ControlFlowArc.java
rename to sdg-core/src/main/java/tfm/arcs/cfg/ControlFlowArc.java
diff --git a/src/main/java/tfm/arcs/pdg/ControlDependencyArc.java b/sdg-core/src/main/java/tfm/arcs/pdg/ControlDependencyArc.java
similarity index 100%
rename from src/main/java/tfm/arcs/pdg/ControlDependencyArc.java
rename to sdg-core/src/main/java/tfm/arcs/pdg/ControlDependencyArc.java
diff --git a/src/main/java/tfm/arcs/pdg/DataDependencyArc.java b/sdg-core/src/main/java/tfm/arcs/pdg/DataDependencyArc.java
similarity index 100%
rename from src/main/java/tfm/arcs/pdg/DataDependencyArc.java
rename to sdg-core/src/main/java/tfm/arcs/pdg/DataDependencyArc.java
diff --git a/src/main/java/tfm/arcs/sdg/CallArc.java b/sdg-core/src/main/java/tfm/arcs/sdg/CallArc.java
similarity index 59%
rename from src/main/java/tfm/arcs/sdg/CallArc.java
rename to sdg-core/src/main/java/tfm/arcs/sdg/CallArc.java
index 43c41382a6f644d6eae191c281ab5cdacc920856..a6af4b579dc0ccf1a44f4e7dc421cf05e3efaefb 100644
--- a/src/main/java/tfm/arcs/sdg/CallArc.java
+++ b/sdg-core/src/main/java/tfm/arcs/sdg/CallArc.java
@@ -2,15 +2,24 @@ package tfm.arcs.sdg;
import org.jgrapht.io.Attribute;
import org.jgrapht.io.DefaultAttribute;
-import tfm.arcs.Arc;
import java.util.Map;
-public class CallArc extends Arc {
+public class CallArc extends InterproceduralArc {
@Override
public Map getDotAttributes() {
Map map = super.getDotAttributes();
map.put("style", DefaultAttribute.createAttribute("dashed"));
return map;
}
+
+ @Override
+ public boolean isInterproceduralInputArc() {
+ return true;
+ }
+
+ @Override
+ public boolean isInterproceduralOutputArc() {
+ return false;
+ }
}
diff --git a/sdg-core/src/main/java/tfm/arcs/sdg/InterproceduralArc.java b/sdg-core/src/main/java/tfm/arcs/sdg/InterproceduralArc.java
new file mode 100644
index 0000000000000000000000000000000000000000..13c74714bd81bc7f0fc03551eb5210e71bc0f7fc
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/arcs/sdg/InterproceduralArc.java
@@ -0,0 +1,15 @@
+package tfm.arcs.sdg;
+
+import tfm.arcs.Arc;
+
+public abstract class InterproceduralArc extends Arc {
+ protected InterproceduralArc() {
+ super();
+ }
+
+ @Override
+ public abstract boolean isInterproceduralInputArc();
+
+ @Override
+ public abstract boolean isInterproceduralOutputArc();
+}
diff --git a/sdg-core/src/main/java/tfm/arcs/sdg/ParameterInOutArc.java b/sdg-core/src/main/java/tfm/arcs/sdg/ParameterInOutArc.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f377d7537ca22d66f7030f6d42efebfe90ed860
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/arcs/sdg/ParameterInOutArc.java
@@ -0,0 +1,29 @@
+package tfm.arcs.sdg;
+
+import org.jgrapht.io.Attribute;
+import org.jgrapht.io.DefaultAttribute;
+import tfm.nodes.GraphNode;
+import tfm.nodes.type.NodeType;
+
+import java.util.Map;
+
+public class ParameterInOutArc extends InterproceduralArc {
+ @Override
+ public Map getDotAttributes() {
+ Map map = super.getDotAttributes();
+ map.put("style", DefaultAttribute.createAttribute("dashed"));
+ return map;
+ }
+
+ @Override
+ public boolean isInterproceduralInputArc() {
+ return ((GraphNode>) getSource()).getNodeType() == NodeType.ACTUAL_IN &&
+ ((GraphNode>) getTarget()).getNodeType() == NodeType.FORMAL_IN;
+ }
+
+ @Override
+ public boolean isInterproceduralOutputArc() {
+ return ((GraphNode>) getSource()).getNodeType() == NodeType.FORMAL_OUT &&
+ ((GraphNode>) getTarget()).getNodeType() == NodeType.ACTUAL_OUT;
+ }
+}
diff --git a/src/main/java/tfm/arcs/sdg/SummaryArc.java b/sdg-core/src/main/java/tfm/arcs/sdg/SummaryArc.java
similarity index 68%
rename from src/main/java/tfm/arcs/sdg/SummaryArc.java
rename to sdg-core/src/main/java/tfm/arcs/sdg/SummaryArc.java
index bde9724c0026bc919cfbe4c317618bf93db644af..1eb583dfa2ddb9acfd028573d3a631cefd2bd66f 100644
--- a/src/main/java/tfm/arcs/sdg/SummaryArc.java
+++ b/sdg-core/src/main/java/tfm/arcs/sdg/SummaryArc.java
@@ -13,4 +13,14 @@ public class SummaryArc extends Arc {
map.put("style", DefaultAttribute.createAttribute("bold"));
return map;
}
+
+ @Override
+ public boolean isInterproceduralInputArc() {
+ return false;
+ }
+
+ @Override
+ public boolean isInterproceduralOutputArc() {
+ return false;
+ }
}
diff --git a/src/main/java/tfm/graphs/Buildable.java b/sdg-core/src/main/java/tfm/graphs/Buildable.java
similarity index 100%
rename from src/main/java/tfm/graphs/Buildable.java
rename to sdg-core/src/main/java/tfm/graphs/Buildable.java
diff --git a/src/main/java/tfm/graphs/Graph.java b/sdg-core/src/main/java/tfm/graphs/Graph.java
similarity index 97%
rename from src/main/java/tfm/graphs/Graph.java
rename to sdg-core/src/main/java/tfm/graphs/Graph.java
index 9326553a2022f1fad16a9a1c53d8dc0209e8feff..bb0fab6aa0e13f29f882138d5900e16f3e66ee4b 100644
--- a/src/main/java/tfm/graphs/Graph.java
+++ b/sdg-core/src/main/java/tfm/graphs/Graph.java
@@ -9,7 +9,8 @@ import tfm.nodes.GraphNode;
import tfm.nodes.NodeFactory;
import tfm.utils.ASTUtils;
-import java.util.*;
+import java.util.Objects;
+import java.util.Optional;
import java.util.stream.Collectors;
/**
diff --git a/src/main/java/tfm/graphs/GraphWithRootNode.java b/sdg-core/src/main/java/tfm/graphs/GraphWithRootNode.java
similarity index 100%
rename from src/main/java/tfm/graphs/GraphWithRootNode.java
rename to sdg-core/src/main/java/tfm/graphs/GraphWithRootNode.java
diff --git a/src/main/java/tfm/graphs/Sliceable.java b/sdg-core/src/main/java/tfm/graphs/Sliceable.java
similarity index 100%
rename from src/main/java/tfm/graphs/Sliceable.java
rename to sdg-core/src/main/java/tfm/graphs/Sliceable.java
diff --git a/src/main/java/tfm/graphs/augmented/ACFG.java b/sdg-core/src/main/java/tfm/graphs/augmented/ACFG.java
similarity index 100%
rename from src/main/java/tfm/graphs/augmented/ACFG.java
rename to sdg-core/src/main/java/tfm/graphs/augmented/ACFG.java
diff --git a/src/main/java/tfm/graphs/augmented/ACFGBuilder.java b/sdg-core/src/main/java/tfm/graphs/augmented/ACFGBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/augmented/ACFGBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/augmented/ACFGBuilder.java
diff --git a/src/main/java/tfm/graphs/augmented/APDG.java b/sdg-core/src/main/java/tfm/graphs/augmented/APDG.java
similarity index 100%
rename from src/main/java/tfm/graphs/augmented/APDG.java
rename to sdg-core/src/main/java/tfm/graphs/augmented/APDG.java
diff --git a/sdg-core/src/main/java/tfm/graphs/augmented/PPDG.java b/sdg-core/src/main/java/tfm/graphs/augmented/PPDG.java
new file mode 100644
index 0000000000000000000000000000000000000000..6dd57cfd565ccf66745eb2e0049e05351d0ba08e
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/graphs/augmented/PPDG.java
@@ -0,0 +1,27 @@
+package tfm.graphs.augmented;
+
+import tfm.nodes.GraphNode;
+import tfm.slicing.PseudoPredicateSlicingAlgorithm;
+import tfm.slicing.Slice;
+import tfm.slicing.SlicingCriterion;
+import tfm.utils.NodeNotFoundException;
+
+import java.util.Optional;
+
+public class PPDG extends APDG {
+ public PPDG() {
+ this(new ACFG());
+ }
+
+ public PPDG(ACFG acfg) {
+ super(acfg);
+ }
+
+ @Override
+ public Slice slice(SlicingCriterion slicingCriterion) {
+ Optional> node = slicingCriterion.findNode(this);
+ if (node.isEmpty())
+ throw new NodeNotFoundException(slicingCriterion);
+ return new PseudoPredicateSlicingAlgorithm(this).traverse(node.get());
+ }
+}
diff --git a/src/main/java/tfm/graphs/cfg/CFG.java b/sdg-core/src/main/java/tfm/graphs/cfg/CFG.java
similarity index 100%
rename from src/main/java/tfm/graphs/cfg/CFG.java
rename to sdg-core/src/main/java/tfm/graphs/cfg/CFG.java
diff --git a/src/main/java/tfm/graphs/cfg/CFGBuilder.java b/sdg-core/src/main/java/tfm/graphs/cfg/CFGBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/cfg/CFGBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/cfg/CFGBuilder.java
diff --git a/src/main/java/tfm/graphs/pdg/ControlDependencyBuilder.java b/sdg-core/src/main/java/tfm/graphs/pdg/ControlDependencyBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/pdg/ControlDependencyBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/pdg/ControlDependencyBuilder.java
diff --git a/src/main/java/tfm/graphs/pdg/DataDependencyBuilder.java b/sdg-core/src/main/java/tfm/graphs/pdg/DataDependencyBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/pdg/DataDependencyBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/pdg/DataDependencyBuilder.java
diff --git a/src/main/java/tfm/graphs/pdg/PDG.java b/sdg-core/src/main/java/tfm/graphs/pdg/PDG.java
similarity index 82%
rename from src/main/java/tfm/graphs/pdg/PDG.java
rename to sdg-core/src/main/java/tfm/graphs/pdg/PDG.java
index 328281af6ebb27a13f3189cff6a9c96fe56dca2a..976ee6490a444d197e585db6785e49a2bfd58003 100644
--- a/src/main/java/tfm/graphs/pdg/PDG.java
+++ b/sdg-core/src/main/java/tfm/graphs/pdg/PDG.java
@@ -1,13 +1,13 @@
package tfm.graphs.pdg;
import com.github.javaparser.ast.body.MethodDeclaration;
-import tfm.arcs.Arc;
import tfm.arcs.pdg.ControlDependencyArc;
import tfm.arcs.pdg.DataDependencyArc;
import tfm.graphs.GraphWithRootNode;
import tfm.graphs.Sliceable;
import tfm.graphs.cfg.CFG;
import tfm.nodes.GraphNode;
+import tfm.slicing.ClassicSlicingAlgorithm;
import tfm.slicing.Slice;
import tfm.slicing.SlicingCriterion;
import tfm.utils.NodeNotFoundException;
@@ -47,22 +47,9 @@ public class PDG extends GraphWithRootNode implements Sliceab
@Override
public Slice slice(SlicingCriterion slicingCriterion) {
Optional> node = slicingCriterion.findNode(this);
- if (!node.isPresent())
+ if (node.isEmpty())
throw new NodeNotFoundException(slicingCriterion);
- Slice slice = new Slice();
- getSliceNodes(slice, node.get());
- return slice;
- }
-
- protected void getSliceNodes(Slice slice, GraphNode> node) {
- slice.add(node);
-
- for (Arc arc : incomingEdgesOf(node)) {
- GraphNode> from = getEdgeSource(arc);
- if (slice.contains(from))
- continue;
- getSliceNodes(slice, from);
- }
+ return new ClassicSlicingAlgorithm(this).traverse(node.get());
}
public CFG getCfg() {
diff --git a/src/main/java/tfm/graphs/pdg/PDGBuilder.java b/sdg-core/src/main/java/tfm/graphs/pdg/PDGBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/pdg/PDGBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/pdg/PDGBuilder.java
diff --git a/src/main/java/tfm/graphs/sdg/MethodCallReplacer.java b/sdg-core/src/main/java/tfm/graphs/sdg/MethodCallReplacer.java
similarity index 79%
rename from src/main/java/tfm/graphs/sdg/MethodCallReplacer.java
rename to sdg-core/src/main/java/tfm/graphs/sdg/MethodCallReplacer.java
index e8290fdec0024402f6e1f0ae4687a7f3c700f099..c3bc8affac2b29ed1af653d2e9d85f37f697887e 100644
--- a/src/main/java/tfm/graphs/sdg/MethodCallReplacer.java
+++ b/sdg-core/src/main/java/tfm/graphs/sdg/MethodCallReplacer.java
@@ -1,12 +1,7 @@
package tfm.graphs.sdg;
import com.github.javaparser.ast.body.MethodDeclaration;
-import tfm.graphs.GraphWithRootNode;
-import tfm.nodes.GraphNode;
import tfm.utils.Context;
-import tfm.utils.Logger;
-
-import java.util.Optional;
class MethodCallReplacer {
diff --git a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java b/sdg-core/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java
similarity index 82%
rename from src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java
rename to sdg-core/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java
index e6f334ae64c1975733897d7eee20b75d5394dd70..9b991a55a1fcb905cc950eddc41ac6b1c941f29e 100644
--- a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java
+++ b/sdg-core/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java
@@ -9,18 +9,16 @@ import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
import tfm.arcs.Arc;
-import tfm.arcs.pdg.DataDependencyArc;
import tfm.graphs.cfg.CFG;
import tfm.nodes.GraphNode;
import tfm.nodes.TypeNodeFactory;
import tfm.nodes.type.NodeType;
import tfm.utils.Context;
import tfm.utils.Logger;
-import tfm.utils.MethodDeclarationSolver;
import java.util.*;
-import java.util.stream.Collectors;
class MethodCallReplacerVisitor extends VoidVisitorAdapter {
@@ -95,19 +93,16 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter {
// .filter(Expression::isMethodCallExpr)
// .forEach(expression -> expression.accept(this, context));
- Logger.log("MethodCallReplacerVisitor", context);
-
- Optional> optionalNethodDeclarationNode =
- MethodDeclarationSolver.getInstance()
- .findDeclarationFrom(methodCallExpr)
- .flatMap(methodDeclaration -> sdg.findNodeByASTNode(methodDeclaration));
-
- if (!optionalNethodDeclarationNode.isPresent()) {
- Logger.format("Not found: '%s'. Discarding", methodCallExpr);
+ GraphNode methodDeclarationNode;
+ try {
+ methodDeclarationNode = methodCallExpr.resolve().toAst()
+ .flatMap(sdg::findNodeByASTNode)
+ .orElseThrow(() -> new UnsolvedSymbolException(""));
+ } catch (UnsolvedSymbolException e) {
+ Logger.format("Method declaration not found: '%s'. Discarding", methodCallExpr);
return;
}
- GraphNode methodDeclarationNode = optionalNethodDeclarationNode.get();
MethodDeclaration methodDeclaration = methodDeclarationNode.getAstNode();
GraphNode methodCallNode = sdg.addNode("CALL " + methodCallExpr.toString(), methodCallExpr, TypeNodeFactory.fromType(NodeType.METHOD_CALL));
@@ -150,16 +145,10 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter {
// Handle data dependency: Remove arc from method call node and add it to IN node
- List inDataDependencies = sdg.incomingEdgesOf(originalMethodCallNode).stream()
- .filter(arc -> arc.isDataDependencyArc() && Objects.equals(arc.getLabel(), argument.toString()))
- .map(Arc::asDataDependencyArc)
- .collect(Collectors.toList());
-
- for (DataDependencyArc arc : inDataDependencies) {
- GraphNode> dataDependencySource = sdg.getEdgeSource(arc);
- sdg.removeEdge(arc);
- sdg.addDataDependencyArc(dataDependencySource, argumentInNode, argument.toString());
- }
+ sdg.incomingEdgesOf(originalMethodCallNode).stream()
+ .filter(Arc::isDataDependencyArc)
+ .filter(arc -> Objects.equals(arc.getLabel(), argument.toString()))
+ .forEach(arc -> sdg.addDataDependencyArc(sdg.getEdgeSource(arc), argumentInNode, argument.toString()));
// Now, find the corresponding method declaration's in node and link argument node with it
@@ -205,16 +194,10 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter {
// Handle data dependency: remove arc from method call node and add it to OUT node
- List outDataDependencies = sdg.outgoingEdgesOf(originalMethodCallNode).stream()
- .filter(arc -> arc.isDataDependencyArc() && Objects.equals(arc.getLabel(), argument.toString()))
- .map(Arc::asDataDependencyArc)
- .collect(Collectors.toList());
-
- for (DataDependencyArc arc : outDataDependencies) {
- GraphNode> dataDependencyTarget = sdg.getEdgeTarget(arc);
- sdg.removeEdge(arc);
- sdg.addDataDependencyArc(argumentOutNode, dataDependencyTarget, argument.toString());
- }
+ sdg.outgoingEdgesOf(originalMethodCallNode).stream()
+ .filter(Arc::isDataDependencyArc)
+ .filter(arc -> Objects.equals(arc.getLabel(), argument.toString()))
+ .forEach(arc -> sdg.addDataDependencyArc(argumentOutNode, sdg.getEdgeTarget(arc), argument.toString()));
if (optionalParameterOutNode.isPresent()) {
sdg.addParameterInOutArc(optionalParameterOutNode.get(), argumentOutNode);
diff --git a/src/main/java/tfm/graphs/sdg/OutNodeVariableVisitor.java b/sdg-core/src/main/java/tfm/graphs/sdg/OutNodeVariableVisitor.java
similarity index 100%
rename from src/main/java/tfm/graphs/sdg/OutNodeVariableVisitor.java
rename to sdg-core/src/main/java/tfm/graphs/sdg/OutNodeVariableVisitor.java
diff --git a/src/main/java/tfm/graphs/sdg/SDG.java b/sdg-core/src/main/java/tfm/graphs/sdg/SDG.java
similarity index 85%
rename from src/main/java/tfm/graphs/sdg/SDG.java
rename to sdg-core/src/main/java/tfm/graphs/sdg/SDG.java
index 8f524de5361c80f8ab232f8a2dd36be69354effd..05ea563c61238780ceddfdfe097745079db36623 100644
--- a/src/main/java/tfm/graphs/sdg/SDG.java
+++ b/sdg-core/src/main/java/tfm/graphs/sdg/SDG.java
@@ -13,7 +13,8 @@ import tfm.arcs.sdg.SummaryArc;
import tfm.graphs.Buildable;
import tfm.graphs.Graph;
import tfm.graphs.cfg.CFG;
-import tfm.nodes.*;
+import tfm.nodes.GraphNode;
+import tfm.slicing.ClassicSlicingAlgorithm;
import tfm.slicing.Slice;
import tfm.slicing.Sliceable;
import tfm.slicing.SlicingCriterion;
@@ -26,19 +27,29 @@ public class SDG extends Graph implements Sliceable, Buildable methodCFGMap;
+ private NodeList compilationUnits;
public SDG() {
this.methodCFGMap = new HashMap<>();
}
+ public NodeList getCompilationUnits() {
+ return compilationUnits;
+ }
+
@Override
public Slice slice(SlicingCriterion slicingCriterion) {
- throw new RuntimeException("Slicing not implemented for the SDG");
+ Optional> optSlicingNode = slicingCriterion.findNode(this);
+ if (optSlicingNode.isEmpty())
+ throw new IllegalArgumentException("Could not locate the slicing criterion in the SDG");
+ return new ClassicSlicingAlgorithm(this).traverse(optSlicingNode.get());
}
@Override
public void build(NodeList nodeList) {
nodeList.accept(new SDGBuilder(this), new Context());
+ compilationUnits = nodeList;
+ built = true;
}
@Override
diff --git a/src/main/java/tfm/graphs/sdg/SDGBuilder.java b/sdg-core/src/main/java/tfm/graphs/sdg/SDGBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/sdg/SDGBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/sdg/SDGBuilder.java
diff --git a/src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java b/sdg-core/src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java
diff --git a/src/main/java/tfm/graphs/sdg/sumarcs/SummaryArcsBuilder.java b/sdg-core/src/main/java/tfm/graphs/sdg/sumarcs/SummaryArcsBuilder.java
similarity index 100%
rename from src/main/java/tfm/graphs/sdg/sumarcs/SummaryArcsBuilder.java
rename to sdg-core/src/main/java/tfm/graphs/sdg/sumarcs/SummaryArcsBuilder.java
diff --git a/src/main/java/tfm/nodes/GraphNode.java b/sdg-core/src/main/java/tfm/nodes/GraphNode.java
similarity index 100%
rename from src/main/java/tfm/nodes/GraphNode.java
rename to sdg-core/src/main/java/tfm/nodes/GraphNode.java
diff --git a/src/main/java/tfm/nodes/IdHelper.java b/sdg-core/src/main/java/tfm/nodes/IdHelper.java
similarity index 100%
rename from src/main/java/tfm/nodes/IdHelper.java
rename to sdg-core/src/main/java/tfm/nodes/IdHelper.java
diff --git a/src/main/java/tfm/nodes/NodeFactory.java b/sdg-core/src/main/java/tfm/nodes/NodeFactory.java
similarity index 98%
rename from src/main/java/tfm/nodes/NodeFactory.java
rename to sdg-core/src/main/java/tfm/nodes/NodeFactory.java
index b54b2efb8a07d6978b34ca83a4c279cbff078f5a..b0c588923a45196939a9b9b7cda0a57bffc52124 100644
--- a/src/main/java/tfm/nodes/NodeFactory.java
+++ b/sdg-core/src/main/java/tfm/nodes/NodeFactory.java
@@ -2,7 +2,6 @@ package tfm.nodes;
import com.github.javaparser.ast.Node;
import org.jetbrains.annotations.NotNull;
-import tfm.nodes.GraphNode;
import java.util.Collection;
diff --git a/src/main/java/tfm/nodes/TypeNodeFactory.java b/sdg-core/src/main/java/tfm/nodes/TypeNodeFactory.java
similarity index 100%
rename from src/main/java/tfm/nodes/TypeNodeFactory.java
rename to sdg-core/src/main/java/tfm/nodes/TypeNodeFactory.java
diff --git a/src/main/java/tfm/nodes/type/NodeType.java b/sdg-core/src/main/java/tfm/nodes/type/NodeType.java
similarity index 100%
rename from src/main/java/tfm/nodes/type/NodeType.java
rename to sdg-core/src/main/java/tfm/nodes/type/NodeType.java
diff --git a/sdg-core/src/main/java/tfm/slicing/ClassicSlicingAlgorithm.java b/sdg-core/src/main/java/tfm/slicing/ClassicSlicingAlgorithm.java
new file mode 100644
index 0000000000000000000000000000000000000000..e608af4cecd091a899ac60baa48599c63b92d6d5
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/slicing/ClassicSlicingAlgorithm.java
@@ -0,0 +1,68 @@
+package tfm.slicing;
+
+import tfm.arcs.Arc;
+import tfm.graphs.Graph;
+import tfm.nodes.GraphNode;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.function.Predicate;
+
+public class ClassicSlicingAlgorithm implements SlicingAlgorithm {
+ protected final Graph graph;
+
+ public ClassicSlicingAlgorithm(Graph graph) {
+ this.graph = graph;
+ }
+
+ @Override
+ public Slice traverse(GraphNode> slicingCriterion) {
+ Slice slice = new Slice();
+ slice.add(slicingCriterion);
+ pass(slice, this::ignorePass1);
+ pass(slice, this::ignorePass2);
+ return slice;
+ }
+
+ protected boolean ignorePass1(Arc arc) {
+ return arc.isInterproceduralOutputArc();
+ }
+
+ protected boolean ignorePass2(Arc arc) {
+ return arc.isInterproceduralInputArc();
+ }
+
+ protected void pass(Slice slice, Predicate ignoreCondition) {
+ // `toVisit` behaves like a set and using iterable we can use it as a queue
+ // More info: https://stackoverflow.com/a/2319126
+ LinkedHashSet> toVisit = new LinkedHashSet<>(slice.getGraphNodes());
+ Set> visited = new HashSet<>();
+
+ while (!toVisit.isEmpty()) {
+ GraphNode> node = removeFirst(toVisit);
+ // Avoid duplicate traversal
+ if (visited.contains(node))
+ continue;
+ visited.add(node);
+ // Traverse all edges backwards
+ for (Arc arc : graph.incomingEdgesOf(node)) {
+ if (ignoreCondition.test(arc))
+ continue;
+ GraphNode> source = graph.getEdgeSource(arc);
+ if (!visited.contains(source))
+ toVisit.add(source);
+ }
+ }
+
+ visited.forEach(slice::add);
+ }
+
+ protected static E removeFirst(Set set) {
+ Iterator i = set.iterator();
+ E e = i.next();
+ i.remove();
+ return e;
+ }
+}
diff --git a/sdg-core/src/main/java/tfm/slicing/FileLineSlicingCriterion.java b/sdg-core/src/main/java/tfm/slicing/FileLineSlicingCriterion.java
new file mode 100644
index 0000000000000000000000000000000000000000..df01201720eedefc0a24106d60a61d644d5cbb84
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/slicing/FileLineSlicingCriterion.java
@@ -0,0 +1,42 @@
+package tfm.slicing;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.stmt.Statement;
+import tfm.graphs.sdg.SDG;
+import tfm.nodes.GraphNode;
+
+import java.io.File;
+import java.util.Optional;
+
+public class FileLineSlicingCriterion extends LineNumberCriterion {
+ protected final File file;
+
+ public FileLineSlicingCriterion(File file, int lineNumber) {
+ super(lineNumber, null);
+ this.file = file;
+ }
+
+ @Override
+ public Optional> findNode(SDG graph) {
+ Optional optCu = findCompilationUnit(graph.getCompilationUnits());
+ if (optCu.isEmpty())
+ return Optional.empty();
+ return optCu.get().findFirst(Statement.class, this::matchesLine).flatMap(graph::findNodeByASTNode);
+ }
+
+ protected Optional findCompilationUnit(NodeList cus) {
+ for (CompilationUnit cu : cus) {
+ Optional optStorage = cu.getStorage();
+ if (optStorage.isPresent() && optStorage.get().getFileName().equals(file.getName())
+ && optStorage.get().getDirectory().toAbsolutePath().equals(file.getParentFile().toPath().toAbsolutePath()))
+ return Optional.of(cu);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public String toString() {
+ return file + "#" + lineNumber + ":" + variable;
+ }
+}
diff --git a/src/main/java/tfm/slicing/GraphNodeCriterion.java b/sdg-core/src/main/java/tfm/slicing/GraphNodeCriterion.java
similarity index 100%
rename from src/main/java/tfm/slicing/GraphNodeCriterion.java
rename to sdg-core/src/main/java/tfm/slicing/GraphNodeCriterion.java
diff --git a/src/main/java/tfm/slicing/LineNumberCriterion.java b/sdg-core/src/main/java/tfm/slicing/LineNumberCriterion.java
similarity index 78%
rename from src/main/java/tfm/slicing/LineNumberCriterion.java
rename to sdg-core/src/main/java/tfm/slicing/LineNumberCriterion.java
index 3eb8ead496dc6c3bde450244e5f66f1a7b6807d4..f7a238588cc35c9b6d6f3e6b6a31b8441c11b432 100644
--- a/src/main/java/tfm/slicing/LineNumberCriterion.java
+++ b/sdg-core/src/main/java/tfm/slicing/LineNumberCriterion.java
@@ -1,5 +1,6 @@
package tfm.slicing;
+import com.github.javaparser.Position;
import com.github.javaparser.ast.Node;
import tfm.graphs.cfg.CFG;
import tfm.graphs.pdg.PDG;
@@ -10,8 +11,9 @@ import tfm.utils.Logger;
import java.util.Optional;
public class LineNumberCriterion extends SlicingCriterion {
+ protected static final Position DEFAULT_POSITION = new Position(0, 0);
- private int lineNumber;
+ protected int lineNumber;
public LineNumberCriterion(int lineNumber, String variable) {
super(variable);
@@ -30,7 +32,7 @@ public class LineNumberCriterion extends SlicingCriterion {
return graph.vertexSet().stream().filter(node -> {
Node astNode = node.getAstNode();
- if (!astNode.getBegin().isPresent() || !astNode.getEnd().isPresent())
+ if (astNode.getBegin().isEmpty() || astNode.getEnd().isEmpty())
return false;
int begin = astNode.getBegin().get().line;
@@ -47,6 +49,10 @@ public class LineNumberCriterion extends SlicingCriterion {
return Optional.empty();
}
+ protected boolean matchesLine(Node node) {
+ return node.getBegin().orElse(DEFAULT_POSITION).line == lineNumber;
+ }
+
@Override
public String toString() {
return String.format("(%s, %s)", lineNumber, variable);
diff --git a/sdg-core/src/main/java/tfm/slicing/PseudoPredicateSlicingAlgorithm.java b/sdg-core/src/main/java/tfm/slicing/PseudoPredicateSlicingAlgorithm.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f66c4378e9f011738658f8791062c21e743d6dd
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/slicing/PseudoPredicateSlicingAlgorithm.java
@@ -0,0 +1,35 @@
+package tfm.slicing;
+
+import tfm.arcs.Arc;
+import tfm.graphs.Graph;
+import tfm.nodes.GraphNode;
+import tfm.utils.ASTUtils;
+
+public class PseudoPredicateSlicingAlgorithm extends ClassicSlicingAlgorithm {
+ protected GraphNode> slicingCriterion;
+
+ public PseudoPredicateSlicingAlgorithm(Graph graph) {
+ super(graph);
+ }
+
+ @Override
+ public Slice traverse(GraphNode> slicingCriterion) {
+ this.slicingCriterion = slicingCriterion;
+ return super.traverse(slicingCriterion);
+ }
+
+ @Override
+ protected boolean ignorePass1(Arc arc) {
+ return super.ignorePass1(arc) || ignorePseudoPredicate(arc);
+ }
+
+ @Override
+ protected boolean ignorePass2(Arc arc) {
+ return super.ignorePass2(arc) || ignorePseudoPredicate(arc);
+ }
+
+ protected boolean ignorePseudoPredicate(Arc arc) {
+ GraphNode> target = graph.getEdgeTarget(arc);
+ return ASTUtils.isPseudoPredicate(target.getAstNode()) && target != slicingCriterion;
+ }
+}
diff --git a/src/main/java/tfm/slicing/Slice.java b/sdg-core/src/main/java/tfm/slicing/Slice.java
similarity index 54%
rename from src/main/java/tfm/slicing/Slice.java
rename to sdg-core/src/main/java/tfm/slicing/Slice.java
index 91563f30a02fb85421dc3da02d4d957e85ad9adb..485a5da437bdf452e6e5530870091364c4295898 100644
--- a/src/main/java/tfm/slicing/Slice.java
+++ b/sdg-core/src/main/java/tfm/slicing/Slice.java
@@ -1,6 +1,8 @@
package tfm.slicing;
+import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.visitor.CloneVisitor;
import com.github.javaparser.ast.visitor.Visitable;
@@ -39,6 +41,41 @@ public class Slice {
return obj instanceof Slice && map.equals(((Slice) obj).map);
}
+ public Set> getGraphNodes() {
+ return Set.copyOf(map.values());
+ }
+
+ /**
+ * Organize all nodes pertaining to this slice in one or more CompilationUnits.
+ * CompilationUnits themselves need not be part of the slice to be included if any of their
+ * components are present.
+ */
+ public NodeList toAst() {
+ Map> cuMap = new HashMap<>();
+ // Add each node to the corresponding bucket of the map
+ // Nodes may not belong to a compilation unit (fictional nodes), and they are skipped for the slice.
+ for (Node node : nodes) {
+ Optional cu = node.findCompilationUnit();
+ if (cu.isEmpty()) continue;
+ cuMap.putIfAbsent(cu.get(), new HashSet<>());
+ cuMap.get(cu.get()).add(node);
+ }
+ // Traverse the AST of each compilation unit, creating a copy and
+ // removing any element not present in the slice.
+ NodeList cus = new NodeList<>();
+ SlicePruneVisitor sliceVisitor = new SlicePruneVisitor();
+ CloneVisitor cloneVisitor = new CloneVisitor();
+ for (Map.Entry> entry : cuMap.entrySet()) {
+ CompilationUnit clone = (CompilationUnit) entry.getKey().accept(cloneVisitor, null);
+ assert entry.getKey().getStorage().isPresent();
+ clone.setStorage(entry.getKey().getStorage().get().getPath());
+ clone.accept(sliceVisitor, entry.getValue());
+ cus.add(clone);
+ }
+ return cus;
+ }
+
+ @Deprecated
public Node getAst() {
List> methods = map.values().stream().filter(e -> e.getAstNode() instanceof MethodDeclaration).collect(Collectors.toList());
if (methods.size() == 1) {
@@ -59,7 +96,7 @@ public class Slice {
private MethodDeclaration getMethodAst(Node node) {
Visitable clone = node.accept(new CloneVisitor(), null);
assert clone instanceof MethodDeclaration;
- clone.accept(new SliceAstVisitor(), this);
+ clone.accept(new SlicePruneVisitor(), nodes);
return ((MethodDeclaration) clone);
}
}
diff --git a/sdg-core/src/main/java/tfm/slicing/SlicePruneVisitor.java b/sdg-core/src/main/java/tfm/slicing/SlicePruneVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f78e870019c588bbcfef2860b3a9fb7dd81fa6cd
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/slicing/SlicePruneVisitor.java
@@ -0,0 +1,171 @@
+package tfm.slicing;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.visitor.ModifierVisitor;
+import com.github.javaparser.ast.visitor.Visitable;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class SlicePruneVisitor extends ModifierVisitor> {
+ // ========== Utility methods ==========
+
+ protected void fillBody(Node n) {
+ if (!(n instanceof NodeWithBody))
+ return;
+ NodeWithBody> nb = ((NodeWithBody>) n);
+ if (nb.getBody() == null)
+ nb.setBody(new EmptyStmt());
+ }
+
+ // ========== File visitors ==========
+
+ @Override
+ public Visitable visit(CompilationUnit n, Set arg) {
+ boolean keep = arg.contains(n);
+ Visitable v = super.visit(n, arg);
+ return keep || !((Node) v).getChildNodes().isEmpty() ? v : null;
+ }
+
+ @Override
+ public Visitable visit(ClassOrInterfaceDeclaration n, Set arg) {
+ boolean keep = arg.contains(n);
+ Visitable v = super.visit(n, arg);
+ return keep || !((Node) v).getChildNodes().isEmpty() ? v : null;
+ }
+
+ // ========== Class body visitors ==========
+
+ @Override
+ public Visitable visit(MethodDeclaration n, Set arg) {
+ boolean keep = arg.contains(n);
+ Visitable v = super.visit(n, arg);
+ return keep ? v : null;
+ }
+
+ @Override
+ public Visitable visit(ConstructorDeclaration n, Set arg) {
+ boolean keep = arg.contains(n);
+ Visitable v = super.visit(n, arg);
+ return keep ? v : null;
+ }
+
+ @Override
+ public Visitable visit(FieldDeclaration n, Set arg) {
+ boolean keep = arg.contains(n);
+ Visitable v = super.visit(n, arg);
+ return keep ? v : null;
+ }
+
+// ========== Method body visitors ==========
+ // 3 alternatives:
+ // a. Without relevant children and included if on the slice or not (e.g. ExpressionStmt)
+ // b. With relevant children and included if of the slice or not, children are discarded if not included (e.g. WhileStmt)
+ // c. With relevant children and included if any children is included OR if on the slice (e.g. SwitchEntryStmt, LabeledStmt)
+
+ @Override
+ public Visitable visit(BreakStmt n, Set arg) {
+ return arg.contains(n) ? n : null;
+ }
+
+ @Override
+ public Visitable visit(ContinueStmt n, Set arg) {
+ return arg.contains(n) ? n : null;
+ }
+
+ @Override
+ public Visitable visit(DoStmt n, Set arg) {
+ boolean keep = arg.contains(n);
+ super.visit(n, arg);
+ fillBody(n);
+ return keep ? n : null;
+ }
+
+ @Override
+ public Visitable visit(ForEachStmt n, Set arg) {
+ boolean keep = arg.contains(n);
+ super.visit(n, arg);
+ fillBody(n);
+ return keep ? n : null;
+ }
+
+ @Override
+ public Visitable visit(ForStmt n, Set arg) {
+ boolean keep = arg.contains(n);
+ super.visit(n, arg);
+ n.setInitialization(new NodeList<>(n.getInitialization().stream()
+ .filter(arg::contains).collect(Collectors.toList())));
+ n.setUpdate(new NodeList<>(n.getUpdate().stream()
+ .filter(arg::contains).collect(Collectors.toList())));
+ fillBody(n);
+ if (keep)
+ return n;
+ if (n.getInitialization().isEmpty() && n.getUpdate().isEmpty())
+ return null;
+ return new ForStmt(n.getInitialization(), new BooleanLiteralExpr(false),
+ n.getUpdate(), n.getBody());
+ }
+
+ @Override
+ public Visitable visit(WhileStmt n, Set arg) {
+ boolean keep = arg.contains(n);
+ super.visit(n, arg);
+ fillBody(n);
+ return keep ? n : null;
+ }
+
+ @Override
+ public Visitable visit(IfStmt n, Set arg) {
+ boolean keep = arg.contains(n);
+ super.visit(n, arg);
+ if (n.getThenStmt() == null)
+ n.setThenStmt(new EmptyStmt());
+ return keep ? n : null;
+ }
+
+ @Override
+ public Visitable visit(LabeledStmt n, Set arg) {
+ super.visit(n, arg);
+ return n.getStatement() != null ? n : null;
+ }
+
+ @Override
+ public Visitable visit(ReturnStmt n, Set arg) {
+ return arg.contains(n) ? n : null;
+ }
+
+ @Override
+ public Visitable visit(ThrowStmt n, Set arg) {
+ return arg.contains(n) ? n : null;
+ }
+
+ @Override
+ public Visitable visit(SwitchEntryStmt n, Set arg) {
+ boolean keep = arg.contains(n);
+ super.visit(n, arg);
+ if (!n.getStatements().isEmpty())
+ return n;
+ return keep ? n : null;
+ }
+
+ @Override
+ public Visitable visit(SwitchStmt n, Set arg) {
+ boolean keep = arg.contains(n);
+ super.visit(n, arg);
+ return keep ? n : null;
+ }
+
+ @Override
+ public Visitable visit(ExpressionStmt n, Set arg) {
+ return arg.contains(n) ? n : null;
+ }
+}
diff --git a/src/main/java/tfm/slicing/Sliceable.java b/sdg-core/src/main/java/tfm/slicing/Sliceable.java
similarity index 100%
rename from src/main/java/tfm/slicing/Sliceable.java
rename to sdg-core/src/main/java/tfm/slicing/Sliceable.java
diff --git a/sdg-core/src/main/java/tfm/slicing/SlicingAlgorithm.java b/sdg-core/src/main/java/tfm/slicing/SlicingAlgorithm.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ad7c4aa7fd74d035e3d3bb691f830db8c5765fe
--- /dev/null
+++ b/sdg-core/src/main/java/tfm/slicing/SlicingAlgorithm.java
@@ -0,0 +1,7 @@
+package tfm.slicing;
+
+import tfm.nodes.GraphNode;
+
+public interface SlicingAlgorithm {
+ Slice traverse(GraphNode> slicingCriterion);
+}
diff --git a/src/main/java/tfm/slicing/SlicingCriterion.java b/sdg-core/src/main/java/tfm/slicing/SlicingCriterion.java
similarity index 100%
rename from src/main/java/tfm/slicing/SlicingCriterion.java
rename to sdg-core/src/main/java/tfm/slicing/SlicingCriterion.java
diff --git a/src/main/java/tfm/utils/ASTUtils.java b/sdg-core/src/main/java/tfm/utils/ASTUtils.java
similarity index 98%
rename from src/main/java/tfm/utils/ASTUtils.java
rename to sdg-core/src/main/java/tfm/utils/ASTUtils.java
index 7744e8b349e7873193689f81f1558a57aa6fe238..dc3de70289dc493423704b02c427314e1a4d6510 100644
--- a/src/main/java/tfm/utils/ASTUtils.java
+++ b/sdg-core/src/main/java/tfm/utils/ASTUtils.java
@@ -3,7 +3,6 @@ package tfm.utils;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
-import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.stmt.*;
import java.util.Objects;
diff --git a/src/main/java/tfm/utils/Context.java b/sdg-core/src/main/java/tfm/utils/Context.java
similarity index 100%
rename from src/main/java/tfm/utils/Context.java
rename to sdg-core/src/main/java/tfm/utils/Context.java
diff --git a/src/main/java/tfm/utils/FileUtil.java b/sdg-core/src/main/java/tfm/utils/FileUtil.java
similarity index 100%
rename from src/main/java/tfm/utils/FileUtil.java
rename to sdg-core/src/main/java/tfm/utils/FileUtil.java
diff --git a/src/main/java/tfm/utils/Logger.java b/sdg-core/src/main/java/tfm/utils/Logger.java
similarity index 100%
rename from src/main/java/tfm/utils/Logger.java
rename to sdg-core/src/main/java/tfm/utils/Logger.java
diff --git a/src/main/java/tfm/utils/NodeNotFoundException.java b/sdg-core/src/main/java/tfm/utils/NodeNotFoundException.java
similarity index 100%
rename from src/main/java/tfm/utils/NodeNotFoundException.java
rename to sdg-core/src/main/java/tfm/utils/NodeNotFoundException.java
diff --git a/src/main/java/tfm/utils/Utils.java b/sdg-core/src/main/java/tfm/utils/Utils.java
similarity index 100%
rename from src/main/java/tfm/utils/Utils.java
rename to sdg-core/src/main/java/tfm/utils/Utils.java
diff --git a/src/main/java/tfm/variables/VariableExtractor.java b/sdg-core/src/main/java/tfm/variables/VariableExtractor.java
similarity index 97%
rename from src/main/java/tfm/variables/VariableExtractor.java
rename to sdg-core/src/main/java/tfm/variables/VariableExtractor.java
index 962e5389061ee8d147a894fcee956e07f829c772..d4828495c327f98c14c7524adca7dca7f5f2f8fb 100644
--- a/src/main/java/tfm/variables/VariableExtractor.java
+++ b/sdg-core/src/main/java/tfm/variables/VariableExtractor.java
@@ -1,7 +1,6 @@
package tfm.variables;
import com.github.javaparser.ast.Node;
-import com.github.javaparser.ast.expr.Expression;
import org.checkerframework.checker.nullness.qual.NonNull;
import tfm.variables.actions.VariableAction;
diff --git a/src/main/java/tfm/variables/VariableVisitor.java b/sdg-core/src/main/java/tfm/variables/VariableVisitor.java
similarity index 99%
rename from src/main/java/tfm/variables/VariableVisitor.java
rename to sdg-core/src/main/java/tfm/variables/VariableVisitor.java
index fd2f639071f991b04a2a8c9c35427e09f7ee84cb..fb629984de2662143d576b83b148d7a49391c897 100644
--- a/src/main/java/tfm/variables/VariableVisitor.java
+++ b/sdg-core/src/main/java/tfm/variables/VariableVisitor.java
@@ -7,8 +7,6 @@ import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import org.checkerframework.checker.nullness.qual.NonNull;
import tfm.variables.actions.VariableAction;
-import java.awt.*;
-
abstract class VariableVisitor extends VoidVisitorAdapter {
@Override
diff --git a/src/main/java/tfm/variables/actions/VariableAction.java b/sdg-core/src/main/java/tfm/variables/actions/VariableAction.java
similarity index 100%
rename from src/main/java/tfm/variables/actions/VariableAction.java
rename to sdg-core/src/main/java/tfm/variables/actions/VariableAction.java
diff --git a/src/main/java/tfm/variables/actions/VariableDeclaration.java b/sdg-core/src/main/java/tfm/variables/actions/VariableDeclaration.java
similarity index 100%
rename from src/main/java/tfm/variables/actions/VariableDeclaration.java
rename to sdg-core/src/main/java/tfm/variables/actions/VariableDeclaration.java
diff --git a/src/main/java/tfm/variables/actions/VariableDefinition.java b/sdg-core/src/main/java/tfm/variables/actions/VariableDefinition.java
similarity index 100%
rename from src/main/java/tfm/variables/actions/VariableDefinition.java
rename to sdg-core/src/main/java/tfm/variables/actions/VariableDefinition.java
diff --git a/src/main/java/tfm/variables/actions/VariableUse.java b/sdg-core/src/main/java/tfm/variables/actions/VariableUse.java
similarity index 100%
rename from src/main/java/tfm/variables/actions/VariableUse.java
rename to sdg-core/src/main/java/tfm/variables/actions/VariableUse.java
diff --git a/src/test/java/tfm/graphs/pdg/HandCraftedGraphs.java b/sdg-core/src/test/java/tfm/graphs/pdg/HandCraftedGraphs.java
similarity index 100%
rename from src/test/java/tfm/graphs/pdg/HandCraftedGraphs.java
rename to sdg-core/src/test/java/tfm/graphs/pdg/HandCraftedGraphs.java
diff --git a/src/test/java/tfm/graphs/pdg/PDGTests.java b/sdg-core/src/test/java/tfm/graphs/pdg/PDGTests.java
similarity index 95%
rename from src/test/java/tfm/graphs/pdg/PDGTests.java
rename to sdg-core/src/test/java/tfm/graphs/pdg/PDGTests.java
index 3063df63c4869b0841dd6db0a6987beafc005146..106858df22ba724736c8bedfa6819fc671756681 100644
--- a/src/test/java/tfm/graphs/pdg/PDGTests.java
+++ b/sdg-core/src/test/java/tfm/graphs/pdg/PDGTests.java
@@ -9,8 +9,6 @@ import com.github.javaparser.ast.stmt.ThrowStmt;
import com.github.javaparser.ast.stmt.TryStmt;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
-import tfm.exec.GraphLog;
-import tfm.exec.PDGLog;
import tfm.graphs.augmented.ACFG;
import tfm.graphs.augmented.APDG;
import tfm.graphs.augmented.PPDG;
@@ -59,14 +57,14 @@ public class PDGTests {
private void runPdg(File file, String methodName, MethodDeclaration root, PDG pdg) throws IOException {
pdg.build(root);
- GraphLog> graphLog = new PDGLog(pdg);
- graphLog.log();
- try {
- graphLog.generateImages(file.getPath() + "-" + methodName);
- } catch (Exception e) {
- System.err.println("Could not generate PNG");
- System.err.println(e.getMessage());
- }
+// GraphLog> graphLog = new PDGLog(pdg);
+// graphLog.log();
+// try {
+// graphLog.generateImages(file.getPath() + "-" + methodName);
+// } catch (Exception e) {
+// System.err.println("Could not generate PNG");
+// System.err.println(e.getMessage());
+// }
}
@ParameterizedTest(name = "[{index}] {0} ({1})")
diff --git a/src/test/java/tfm/utils/FileFinder.java b/sdg-core/src/test/java/tfm/utils/FileFinder.java
similarity index 100%
rename from src/test/java/tfm/utils/FileFinder.java
rename to sdg-core/src/test/java/tfm/utils/FileFinder.java
diff --git a/src/test/res/carlos/Problem1.java b/sdg-core/src/test/res/carlos/Problem1.java
similarity index 100%
rename from src/test/res/carlos/Problem1.java
rename to sdg-core/src/test/res/carlos/Problem1.java
diff --git a/src/test/res/carlos/Problem2.java b/sdg-core/src/test/res/carlos/Problem2.java
similarity index 100%
rename from src/test/res/carlos/Problem2.java
rename to sdg-core/src/test/res/carlos/Problem2.java
diff --git a/src/test/res/carlos/Problem3.java b/sdg-core/src/test/res/carlos/Problem3.java
similarity index 100%
rename from src/test/res/carlos/Problem3.java
rename to sdg-core/src/test/res/carlos/Problem3.java
diff --git a/src/test/res/carlos/Test1.java b/sdg-core/src/test/res/carlos/Test1.java
similarity index 100%
rename from src/test/res/carlos/Test1.java
rename to sdg-core/src/test/res/carlos/Test1.java
diff --git a/src/test/res/java-slicing-benchmarks b/sdg-core/src/test/res/java-slicing-benchmarks
similarity index 100%
rename from src/test/res/java-slicing-benchmarks
rename to sdg-core/src/test/res/java-slicing-benchmarks
diff --git a/src/test/res/ltd-samples/BasicBreak.java b/sdg-core/src/test/res/ltd-samples/BasicBreak.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicBreak.java
rename to sdg-core/src/test/res/ltd-samples/BasicBreak.java
diff --git a/src/test/res/ltd-samples/BasicContinue.java b/sdg-core/src/test/res/ltd-samples/BasicContinue.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicContinue.java
rename to sdg-core/src/test/res/ltd-samples/BasicContinue.java
diff --git a/src/test/res/ltd-samples/BasicForeach.java b/sdg-core/src/test/res/ltd-samples/BasicForeach.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicForeach.java
rename to sdg-core/src/test/res/ltd-samples/BasicForeach.java
diff --git a/src/test/res/ltd-samples/BasicIf.java b/sdg-core/src/test/res/ltd-samples/BasicIf.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicIf.java
rename to sdg-core/src/test/res/ltd-samples/BasicIf.java
diff --git a/src/test/res/ltd-samples/BasicIfElse.java b/sdg-core/src/test/res/ltd-samples/BasicIfElse.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicIfElse.java
rename to sdg-core/src/test/res/ltd-samples/BasicIfElse.java
diff --git a/src/test/res/ltd-samples/BasicSwitch.java b/sdg-core/src/test/res/ltd-samples/BasicSwitch.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicSwitch.java
rename to sdg-core/src/test/res/ltd-samples/BasicSwitch.java
diff --git a/src/test/res/ltd-samples/BasicSwitchDefault.java b/sdg-core/src/test/res/ltd-samples/BasicSwitchDefault.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicSwitchDefault.java
rename to sdg-core/src/test/res/ltd-samples/BasicSwitchDefault.java
diff --git a/src/test/res/ltd-samples/BasicSwitchNoBreak.java b/sdg-core/src/test/res/ltd-samples/BasicSwitchNoBreak.java
similarity index 100%
rename from src/test/res/ltd-samples/BasicSwitchNoBreak.java
rename to sdg-core/src/test/res/ltd-samples/BasicSwitchNoBreak.java
diff --git a/src/test/res/ltd-samples/Bucles_1.java b/sdg-core/src/test/res/ltd-samples/Bucles_1.java
similarity index 100%
rename from src/test/res/ltd-samples/Bucles_1.java
rename to sdg-core/src/test/res/ltd-samples/Bucles_1.java
diff --git a/src/test/res/ltd-samples/Bucles_2.java b/sdg-core/src/test/res/ltd-samples/Bucles_2.java
similarity index 100%
rename from src/test/res/ltd-samples/Bucles_2.java
rename to sdg-core/src/test/res/ltd-samples/Bucles_2.java
diff --git a/src/test/res/ltd-samples/Bucles_3.java b/sdg-core/src/test/res/ltd-samples/Bucles_3.java
similarity index 100%
rename from src/test/res/ltd-samples/Bucles_3.java
rename to sdg-core/src/test/res/ltd-samples/Bucles_3.java
diff --git a/src/test/res/ltd-samples/Bucles_4.java b/sdg-core/src/test/res/ltd-samples/Bucles_4.java
similarity index 100%
rename from src/test/res/ltd-samples/Bucles_4.java
rename to sdg-core/src/test/res/ltd-samples/Bucles_4.java
diff --git a/src/test/res/ltd-samples/Bucles_5.java b/sdg-core/src/test/res/ltd-samples/Bucles_5.java
similarity index 100%
rename from src/test/res/ltd-samples/Bucles_5.java
rename to sdg-core/src/test/res/ltd-samples/Bucles_5.java
diff --git a/src/test/res/ltd-samples/Bucles_6.java b/sdg-core/src/test/res/ltd-samples/Bucles_6.java
similarity index 100%
rename from src/test/res/ltd-samples/Bucles_6.java
rename to sdg-core/src/test/res/ltd-samples/Bucles_6.java
diff --git a/src/test/res/ltd-samples/Bucles_Josep.java b/sdg-core/src/test/res/ltd-samples/Bucles_Josep.java
similarity index 100%
rename from src/test/res/ltd-samples/Bucles_Josep.java
rename to sdg-core/src/test/res/ltd-samples/Bucles_Josep.java
diff --git a/src/test/res/ltd-samples/ReturnTest.java b/sdg-core/src/test/res/ltd-samples/ReturnTest.java
similarity index 100%
rename from src/test/res/ltd-samples/ReturnTest.java
rename to sdg-core/src/test/res/ltd-samples/ReturnTest.java
diff --git a/src/test/res/ltd-samples/Test_1.java b/sdg-core/src/test/res/ltd-samples/Test_1.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_1.java
rename to sdg-core/src/test/res/ltd-samples/Test_1.java
diff --git a/src/test/res/ltd-samples/Test_2.java b/sdg-core/src/test/res/ltd-samples/Test_2.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_2.java
rename to sdg-core/src/test/res/ltd-samples/Test_2.java
diff --git a/src/test/res/ltd-samples/Test_3.java b/sdg-core/src/test/res/ltd-samples/Test_3.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_3.java
rename to sdg-core/src/test/res/ltd-samples/Test_3.java
diff --git a/src/test/res/ltd-samples/Test_4.java b/sdg-core/src/test/res/ltd-samples/Test_4.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_4.java
rename to sdg-core/src/test/res/ltd-samples/Test_4.java
diff --git a/src/test/res/ltd-samples/Test_5.java b/sdg-core/src/test/res/ltd-samples/Test_5.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_5.java
rename to sdg-core/src/test/res/ltd-samples/Test_5.java
diff --git a/src/test/res/ltd-samples/Test_6.java b/sdg-core/src/test/res/ltd-samples/Test_6.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_6.java
rename to sdg-core/src/test/res/ltd-samples/Test_6.java
diff --git a/src/test/res/ltd-samples/Test_7.java b/sdg-core/src/test/res/ltd-samples/Test_7.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_7.java
rename to sdg-core/src/test/res/ltd-samples/Test_7.java
diff --git a/src/test/res/ltd-samples/Test_8.java b/sdg-core/src/test/res/ltd-samples/Test_8.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_8.java
rename to sdg-core/src/test/res/ltd-samples/Test_8.java
diff --git a/src/test/res/ltd-samples/Test_9.java b/sdg-core/src/test/res/ltd-samples/Test_9.java
similarity index 100%
rename from src/test/res/ltd-samples/Test_9.java
rename to sdg-core/src/test/res/ltd-samples/Test_9.java
diff --git a/src/test/res/papers/Example1_Horwitz_PPDG.java b/sdg-core/src/test/res/papers/Example1_Horwitz_PPDG.java
similarity index 100%
rename from src/test/res/papers/Example1_Horwitz_PPDG.java
rename to sdg-core/src/test/res/papers/Example1_Horwitz_PPDG.java
diff --git a/src/test/res/programs/WhileLoop.java b/sdg-core/src/test/res/programs/WhileLoop.java
similarity index 100%
rename from src/test/res/programs/WhileLoop.java
rename to sdg-core/src/test/res/programs/WhileLoop.java
diff --git a/src/test/res/programs/cfg/CFG_Test1.java b/sdg-core/src/test/res/programs/cfg/CFG_Test1.java
similarity index 100%
rename from src/test/res/programs/cfg/CFG_Test1.java
rename to sdg-core/src/test/res/programs/cfg/CFG_Test1.java
diff --git a/src/test/res/programs/cfg/CFG_Test2.java b/sdg-core/src/test/res/programs/cfg/CFG_Test2.java
similarity index 100%
rename from src/test/res/programs/cfg/CFG_Test2.java
rename to sdg-core/src/test/res/programs/cfg/CFG_Test2.java
diff --git a/src/test/res/programs/cfg/CFG_Test3.java b/sdg-core/src/test/res/programs/cfg/CFG_Test3.java
similarity index 100%
rename from src/test/res/programs/cfg/CFG_Test3.java
rename to sdg-core/src/test/res/programs/cfg/CFG_Test3.java
diff --git a/src/test/res/programs/cfg/CFG_Test4.java b/sdg-core/src/test/res/programs/cfg/CFG_Test4.java
similarity index 100%
rename from src/test/res/programs/cfg/CFG_Test4.java
rename to sdg-core/src/test/res/programs/cfg/CFG_Test4.java
diff --git a/src/test/res/programs/cfg/CFG_Test5.java b/sdg-core/src/test/res/programs/cfg/CFG_Test5.java
similarity index 100%
rename from src/test/res/programs/cfg/CFG_Test5.java
rename to sdg-core/src/test/res/programs/cfg/CFG_Test5.java
diff --git a/src/test/res/programs/cfg/Eval_1.java b/sdg-core/src/test/res/programs/cfg/Eval_1.java
similarity index 100%
rename from src/test/res/programs/cfg/Eval_1.java
rename to sdg-core/src/test/res/programs/cfg/Eval_1.java
diff --git a/src/test/res/programs/cfg/Eval_2.java b/sdg-core/src/test/res/programs/cfg/Eval_2.java
similarity index 100%
rename from src/test/res/programs/cfg/Eval_2.java
rename to sdg-core/src/test/res/programs/cfg/Eval_2.java
diff --git a/src/test/res/programs/cfg/Eval_3.java b/sdg-core/src/test/res/programs/cfg/Eval_3.java
similarity index 100%
rename from src/test/res/programs/cfg/Eval_3.java
rename to sdg-core/src/test/res/programs/cfg/Eval_3.java
diff --git a/src/test/res/programs/cfg/Eval_4.java b/sdg-core/src/test/res/programs/cfg/Eval_4.java
similarity index 100%
rename from src/test/res/programs/cfg/Eval_4.java
rename to sdg-core/src/test/res/programs/cfg/Eval_4.java
diff --git a/src/test/res/programs/pdg/Example1.java b/sdg-core/src/test/res/programs/pdg/Example1.java
similarity index 100%
rename from src/test/res/programs/pdg/Example1.java
rename to sdg-core/src/test/res/programs/pdg/Example1.java
diff --git a/src/test/res/programs/pdg/Example2.java b/sdg-core/src/test/res/programs/pdg/Example2.java
similarity index 100%
rename from src/test/res/programs/pdg/Example2.java
rename to sdg-core/src/test/res/programs/pdg/Example2.java
diff --git a/src/test/res/programs/pdg/Example3.java b/sdg-core/src/test/res/programs/pdg/Example3.java
similarity index 100%
rename from src/test/res/programs/pdg/Example3.java
rename to sdg-core/src/test/res/programs/pdg/Example3.java
diff --git a/src/test/res/programs/pdg/Test.java b/sdg-core/src/test/res/programs/pdg/Test.java
similarity index 100%
rename from src/test/res/programs/pdg/Test.java
rename to sdg-core/src/test/res/programs/pdg/Test.java
diff --git a/src/test/res/programs/sdg/Example1.java b/sdg-core/src/test/res/programs/sdg/Example1.java
similarity index 100%
rename from src/test/res/programs/sdg/Example1.java
rename to sdg-core/src/test/res/programs/sdg/Example1.java
diff --git a/src/test/res/programs/sdg/Example2.java b/sdg-core/src/test/res/programs/sdg/Example2.java
similarity index 100%
rename from src/test/res/programs/sdg/Example2.java
rename to sdg-core/src/test/res/programs/sdg/Example2.java
diff --git a/src/main/java/tfm/arcs/sdg/ParameterInOutArc.java b/src/main/java/tfm/arcs/sdg/ParameterInOutArc.java
deleted file mode 100644
index 50673b700ca84ca8f7e556f209334b5376298f70..0000000000000000000000000000000000000000
--- a/src/main/java/tfm/arcs/sdg/ParameterInOutArc.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package tfm.arcs.sdg;
-
-import org.jgrapht.io.Attribute;
-import org.jgrapht.io.DefaultAttribute;
-import tfm.arcs.Arc;
-
-import java.util.Map;
-
-public class ParameterInOutArc extends Arc {
- @Override
- public Map getDotAttributes() {
- Map map = super.getDotAttributes();
- map.put("style", DefaultAttribute.createAttribute("dashed"));
- return map;
- }
-}
diff --git a/src/main/java/tfm/exec/Main.java b/src/main/java/tfm/exec/Main.java
deleted file mode 100644
index 6d7a54e41a450a85e931b32efde677cbb82f27c4..0000000000000000000000000000000000000000
--- a/src/main/java/tfm/exec/Main.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package tfm.exec;
-
-import com.github.javaparser.JavaParser;
-import com.github.javaparser.ast.Node;
-import com.github.javaparser.ast.NodeList;
-import com.github.javaparser.ast.body.MethodDeclaration;
-import com.github.javaparser.ast.type.Type;
-import com.github.javaparser.ast.visitor.GenericVisitor;
-import com.github.javaparser.ast.visitor.VoidVisitor;
-import com.github.javaparser.resolution.types.ResolvedType;
-import tfm.graphs.cfg.CFG;
-import tfm.graphs.Graph;
-import tfm.graphs.pdg.PDG;
-import tfm.graphs.sdg.SDG;
-import tfm.utils.Logger;
-import tfm.utils.Utils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Objects;
-import java.util.Optional;
-
-public class Main {
-
- public static final String PROGRAM = Utils.PROGRAMS_FOLDER + "sdg/Example1.java";
- public static final String GRAPH = GraphLog.PDG;
- public static final String METHOD = "main";
-
- public static void main(String[] args) throws IOException {
- JavaParser.getStaticConfiguration().setAttributeComments(false);
-
- // File
- File file = new File(PROGRAM);
- Node root = JavaParser.parse(file);
-
- if (!METHOD.isEmpty()) {
- Optional methodDeclarationOptional = root.findFirst(MethodDeclaration.class,
- methodDeclaration -> Objects.equals(methodDeclaration.getNameAsString(), METHOD));
-
- if (!methodDeclarationOptional.isPresent()) {
- Logger.format("Method '%s' not found in '%s'. Exiting...", METHOD, PROGRAM);
- return;
- }
-
- root = methodDeclarationOptional.get();
- }
-
- // GraphLog
- long t0 = System.nanoTime();
- Graph graph = getBuiltGraph(args.length == 1 ? args[0] : GRAPH, (MethodDeclaration) root);
- long tf = System.nanoTime();
- long tt = tf - t0;
-
- GraphLog> graphLog = getGraphLog(graph);
- graphLog.log();
- graphLog.openVisualRepresentation();
-
- Logger.log();
- Logger.format("Graph generated in %.2f ms", tt / 10e6);
- }
-
- private static Graph getBuiltGraph(String graph, MethodDeclaration method) {
- switch (graph) {
- case GraphLog.CFG:
- CFG cfg = new CFG();
- cfg.build(method);
- return cfg;
- case GraphLog.PDG:
- PDG pdg = new PDG();
- pdg.build(method);
- return pdg;
- case GraphLog.SDG:
- SDG sdg = new SDG();
- sdg.build(new NodeList<>(method.findCompilationUnit().get()));
- return sdg;
- default:
- Logger.log("Unkown graph type");
- System.exit(1);
- return null;
- }
- }
-
- private static GraphLog> getGraphLog(Graph graph) {
- if (graph instanceof CFG)
- return new CFGLog((CFG) graph);
- else if (graph instanceof PDG)
- return new PDGLog((PDG) graph);
- else if (graph instanceof SDG)
- return new SDGLog((SDG) graph);
- Logger.log("Unknown graph type");
- System.exit(1);
- return null;
- }
-}
diff --git a/src/main/java/tfm/exec/MethodResolver.java b/src/main/java/tfm/exec/MethodResolver.java
deleted file mode 100644
index e2d28d6ccb7267ca43d700e6b042a3d7ce0cb09b..0000000000000000000000000000000000000000
--- a/src/main/java/tfm/exec/MethodResolver.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package tfm.exec;
-
-import com.github.javaparser.JavaParser;
-import com.github.javaparser.ast.CompilationUnit;
-import com.github.javaparser.ast.NodeList;
-import com.github.javaparser.ast.body.AnnotationDeclaration;
-import com.github.javaparser.ast.body.MethodDeclaration;
-import com.github.javaparser.ast.expr.MethodCallExpr;
-import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
-import com.github.javaparser.resolution.UnsolvedSymbolException;
-import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
-import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
-import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
-import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
-import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
-import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
-import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
-import tfm.graphs.sdg.SDG;
-import tfm.nodes.GraphNode;
-import tfm.utils.Context;
-import tfm.utils.Logger;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-import java.util.Optional;
-
-public class MethodResolver {
-
- private static class Args {
- String file;
- String method;
- }
-
- public static void main(String[] inputArgs) throws FileNotFoundException {
- Args args = parseArgs(inputArgs);
-
- CompilationUnit cu = JavaParser.parse(new File(args.file));
-
- SDG sdg = new SDG();
- sdg.build(new NodeList<>(cu));
-
- VoidVisitorAdapter visitor = new VoidVisitorAdapter() {
- @Override
- public void visit(MethodCallExpr n, Void arg) {
- TypeSolver solver = new JavaParserTypeSolver(args.file.substring(0, args.file.lastIndexOf('/')));
-
- Logger.log("-- Trying to solve method " + n.getNameAsString() + " --");
-
- Optional optionalResolvedMethod;
-
- try {
- optionalResolvedMethod = getMethodCallWithJavaParserSymbolSolver(n, solver, new ReflectionTypeSolver());
- } catch (UnsolvedSymbolException e) {
- optionalResolvedMethod = Optional.empty();
- }
-
- if (!optionalResolvedMethod.isPresent()) {
- Logger.format("Not found: %s", n);
- return;
- }
-
- Logger.format("Found: %s", n.getNameAsString());
- Logger.log(optionalResolvedMethod.get().getSignature().asString());
-
- Logger.log("-- Trying to match with a node from SDG --");
- Optional> methodDeclarationNode = optionalResolvedMethod.flatMap(sdg::findNodeByASTNode);
-
- if (!methodDeclarationNode.isPresent()) {
- Logger.log("Failed to find node in SDG");
- return;
- }
-
- Logger.format("SDG node: %s", methodDeclarationNode.get());
-
- }
- };
-
- cu.accept(visitor, null);
- }
-
- private static Args parseArgs(String[] args) {
- Args res = new Args();
-
- Logger.log(Arrays.asList(args));
-
- try {
- res.file = args[0];
- // res.method = args[2];
- } catch (Exception e) {
- Logger.log("Incorrect syntax: java MethodResolver.class ");
- System.exit(1);
- }
-
- return res;
- }
-
- private static Optional getMethodCallWithJavaParserSymbolSolver(MethodCallExpr methodCallExpr, TypeSolver... solvers) {
- CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(solvers);
-
- SymbolReference solver = JavaParserFacade.get(combinedTypeSolver).solve(methodCallExpr);
-
- return solver.isSolved() ? solver.getCorrespondingDeclaration().toAst() : Optional.empty();
- }
-}
diff --git a/src/main/java/tfm/graphs/augmented/PPDG.java b/src/main/java/tfm/graphs/augmented/PPDG.java
deleted file mode 100644
index c864533e2a48e947e1fb45cf8c432284b26264a1..0000000000000000000000000000000000000000
--- a/src/main/java/tfm/graphs/augmented/PPDG.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package tfm.graphs.augmented;
-
-import tfm.arcs.Arc;
-import tfm.nodes.GraphNode;
-import tfm.slicing.Slice;
-import tfm.utils.ASTUtils;
-
-public class PPDG extends APDG {
- public PPDG() {
- this(new ACFG());
- }
-
- public PPDG(ACFG acfg) {
- super(acfg);
- }
-
- @Override
- protected void getSliceNodes(Slice slice, GraphNode> node) {
- slice.add(node);
-
- for (Arc arc : incomingEdgesOf(node)) {
- GraphNode> from = getEdgeSource(arc);
- if (slice.contains(from))
- continue;
- getSliceNodesPPDG(slice, from);
- }
- }
-
- protected void getSliceNodesPPDG(Slice slice, GraphNode> node) {
- slice.add(node);
- if (ASTUtils.isPseudoPredicate(node.getAstNode()))
- return;
-
- for (Arc arc : incomingEdgesOf(node)) {
- GraphNode> from = getEdgeSource(arc);
- if (slice.contains(from))
- continue;
- getSliceNodesPPDG(slice, from);
- }
- }
-}
diff --git a/src/main/java/tfm/slicing/SliceAstVisitor.java b/src/main/java/tfm/slicing/SliceAstVisitor.java
deleted file mode 100644
index 63f187c59d408a94a75f465a7be139a76996c8eb..0000000000000000000000000000000000000000
--- a/src/main/java/tfm/slicing/SliceAstVisitor.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package tfm.slicing;
-
-import com.github.javaparser.ast.Node;
-import com.github.javaparser.ast.NodeList;
-import com.github.javaparser.ast.expr.BooleanLiteralExpr;
-import com.github.javaparser.ast.nodeTypes.NodeWithBody;
-import com.github.javaparser.ast.stmt.*;
-import com.github.javaparser.ast.visitor.ModifierVisitor;
-import com.github.javaparser.ast.visitor.Visitable;
-
-import java.util.stream.Collectors;
-
-public class SliceAstVisitor extends ModifierVisitor {
- @Override
- public Visitable visit(BreakStmt n, Slice arg) {
- return arg.contains(n) ? n : null;
- }
-
- @Override
- public Visitable visit(ContinueStmt n, Slice arg) {
- return arg.contains(n) ? n : null;
- }
-
- @Override
- public Visitable visit(DoStmt n, Slice arg) {
- boolean keep = arg.contains(n);
- super.visit(n, arg);
- fillBody(n);
- return keep ? n : null;
- }
-
- @Override
- public Visitable visit(ForEachStmt n, Slice arg) {
- boolean keep = arg.contains(n);
- super.visit(n, arg);
- fillBody(n);
- return keep ? n : null;
- }
-
- @Override
- public Visitable visit(ForStmt n, Slice arg) {
- boolean keep = arg.contains(n);
- super.visit(n, arg);
- n.setInitialization(new NodeList<>(n.getInitialization().stream()
- .filter(arg::contains).collect(Collectors.toList())));
- n.setUpdate(new NodeList<>(n.getUpdate().stream()
- .filter(arg::contains).collect(Collectors.toList())));
- fillBody(n);
- if (keep)
- return n;
- if (n.getInitialization().isEmpty() && n.getUpdate().isEmpty())
- return null;
- return new ForStmt(n.getInitialization(), new BooleanLiteralExpr(false),
- n.getUpdate(), n.getBody());
- }
-
- @Override
- public Visitable visit(WhileStmt n, Slice arg) {
- boolean keep = arg.contains(n);
- super.visit(n, arg);
- fillBody(n);
- return keep ? n : null;
- }
-
- @Override
- public Visitable visit(IfStmt n, Slice arg) {
- boolean keep = arg.contains(n);
- super.visit(n, arg);
- if (n.getThenStmt() == null)
- n.setThenStmt(new EmptyStmt());
- return keep ? n : null;
- }
-
- @Override
- public Visitable visit(LabeledStmt n, Slice arg) {
- super.visit(n, arg);
- return n.getStatement() != null ? n : null;
- }
-
- @Override
- public Visitable visit(ReturnStmt n, Slice arg) {
- return arg.contains(n) ? n : null;
- }
-
- @Override
- public Visitable visit(ThrowStmt n, Slice arg) {
- return arg.contains(n) ? n : null;
- }
-
- @Override
- public Visitable visit(SwitchEntryStmt n, Slice arg) {
- boolean keep = arg.contains(n);
- super.visit(n, arg);
- if (!n.getStatements().isEmpty())
- return n;
- return keep ? n : null;
- }
-
- @Override
- public Visitable visit(SwitchStmt n, Slice arg) {
- boolean keep = arg.contains(n);
- super.visit(n, arg);
- return keep ? n : null;
- }
-
- @Override
- public Visitable visit(ExpressionStmt n, Slice arg) {
- return arg.contains(n) ? n : null;
- }
-
- private void fillBody(Node n) {
- if (!(n instanceof NodeWithBody))
- return;
- NodeWithBody> nb = ((NodeWithBody>) n);
- if (nb.getBody() == null)
- nb.setBody(new EmptyStmt());
- }
-}
diff --git a/src/main/java/tfm/utils/MethodDeclarationSolver.java b/src/main/java/tfm/utils/MethodDeclarationSolver.java
deleted file mode 100644
index b6e7ebab3061ada67e5115dab52bc4bae6afad1a..0000000000000000000000000000000000000000
--- a/src/main/java/tfm/utils/MethodDeclarationSolver.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package tfm.utils;
-
-import com.github.javaparser.ast.body.MethodDeclaration;
-import com.github.javaparser.ast.expr.MethodCallExpr;
-import com.github.javaparser.resolution.UnsolvedSymbolException;
-import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
-import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
-import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
-import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
-import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
-
-import java.util.*;
-
-public class MethodDeclarationSolver {
-
- private static final MethodDeclarationSolver instance = new MethodDeclarationSolver();
- private static final List usedTypeSolvers = new ArrayList<>();
-
- private MethodDeclarationSolver() {
-
- }
-
- public static void addTypeSolvers(TypeSolver... typeSolvers) {
- usedTypeSolvers.addAll(Arrays.asList(typeSolvers));
- }
-
- public static MethodDeclarationSolver getInstance() {
- return instance;
- }
-
- public Optional findDeclarationFrom(MethodCallExpr methodCallExpr) {
- return this.findDeclarationFrom(methodCallExpr, usedTypeSolvers);
- }
-
- public Optional findDeclarationFrom(MethodCallExpr methodCallExpr, Collection extends TypeSolver> customTypeSolvers) {
- CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(customTypeSolvers.toArray(new TypeSolver[0]));
-
- try {
- SymbolReference solver = JavaParserFacade.get(combinedTypeSolver).solve(methodCallExpr);
-
- return solver.isSolved()
- ? solver.getCorrespondingDeclaration().toAst()
- : Optional.empty();
- } catch (UnsolvedSymbolException e) {
- return Optional.empty();
- }
- }
-}