Skip to content

Commit b38d6dc

Browse files
authored
Merge pull request #45 from IBM/add-private-method-info-to-callsite-object
Add callee method's access specifier information to caller's callsite object
2 parents c13ae69 + 2691303 commit b38d6dc

File tree

3 files changed

+77
-20
lines changed

3 files changed

+77
-20
lines changed

src/main/java/com/ibm/northstar/SymbolTable.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.github.javaparser.ParseResult;
55
import com.github.javaparser.ParserConfiguration;
66
import com.github.javaparser.Problem;
7+
import com.github.javaparser.ast.AccessSpecifier;
78
import com.github.javaparser.ast.CompilationUnit;
89
import com.github.javaparser.ast.NodeList;
910
import com.github.javaparser.ast.body.*;
@@ -12,6 +13,7 @@
1213
import com.github.javaparser.ast.stmt.BlockStmt;
1314
import com.github.javaparser.ast.type.ReferenceType;
1415
import com.github.javaparser.ast.type.Type;
16+
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
1517
import com.github.javaparser.resolution.types.ResolvedType;
1618
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
1719
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
@@ -498,12 +500,21 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
498500
Log.debug("Could not resolve method call: " + methodCallExpr + ": " + exception.getMessage());
499501
}
500502

503+
// Resolve access qualifier
504+
AccessSpecifier accessSpecifier = AccessSpecifier.NONE;
505+
try {
506+
ResolvedMethodDeclaration resolvedMethodDeclaration = methodCallExpr.resolve();
507+
accessSpecifier = resolvedMethodDeclaration.accessSpecifier();
508+
}
509+
catch (RuntimeException exception) {
510+
Log.debug("Could not resolve access specifier for method call: " + methodCallExpr + ": " + exception.getMessage());
511+
}
501512
// resolve arguments of the method call to types
502513
List<String> arguments = methodCallExpr.getArguments().stream()
503514
.map(SymbolTable::resolveExpression).collect(Collectors.toList());
504515
// add a new call site object
505516
callSites.add(createCallSite(methodCallExpr, methodCallExpr.getNameAsString(), receiverName, declaringType,
506-
arguments, returnType, calleeSignature, isStaticCall, false));
517+
arguments, returnType, calleeSignature, isStaticCall, false, accessSpecifier));
507518
}
508519

509520
for (ObjectCreationExpr objectCreationExpr : callableBody.get().findAll(ObjectCreationExpr.class)) {
@@ -525,7 +536,7 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
525536
// add a new call site object
526537
callSites.add(createCallSite(objectCreationExpr, "<init>",
527538
objectCreationExpr.getScope().isPresent() ? objectCreationExpr.getScope().get().toString() : "",
528-
instantiatedType, arguments, instantiatedType, calleeSignature,false, true));
539+
instantiatedType, arguments, instantiatedType, calleeSignature,false, true, AccessSpecifier.NONE));
529540
}
530541

