From 19cca4d6fa71a79e86d1b0d46d635ca32d841cf1 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Mon, 2 Jan 2023 12:17:47 -0500 Subject: [PATCH 1/2] update dependency to use org.json --- .../java/edu/ucr/cs/riple/core/Config.java | 48 +++++++++---------- .../edu/ucr/cs/riple/core/ModuleInfo.java | 15 +++--- .../ucr/cs/riple/core/metadata/index/Fix.java | 2 +- .../edu/ucr/cs/riple/core/util/Utility.java | 23 ++++----- gradle/dependencies.gradle | 4 +- injector/build.gradle | 1 + .../riple/injector/changes/AddAnnotation.java | 3 +- .../ucr/cs/riple/injector/changes/Change.java | 3 +- .../injector/changes/RemoveAnnotation.java | 3 +- .../cs/riple/injector/location/Location.java | 9 ++-- .../cs/riple/injector/location/OnField.java | 9 ++-- .../cs/riple/injector/location/OnMethod.java | 5 +- .../riple/injector/location/OnParameter.java | 7 ++- 13 files changed, 63 insertions(+), 69 deletions(-) diff --git a/annotator-core/src/main/java/edu/ucr/cs/riple/core/Config.java b/annotator-core/src/main/java/edu/ucr/cs/riple/core/Config.java index 076f993e1..15234eedd 100644 --- a/annotator-core/src/main/java/edu/ucr/cs/riple/core/Config.java +++ b/annotator-core/src/main/java/edu/ucr/cs/riple/core/Config.java @@ -61,9 +61,8 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; +import org.json.JSONArray; +import org.json.JSONObject; /** * Config class for Annotator. Different flags can be set with either command line arguments or an @@ -439,13 +438,11 @@ public Config(Path configPath) { Preconditions.checkNotNull(configPath); JSONObject jsonObject; try { - Object obj = - new JSONParser().parse(Files.newBufferedReader(configPath, Charset.defaultCharset())); - jsonObject = (JSONObject) obj; + jsonObject = new JSONObject(Files.readString(configPath, Charset.defaultCharset())); } catch (Exception e) { throw new RuntimeException("Error in reading/parsing config at path: " + configPath, e); } - this.depth = getValueFromKey(jsonObject, "DEPTH", Long.class).orElse((long) 1).intValue(); + this.depth = getValueFromKey(jsonObject, "DEPTH", Integer.class).orElse(1); this.chain = getValueFromKey(jsonObject, "CHAIN", Boolean.class).orElse(false); this.redirectBuildOutputToStdErr = getValueFromKey(jsonObject, "REDIRECT_BUILD_OUTPUT_TO_STDERR", Boolean.class).orElse(false); @@ -467,7 +464,7 @@ public Config(Path configPath) { getArrayValueFromKey( jsonObject, "CONFIG_PATHS", - instance -> ModuleInfo.buildFromJson(getNextModuleUniqueID(), globalDir, instance), + instance -> ModuleInfo.buildFromMap(getNextModuleUniqueID(), globalDir, instance), ModuleInfo.class) .orElse(Collections.emptyList()); this.target = moduleInfoList.get(0); @@ -586,14 +583,14 @@ private OrElse getValueFromKey(JSONObject json, String key, Class klas try { ArrayList keys = new ArrayList<>(Arrays.asList(key.split(":"))); while (keys.size() != 1) { - if (json.containsKey(keys.get(0))) { + if (json.has(keys.get(0))) { json = (JSONObject) json.get(keys.get(0)); keys.remove(0); } else { return new OrElse<>(null, klass); } } - return json.containsKey(keys.get(0)) + return json.has(keys.get(0)) ? new OrElse<>(json.get(keys.get(0)), klass) : new OrElse<>(null, klass); } catch (Exception e) { @@ -601,9 +598,9 @@ private OrElse getValueFromKey(JSONObject json, String key, Class klas } } - @SuppressWarnings({"SameParameterValue", "unchecked"}) + @SuppressWarnings("SameParameterValue") private ListOrElse getArrayValueFromKey( - JSONObject json, String key, Function mapper, Class klass) { + JSONObject json, String key, Function, T> mapper, Class klass) { if (json == null) { return new ListOrElse<>(null, klass); } @@ -612,7 +609,9 @@ private ListOrElse getArrayValueFromKey( return new ListOrElse<>(null, klass); } else { if (jsonValue.value instanceof JSONArray) { - return new ListOrElse<>(((JSONArray) jsonValue.value).stream().map(mapper), klass); + return new ListOrElse<>( + ((JSONArray) jsonValue.value).toList().stream().map(o -> mapper.apply((Map) o)), + klass); } throw new IllegalStateException( "Expected type to be json array, found: " + jsonValue.value.getClass()); @@ -681,7 +680,6 @@ public static class Builder { public Set sourceTypes = new HashSet<>(); public int depth = 1; - @SuppressWarnings("unchecked") public void write(Path path) { Preconditions.checkNotNull( buildCommand, "Build command must be initialized to construct the config."); @@ -711,16 +709,15 @@ public void write(Path path) { json.put("FORCE_RESOLVE", forceResolveActivation); json.put("INFERENCE_ACTIVATION", inferenceActivated); JSONArray configPathsJson = new JSONArray(); - configPathsJson.addAll( - configPaths.stream() - .map( - info -> { - JSONObject res = new JSONObject(); - res.put("NULLAWAY", info.nullawayConfig.toString()); - res.put("SCANNER", info.scannerConfig.toString()); - return res; - }) - .collect(Collectors.toList())); + configPaths.stream() + .map( + info -> { + JSONObject res = new JSONObject(); + res.put("NULLAWAY", info.nullawayConfig.toString()); + res.put("SCANNER", info.scannerConfig.toString()); + return res; + }) + .forEach(configPathsJson::put); json.put("CONFIG_PATHS", configPathsJson); JSONObject downstreamDependency = new JSONObject(); downstreamDependency.put("ACTIVATION", downStreamDependenciesAnalysisActivated); @@ -747,10 +744,9 @@ public void write(Path path) { processors.put(sourceType.name(), st); }); json.put("PROCESSORS", processors); - try (BufferedWriter file = Files.newBufferedWriter(path.toFile().toPath(), Charset.defaultCharset())) { - file.write(json.toJSONString()); + json.write(file); } catch (IOException e) { System.err.println("Error happened in writing config json: " + e); } diff --git a/annotator-core/src/main/java/edu/ucr/cs/riple/core/ModuleInfo.java b/annotator-core/src/main/java/edu/ucr/cs/riple/core/ModuleInfo.java index b70168e60..e5cbe35d8 100644 --- a/annotator-core/src/main/java/edu/ucr/cs/riple/core/ModuleInfo.java +++ b/annotator-core/src/main/java/edu/ucr/cs/riple/core/ModuleInfo.java @@ -28,8 +28,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Map; import java.util.Objects; -import org.json.simple.JSONObject; /** Container class to hold paths to nullaway and scanner config files. */ public class ModuleInfo { @@ -41,16 +41,19 @@ public class ModuleInfo { public final Path dir; /** - * Creates an instance of {@link ModuleInfo} from the given json object. + * Creates an instance of {@link ModuleInfo} from the given map object. This method is used in + * constructing {@link ModuleInfo} instances from a JSON object. Please note that array of + * dictionaries in json are parsed to {@link org.json.JSONArray} of maps. This method is called on + * each dictionary stored in the parsed collection to create the corresponding instance. * * @param id Global unique id for this module. * @param globalDir Global path for all Annotator/Scanner/NullAway outputs. - * @param jsonObject Json Object to retrieve values. + * @param mapFromJSON Map Object to retrieve require values. * @return An instance of {@link ModuleInfo}. */ - public static ModuleInfo buildFromJson(int id, Path globalDir, JSONObject jsonObject) { - String nullawayConfigPath = (String) jsonObject.get("NULLAWAY"); - String scannerConfigPath = (String) jsonObject.get("SCANNER"); + public static ModuleInfo buildFromMap(int id, Path globalDir, Map mapFromJSON) { + String nullawayConfigPath = (String) mapFromJSON.get("NULLAWAY"); + String scannerConfigPath = (String) mapFromJSON.get("SCANNER"); if (nullawayConfigPath == null || scannerConfigPath == null) { throw new IllegalArgumentException( "Both paths to NullAway and Scanner config files must be set with NULLAWAY and SCANNER keys!"); diff --git a/annotator-core/src/main/java/edu/ucr/cs/riple/core/metadata/index/Fix.java b/annotator-core/src/main/java/edu/ucr/cs/riple/core/metadata/index/Fix.java index ce0fc40bd..7d7d6025d 100644 --- a/annotator-core/src/main/java/edu/ucr/cs/riple/core/metadata/index/Fix.java +++ b/annotator-core/src/main/java/edu/ucr/cs/riple/core/metadata/index/Fix.java @@ -40,7 +40,7 @@ import java.util.Objects; import java.util.Set; import java.util.function.Consumer; -import org.json.simple.JSONObject; +import org.json.JSONObject; /** * Stores information suggesting adding @Nullable on an element in source code. These suggestions diff --git a/annotator-core/src/main/java/edu/ucr/cs/riple/core/util/Utility.java b/annotator-core/src/main/java/edu/ucr/cs/riple/core/util/Utility.java index 5de00f686..f05656b5c 100644 --- a/annotator-core/src/main/java/edu/ucr/cs/riple/core/util/Utility.java +++ b/annotator-core/src/main/java/edu/ucr/cs/riple/core/util/Utility.java @@ -44,6 +44,7 @@ import java.nio.file.Path; import java.time.Duration; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -62,8 +63,8 @@ import javax.xml.transform.stream.StreamResult; import me.tongfei.progressbar.ProgressBar; import me.tongfei.progressbar.ProgressBarStyle; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; +import org.json.JSONArray; +import org.json.JSONObject; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -100,11 +101,10 @@ public static void executeCommand(Config config, String command) { * @param config Annotator config. * @param reports Immutable set of reports. */ - @SuppressWarnings("unchecked") public static void writeReports(Config config, ImmutableSet reports) { Path reportsPath = config.globalDir.resolve("reports.json"); JSONObject result = new JSONObject(); - JSONArray reportsJson = new JSONArray(); + List reportsList = new ArrayList<>(); for (Report report : reports) { JSONObject reportJson = report.root.getJson(); reportJson.put("LOCAL EFFECT", report.localEffect); @@ -115,23 +115,24 @@ public static void writeReports(Config config, ImmutableSet reports) { JSONArray followUps = new JSONArray(); if (config.chain && report.localEffect < 1) { report.tree.remove(report.root); - followUps.addAll(report.tree.stream().map(Fix::getJson).collect(Collectors.toList())); + report.tree.stream().map(Fix::getJson).forEach(followUps::put); } reportJson.put("TREE", followUps); - reportsJson.add(reportJson); + reportsList.add(reportJson); } // Sort by overall effect. - reportsJson.sort( + reportsList.sort( (o1, o2) -> { - int first = (Integer) ((JSONObject) o1).get("OVERALL EFFECT"); - int second = (Integer) ((JSONObject) o2).get("OVERALL EFFECT"); + int first = (Integer) o1.get("OVERALL EFFECT"); + int second = (Integer) o2.get("OVERALL EFFECT"); return Integer.compare(second, first); }); + JSONArray reportsJson = new JSONArray(); + reportsList.forEach(reportsJson::put); result.put("REPORTS", reportsJson); try (BufferedWriter writer = Files.newBufferedWriter(reportsPath.toFile().toPath(), Charset.defaultCharset())) { - writer.write(result.toJSONString().replace("\\/", "/").replace("\\\\\\", "\\")); - writer.flush(); + result.write(writer); } catch (IOException e) { throw new RuntimeException( "Could not create the Annotator report json file: " + reportsPath, e); diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 207874cff..e4002df31 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -36,7 +36,7 @@ def versions = [ errorProneApi : project.hasProperty("epApiVersion") ? epApiVersion : oldestErrorProneApi, autoService : "1.0-rc7", javaparser : "3.24.0", - json : "1.1.1", + json : "20220924", guava : "31.0.1-jre", cli : "1.5.0", commonsio : "2.11.0", @@ -52,7 +52,7 @@ def apt = [ def build = [ guava : "com.google.guava:guava:${versions.guava}", - json : "com.googlecode.json-simple:json-simple:${versions.json}", + json : "org.json:json:${versions.json}", progressbar : "me.tongfei:progressbar:${versions.progressbar}", javaparser : "com.github.javaparser:javaparser-core:${versions.javaparser}", commonscli : "commons-cli:commons-cli:${versions.cli}", diff --git a/injector/build.gradle b/injector/build.gradle index 24378e1ee..438964f48 100644 --- a/injector/build.gradle +++ b/injector/build.gradle @@ -37,6 +37,7 @@ dependencies { implementation deps.build.progressbar testImplementation deps.build.commonsio + testImplementation 'junit:junit:4.13.1' } compileJava.mustRunAfter verifyGoogleJavaFormat diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/AddAnnotation.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/AddAnnotation.java index 4c28e720b..c15e8ab28 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/AddAnnotation.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/AddAnnotation.java @@ -24,7 +24,7 @@ import edu.ucr.cs.riple.injector.location.Location; import java.util.Objects; -import org.json.simple.JSONObject; +import org.json.JSONObject; /** Used to add annotations on elements in source code. */ public abstract class AddAnnotation extends Change { @@ -34,7 +34,6 @@ public AddAnnotation(Location location, String annotation) { } @Override - @SuppressWarnings("unchecked") public JSONObject getJson() { JSONObject res = super.getJson(); res.put("INJECT", true); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java index d7a9d5b0c..1342a6e94 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/Change.java @@ -30,7 +30,7 @@ import edu.ucr.cs.riple.injector.modifications.Modification; import java.util.Objects; import javax.annotation.Nullable; -import org.json.simple.JSONObject; +import org.json.JSONObject; /** Represents a change in the AST of the source code. */ public abstract class Change { @@ -86,7 +86,6 @@ public int hashCode() { return Objects.hash(location, annotation); } - @SuppressWarnings("unchecked") public JSONObject getJson() { JSONObject res = new JSONObject(); res.put("LOCATION", location.getJson()); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/RemoveAnnotation.java b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/RemoveAnnotation.java index cbb70379a..d17220928 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/changes/RemoveAnnotation.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/changes/RemoveAnnotation.java @@ -32,7 +32,7 @@ import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; -import org.json.simple.JSONObject; +import org.json.JSONObject; /** * Used to remove node, Range range) { } @Override - @SuppressWarnings("unchecked") public JSONObject getJson() { JSONObject res = super.getJson(); res.put("INJECT", false); diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java index dd5f312d6..d10840a4a 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/Location.java @@ -37,7 +37,7 @@ import java.util.Objects; import java.util.function.Consumer; import javax.annotation.Nullable; -import org.json.simple.JSONObject; +import org.json.JSONObject; public abstract class Location { public final LocationType type; @@ -126,12 +126,11 @@ public Modification apply(CompilationUnit tree, Change change) { return applyToMember(clazz, change); } - @SuppressWarnings("unchecked") public JSONObject getJson() { JSONObject res = new JSONObject(); - res.put(KEYS.CLASS, clazz); - res.put(KEYS.KIND, type.toString()); - res.put(KEYS.PATH, path); + res.put(KEYS.CLASS.toString(), clazz); + res.put(KEYS.KIND.toString(), type.toString()); + res.put(KEYS.PATH.toString(), path); fillJsonInformation(res); return res; } diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java index e6a344e64..e92f03d36 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnField.java @@ -36,8 +36,8 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; +import org.json.JSONArray; +import org.json.JSONObject; public class OnField extends Location { /** @@ -59,12 +59,11 @@ public OnField(String path, String clazz, Set variables) { this.variables = variables; } - @SuppressWarnings("unchecked") @Override protected void fillJsonInformation(JSONObject res) { JSONArray fields = new JSONArray(); - fields.addAll(variables); - res.put(KEYS.VARIABLES, fields); + variables.forEach(fields::put); + res.put(KEYS.VARIABLES.toString(), fields); } @Override diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java index 9b42d7f30..9fbf7788b 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnMethod.java @@ -35,7 +35,7 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import org.json.simple.JSONObject; +import org.json.JSONObject; public class OnMethod extends Location { public final String method; @@ -47,10 +47,9 @@ public OnMethod(String path, String clazz, String method) { this.matcher = new SignatureMatcher(method); } - @SuppressWarnings("unchecked") @Override protected void fillJsonInformation(JSONObject res) { - res.put(KEYS.METHOD, method); + res.put(KEYS.METHOD.toString(), method); } @Override diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java index 8ae52ce9a..5e422488f 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnParameter.java @@ -37,7 +37,7 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import org.json.simple.JSONObject; +import org.json.JSONObject; public class OnParameter extends Location { public final String method; @@ -51,11 +51,10 @@ public OnParameter(String path, String clazz, String method, int index) { this.matcher = new SignatureMatcher(method); } - @SuppressWarnings("unchecked") @Override protected void fillJsonInformation(JSONObject res) { - res.put(KEYS.METHOD, method); - res.put(KEYS.INDEX, index); + res.put(KEYS.METHOD.toString(), method); + res.put(KEYS.INDEX.toString(), index); } @Override From 1a2c213d02cc0543278e77d712bd37715eabfea0 Mon Sep 17 00:00:00 2001 From: nimakarimipour Date: Sun, 12 Mar 2023 16:24:17 -0500 Subject: [PATCH 2/2] update --- .../edu/ucr/cs/riple/injector/location/OnClass.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java index 6fa53741b..347143a40 100644 --- a/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java +++ b/injector/src/main/java/edu/ucr/cs/riple/injector/location/OnClass.java @@ -35,7 +35,7 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Pattern; -import org.json.simple.JSONObject; +import org.json.JSONObject; public class OnClass extends Location { @@ -67,6 +67,9 @@ protected Modification applyToMember(NodeList> declarations, return ans.get(); } + @Override + protected void fillJsonInformation(JSONObject res) {} + /** * Checks if flat name is for an anonymous class. * @@ -76,11 +79,6 @@ public static boolean isAnonymousClassFlatName(String flatName) { return anonymousClassPattern.matcher(flatName).matches(); } - @Override - protected void fillJsonInformation(JSONObject res) { - // no op - } - @Override public String toString() { return "OnClass{" + "type=" + type + ", clazz='" + clazz + '\'' + ", path=" + path + '}';