531542
return callSites;
@@ -546,7 +557,7 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
546557
*/
547558
private static CallSite createCallSite(Expression callExpr, String calleeName, String receiverExpr,
548559
String receiverType, List<String> arguments, String returnType,
549-
String calleeSignature, boolean isStaticCall, boolean isConstructorCall) {
560+
String calleeSignature, boolean isStaticCall, boolean isConstructorCall, AccessSpecifier accessSpecifier) {
550561
CallSite callSite = new CallSite();
551562
callSite.setMethodName(calleeName);
552563
callSite.setReceiverExpr(receiverExpr);
@@ -556,6 +567,10 @@ private static CallSite createCallSite(Expression callExpr, String calleeName, S
556567
callSite.setCalleeSignature(calleeSignature);
557568
callSite.setStaticCall(isStaticCall);
558569
callSite.setConstructorCall(isConstructorCall);
570+
callSite.setPrivate(accessSpecifier.equals(AccessSpecifier.PRIVATE));
571+
callSite.setPublic(accessSpecifier.equals(AccessSpecifier.PUBLIC));
572+
callSite.setProtected(accessSpecifier.equals(AccessSpecifier.PROTECTED));
573+
callSite.setUnspecified(accessSpecifier.equals(AccessSpecifier.NONE));
559574
if (callExpr.getRange().isPresent()) {
560575
callSite.setStartLine(callExpr.getRange().get().begin.line);
561576
callSite.setStartColumn(callExpr.getRange().get().begin.column);

src/main/java/com/ibm/northstar/entities/CallSite.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ public class CallSite {
1212
private List<String> argumentTypes;
1313
private String returnType;
1414
private String calleeSignature;
15+
// Access specifiers
16+
private boolean isPublic = false;
17+
private boolean isProtected = false;
18+
private boolean isPrivate = false;
19+
private boolean isUnspecified = false;
1520
private boolean isStaticCall;
1621
private boolean isConstructorCall;
1722
private int startLine;

src/main/java/com/ibm/northstar/utils/BuildProject.java

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.nio.file.Files;
88
import java.nio.file.Path;
99
import java.nio.file.Paths;
10+
import java.util.Arrays;
1011
import java.util.List;
1112

1213
import static com.ibm.northstar.utils.ProjectDirectoryScanner.classFilesStream;
@@ -17,6 +18,31 @@ public class BuildProject {
1718
private static final String LIB_DEPS_DOWNLOAD_DIR = "_library_dependencies";
1819
private static final String MAVEN_CMD = System.getProperty("os.name").toLowerCase().contains("windows") ? "mvn.cmd" : "mvn";
1920
private static final String GRADLE_CMD = System.getProperty("os.name").toLowerCase().contains("windows") ? "gradlew.bat" : "gradlew";
21+
public static Path tempInitScript;
22+
static {
23+
try {
24+
tempInitScript = Files.createTempFile("gradle-init-", ".gradle");
25+
} catch (IOException e) {
26+
throw new RuntimeException(e);
27+
}
28+
}
29+
private static final String GRADLE_DEPENDENCIES_TASK = "allprojects { afterEvaluate { project -> task downloadDependencies(type: Copy) {\n" +
30+
" def configs = project.configurations.findAll { it.canBeResolved }\n\n" +
31+
" dependsOn configs\n" +
32+
" from configs\n" +
33+
" into project.hasProperty('outputDir') ? project.property('outputDir') : \"${project.buildDir}/libs\"\n\n" +
34+
" doFirst {\n" +
35+
" println \"Downloading dependencies for project ${project.name} to: ${destinationDir}\"\n" +
36+
" configs.each { config ->\n" +
37+
" println \"Configuration: ${config.name}\"\n" +
38+
" config.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n" +
39+
" println \"\t${artifact.moduleVersion.id}:${artifact.extension}\"\n" +
40+
" }\n" +
41+
" }\n" +
42+
" }\n" +
43+
" }\n" +
44+
" }\n" +
45+
"}";
2046

2147
private static boolean buildWithTool(String[] buildCommand) {
2248
Log.info("Building the project using " + buildCommand[0] + ".");
@@ -30,6 +56,7 @@ private static boolean buildWithTool(String[] buildCommand) {
3056
Log.info(line);
3157
}
3258
int exitCode = process.waitFor();
59+
process.getErrorStream().transferTo(System.err);
3360
Log.info(buildCommand[0].toUpperCase() + " build exited with code " + exitCode);
3461
return exitCode == 0;
3562
} catch (IOException | InterruptedException e) {
@@ -73,24 +100,24 @@ private static boolean mavenBuild(String projectPath) {
73100
return false;
74101
}
75102
String[] mavenCommand = {
76-
MAVEN_CMD, "clean", "compile", "-f", projectPath + "/pom.xml", "-B", "-V", "-e", "-Drat.skip",
77-
"-Dfindbugs.skip", "-Dcheckstyle.skip", "-Dpmd.skip=true", "-Dspotbugs.skip", "-Denforcer.skip",
78-
"-Dmaven.javadoc.skip", "-DskipTests", "-Dmaven.test.skip.exec", "-Dlicense.skip=true",
79-
"-Drat.skip=true", "-Dspotless.check.skip=true" };
103+
MAVEN_CMD, "clean", "compile", "-f", projectPath + "/pom.xml", "-B", "-V", "-e", "-Drat.skip",
104+
"-Dfindbugs.skip", "-Dcheckstyle.skip", "-Dpmd.skip=true", "-Dspotbugs.skip", "-Denforcer.skip",
105+
"-Dmaven.javadoc.skip", "-DskipTests", "-Dmaven.test.skip.exec", "-Dlicense.skip=true",
106+
"-Drat.skip=true", "-Dspotless.check.skip=true"};
80107

81108
return buildWithTool(mavenCommand);
82109
}
83110

84111
public static boolean gradleBuild(String projectPath) {
85112
// Adjust Gradle command as needed
86113
String gradleWrapper = projectPath + File.separator + GRADLE_CMD;
87-
String[] gradleCommand = { gradleWrapper, "clean", "compileJava", "-p", projectPath };
114+
String[] gradleCommand = {gradleWrapper, "clean", "compileJava", "-p", projectPath};
88115
return buildWithTool(gradleCommand);
89116
}
90117

91118
private static boolean buildProject(String projectPath, String build) {
92119
File pomFile = new File(projectPath, "pom.xml");
93-
if (build ==null) {
120+
if (build == null) {
94121
return true;
95122
} else if (build.equals("auto")) {
96123
if (pomFile.exists()) {
@@ -100,8 +127,7 @@ private static boolean buildProject(String projectPath, String build) {
100127
Log.info("Did not find a pom.xml in the project directory. Using Gradle to build the project.");
101128
return gradleBuild(projectPath); // Otherwise, use Gradle
102129
}
103-
}
104-
else {
130+
} else {
105131
// Update command with a project path
106132
build = build.replace(MAVEN_CMD, MAVEN_CMD + " -f " + projectPath);
107133
Log.info("Using custom build command: " + build);
@@ -127,31 +153,35 @@ public static List<Path> buildProjectAndStreamClassFiles(String projectPath, Str
127153
* @param projectPath Path to the project under analysis
128154
* @return true if dependency download succeeds; false otherwise
129155
*/
130-
public static boolean downloadLibraryDependencies(String projectPath) {
156+
public static boolean downloadLibraryDependencies(String projectPath) throws IOException {
131157
// created download dir if it does not exist
132158
libDownloadPath = Paths.get(projectPath, LIB_DEPS_DOWNLOAD_DIR).toAbsolutePath();
133159
if (!Files.exists(libDownloadPath)) {
134160
try {
135161
Files.createDirectory(libDownloadPath);
136162
} catch (IOException e) {
137-
Log.error("Error creating library dependency directory for " + projectPath + ": " +e.getMessage());
163+
Log.error("Error creating library dependency directory for " + projectPath + ": " + e.getMessage());
138164
return false;
139165
}
140166
}
141167
File pomFile = new File(projectPath, "pom.xml");
142168
if (pomFile.exists()) {
143169
Log.info("Found pom.xml in the project directory. Using Maven to download dependencies.");
144170
String[] mavenCommand = {
145-
MAVEN_CMD, "--no-transfer-progress", "-f",
146-
Paths.get(projectPath, "pom.xml").toString(),
147-
"dependency:copy-dependencies",
148-
"-DoutputDirectory=" + libDownloadPath.toString()
171+
MAVEN_CMD, "--no-transfer-progress", "-f",
172+
Paths.get(projectPath, "pom.xml").toString(),
173+
"dependency:copy-dependencies",
174+
"-DoutputDirectory=" + libDownloadPath.toString()
149175
};
150176
return buildWithTool(mavenCommand);
151-
} else {
152-
// TODO: implement for gradle
153-
return false;
177+
} else if (new File(projectPath, "build.gradle").exists() || new File(projectPath, "build.gradle.kts").exists()) {
178+
Log.info("Found build.gradle[.kts] in the project directory. Using Gradle to download dependencies.");
179+
tempInitScript = Files.writeString(tempInitScript, GRADLE_DEPENDENCIES_TASK);
180+
String[] gradleCommand = {projectPath + File.separator + GRADLE_CMD, "--init-script", tempInitScript.toFile().getAbsolutePath(), "downloadDependencies", "-PoutputDir="+libDownloadPath.toString()};
181+
System.out.println(Arrays.toString(gradleCommand));
182+
return buildWithTool(gradleCommand);
154183
}
184+
return false;
155185
}
156186

157187
public static void cleanLibraryDependencies() {
@@ -167,5 +197,12 @@ public static void cleanLibraryDependencies() {
167197
Log.error("Error deleting library dependency directory: " + e.getMessage());
168198
}
169199
}
200+
if (tempInitScript != null) {
201+
try {
202+
Files.delete(tempInitScript);
203+
} catch (IOException e) {
204+
Log.error("Error deleting temporary Gradle init script: " + e.getMessage());
205+
}
206+
}
170207
}
171208
}

0 commit comments

Comments
 (0)