Skip to content

Commit 9f13a5d

Browse files
extract the parser as a separate class
1 parent c695c24 commit 9f13a5d

File tree

3 files changed

+245
-115
lines changed

3 files changed

+245
-115
lines changed

annotator-core/src/main/java/edu/ucr/cs/riple/core/Config.java

Lines changed: 39 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@
2929
import com.google.common.collect.ImmutableSet;
3030
import com.google.common.collect.Sets;
3131
import com.google.gson.JsonArray;
32-
import com.google.gson.JsonElement;
33-
import com.google.gson.JsonNull;
3432
import com.google.gson.JsonObject;
35-
import com.google.gson.JsonPrimitive;
3633
import edu.ucr.cs.riple.core.module.ModuleConfiguration;
34+
import edu.ucr.cs.riple.core.util.JsonParser;
3735
import edu.ucr.cs.riple.core.util.Utility;
3836
import edu.ucr.cs.riple.scanner.generatedcode.SourceType;
3937
import java.io.BufferedWriter;
@@ -42,16 +40,11 @@
4240
import java.nio.file.Files;
4341
import java.nio.file.Path;
4442
import java.nio.file.Paths;
45-
import java.util.ArrayList;
46-
import java.util.Arrays;
4743
import java.util.Collections;
4844
import java.util.HashSet;
4945
import java.util.List;
5046
import java.util.Set;
51-
import java.util.function.Function;
5247
import java.util.stream.Collectors;
53-
import java.util.stream.Stream;
54-
import java.util.stream.StreamSupport;
5548
import org.apache.commons.cli.CommandLine;
5649
import org.apache.commons.cli.CommandLineParser;
5750
import org.apache.commons.cli.DefaultParser;
@@ -521,51 +514,54 @@ private ParserConfiguration.LanguageLevel getLanguageLevel(String languageLevelS
521514
*/
522515
public Config(Path configPath) {
523516
Preconditions.checkNotNull(configPath);
524-
JsonObject jsonObject = Utility.parseJson(configPath);
525-
this.checkerName = getValueFromKey(jsonObject, "CHECKER").orElse(null).getAsString();
526-
this.depth = getValueFromKey(jsonObject, "DEPTH").orElse(5).getAsInt();
527-
this.chain = getValueFromKey(jsonObject, "CHAIN").orElse(false).getAsBoolean();
517+
JsonParser parser = new JsonParser(configPath);
518+
this.checkerName = parser.getValueFromKey("CHECKER").orElse(null).getAsString();
519+
this.depth = parser.getValueFromKey("DEPTH").orElse(5).getAsInt();
520+
this.chain = parser.getValueFromKey("CHAIN").orElse(false).getAsBoolean();
528521
this.redirectBuildOutputToStdErr =
529-
getValueFromKey(jsonObject, "REDIRECT_BUILD_OUTPUT_TO_STDERR").orElse(false).getAsBoolean();
530-
this.useCache = getValueFromKey(jsonObject, "CACHE").orElse(true).getAsBoolean();
522+
parser.getValueFromKey("REDIRECT_BUILD_OUTPUT_TO_STDERR").orElse(false).getAsBoolean();
523+
this.useCache = parser.getValueFromKey("CACHE").orElse(true).getAsBoolean();
531524
this.useParallelGraphProcessor =
532-
getValueFromKey(jsonObject, "PARALLEL_PROCESSING").orElse(true).getAsBoolean();
525+
parser.getValueFromKey("PARALLEL_PROCESSING").orElse(true).getAsBoolean();
533526
this.useImpactCache =
534-
getValueFromKey(jsonObject, "CACHE_IMPACT_ACTIVATION").orElse(false).getAsBoolean();
535-
this.exhaustiveSearch =
536-
getValueFromKey(jsonObject, "EXHAUSTIVE_SEARCH").orElse(true).getAsBoolean();
537-
this.disableOuterLoop = !getValueFromKey(jsonObject, "OUTER_LOOP").orElse(false).getAsBoolean();
538-
this.bailout = getValueFromKey(jsonObject, "BAILOUT").orElse(true).getAsBoolean();
527+
parser.getValueFromKey("CACHE_IMPACT_ACTIVATION").orElse(false).getAsBoolean();
528+
this.exhaustiveSearch = parser.getValueFromKey("EXHAUSTIVE_SEARCH").orElse(true).getAsBoolean();
529+
this.disableOuterLoop = !parser.getValueFromKey("OUTER_LOOP").orElse(false).getAsBoolean();
530+
this.bailout = parser.getValueFromKey("BAILOUT").orElse(true).getAsBoolean();
539531
this.nullableAnnot =
540-
getValueFromKey(jsonObject, "ANNOTATION:NULLABLE")
532+
parser
533+
.getValueFromKey("ANNOTATION:NULLABLE")
541534
.orElse("javax.annotation.Nullable")
542535
.getAsString();
543536
this.initializerAnnot =
544-
getValueFromKey(jsonObject, "ANNOTATION:INITIALIZER")
537+
parser
538+
.getValueFromKey("ANNOTATION:INITIALIZER")
545539
.orElse("com.uber.nullaway.annotations.Initializer")
546540
.getAsString();
547-
this.globalDir =
548-
Paths.get(getValueFromKey(jsonObject, "OUTPUT_DIR").orElse(null).getAsString());
541+
this.globalDir = Paths.get(parser.getValueFromKey("OUTPUT_DIR").orElse(null).getAsString());
549542
List<ModuleConfiguration> moduleConfigurationList =
550-
getArrayValueFromKey(
551-
jsonObject,
543+
parser
544+
.getArrayValueFromKey(
552545
"CONFIG_PATHS",
553546
moduleInfo ->
554547
ModuleConfiguration.buildFromJson(
555548
getNextModuleUniqueID(), globalDir, moduleInfo))
556549
.orElse(Collections.emptyList());
557550
this.target = moduleConfigurationList.get(0);
558-
this.buildCommand = getValueFromKey(jsonObject, "BUILD_COMMAND").orElse(null).getAsString();
551+
this.buildCommand = parser.getValueFromKey("BUILD_COMMAND").orElse(null).getAsString();
559552
this.downStreamDependenciesAnalysisActivated =
560-
getValueFromKey(jsonObject, "DOWNSTREAM_DEPENDENCY_ANALYSIS:ACTIVATION")
553+
parser
554+
.getValueFromKey("DOWNSTREAM_DEPENDENCY_ANALYSIS:ACTIVATION")
561555
.orElse(false)
562556
.getAsBoolean();
563557
this.downstreamDependenciesBuildCommand =
564-
getValueFromKey(jsonObject, "DOWNSTREAM_DEPENDENCY_ANALYSIS:BUILD_COMMAND")
558+
parser
559+
.getValueFromKey("DOWNSTREAM_DEPENDENCY_ANALYSIS:BUILD_COMMAND")
565560
.orElse(null)
566561
.getAsString();
567562
String nullawayLibraryModelLoaderPathString =
568-
getValueFromKey(jsonObject, "DOWNSTREAM_DEPENDENCY_ANALYSIS:LIBRARY_MODEL_LOADER_PATH")
563+
parser
564+
.getValueFromKey("DOWNSTREAM_DEPENDENCY_ANALYSIS:LIBRARY_MODEL_LOADER_PATH")
569565
.orElse(null)
570566
.getAsString();
571567
this.nullawayLibraryModelLoaderPath =
@@ -576,32 +572,35 @@ public Config(Path configPath) {
576572
this.mode =
577573
AnalysisMode.parseMode(
578574
this.downStreamDependenciesAnalysisActivated,
579-
getValueFromKey(jsonObject, "DOWNSTREAM_DEPENDENCY_ANALYSIS:ANALYSIS_MODE")
575+
parser
576+
.getValueFromKey("DOWNSTREAM_DEPENDENCY_ANALYSIS:ANALYSIS_MODE")
580577
.orElse("default")
581578
.getAsString());
582-
583579
this.downstreamConfigurations = ImmutableSet.copyOf(moduleConfigurationList);
584580
this.moduleCounterID = 0;
585581
this.suppressRemainingErrors =
586-
getValueFromKey(jsonObject, "SUPPRESS_REMAINING_ERRORS").orElse(false).getAsBoolean();
582+
parser.getValueFromKey("SUPPRESS_REMAINING_ERRORS").orElse(false).getAsBoolean();
587583
this.inferenceActivated =
588-
getValueFromKey(jsonObject, "INFERENCE_ACTIVATION").orElse(true).getAsBoolean();
584+
parser.getValueFromKey("INFERENCE_ACTIVATION").orElse(true).getAsBoolean();
589585
this.nullUnMarkedAnnotation =
590-
getValueFromKey(jsonObject, "ANNOTATION:NULL_UNMARKED")
586+
parser
587+
.getValueFromKey("ANNOTATION:NULL_UNMARKED")
591588
.orElse("org.jspecify.annotations.NullUnmarked")
592589
.getAsString();
593590
boolean lombokCodeDetectorActivated =
594-
getValueFromKey(jsonObject, "PROCESSORS:" + SourceType.LOMBOK.name() + ":ACTIVATION")
591+
parser
592+
.getValueFromKey("PROCESSORS:" + SourceType.LOMBOK.name() + ":ACTIVATION")
595593
.orElse(true)
596594
.getAsBoolean();
597595
this.generatedCodeDetectors =
598596
lombokCodeDetectorActivated ? Sets.immutableEnumSet(SourceType.LOMBOK) : ImmutableSet.of();
599597
this.languageLevel =
600-
getLanguageLevel(getValueFromKey(jsonObject, "LANGUAGE_LEVEL").orElse("17").getAsString());
598+
getLanguageLevel(parser.getValueFromKey("LANGUAGE_LEVEL").orElse("17").getAsString());
601599
this.nonnullAnnotations =
602600
ImmutableSet.copyOf(
603-
getArrayValueFromKey(
604-
jsonObject, "ANNOTATION:NONNULL", json -> json.get("NONNULL").getAsString())
601+
parser
602+
.getArrayValueFromKey(
603+
"ANNOTATION:NONNULL", json -> json.get("NONNULL").getAsString())
605604
.orElse(List.of()));
606605
}
607606

@@ -628,78 +627,7 @@ private static void showHelp(HelpFormatter formatter, Options options) {
628627
formatter.printHelp("Annotator context Flags", options);
629628
}
630629

631-
private OrElse getValueFromKey(JsonObject json, String key) {
632-
if (json == null) {
633-
return new OrElse(JsonNull.INSTANCE);
634-
}
635-
try {
636-
ArrayList<String> keys = new ArrayList<>(Arrays.asList(key.split(":")));
637-
while (keys.size() != 1) {
638-
if (json.keySet().contains(keys.get(0))) {
639-
json = (JsonObject) json.get(keys.get(0));
640-
keys.remove(0);
641-
} else {
642-
return new OrElse(JsonNull.INSTANCE);
643-
}
644-
}
645-
return json.keySet().contains(keys.get(0))
646-
? new OrElse(json.get(keys.get(0)))
647-
: new OrElse(JsonNull.INSTANCE);
648-
} catch (Exception e) {
649-
return new OrElse(JsonNull.INSTANCE);
650-
}
651-
}
652-
653-
private <T> ListOrElse<T> getArrayValueFromKey(
654-
JsonObject json, String key, Function<JsonObject, T> mapper) {
655-
if (json == null) {
656-
return new ListOrElse<>(Stream.of());
657-
}
658-
OrElse jsonValue = getValueFromKey(json, key);
659-
if (jsonValue.value.equals(JsonNull.INSTANCE)) {
660-
return new ListOrElse<>(Stream.of());
661-
} else {
662-
if (jsonValue.value instanceof JsonArray) {
663-
return new ListOrElse<>(
664-
StreamSupport.stream(((JsonArray) jsonValue.value).spliterator(), false)
665-
.map(jsonElement -> mapper.apply(jsonElement.getAsJsonObject())));
666-
}
667-
throw new IllegalStateException(
668-
"Expected type to be json array, found: " + jsonValue.value.getClass());
669-
}
670-
}
671-
672-
private static class OrElse {
673-
674-
private final JsonElement value;
675-
676-
OrElse(JsonElement value) {
677-
this.value = value;
678-
}
679-
680-
JsonPrimitive orElse(Object other) {
681-
return value.equals(JsonNull.INSTANCE)
682-
? new JsonPrimitive(String.valueOf(other))
683-
: value.getAsJsonPrimitive();
684-
}
685-
}
686-
687-
private static class ListOrElse<T> {
688-
private final Stream<T> value;
689-
690-
ListOrElse(Stream<T> value) {
691-
this.value = value;
692-
}
693-
694-
List<T> orElse(List<T> other) {
695-
if (value == null) {
696-
return other;
697-
} else {
698-
return this.value.collect(Collectors.toList());
699-
}
700-
}
701-
}
702-
630+
/** Builder for creating a {@link Config} instance on json file. */
703631
public static class Builder {
704632

705633
public String buildCommand;
@@ -789,7 +717,6 @@ public void write(Path path) {
789717
downstreamDependency.addProperty("ANALYSIS_MODE", mode.name());
790718
}
791719
json.add("DOWNSTREAM_DEPENDENCY_ANALYSIS", downstreamDependency);
792-
793720
JsonObject processors = new JsonObject();
794721
sourceTypes.forEach(
795722
sourceType -> {
@@ -798,7 +725,6 @@ public void write(Path path) {
798725
processors.add(sourceType.name(), st);
799726
});
800727
json.add("PROCESSORS", processors);
801-
802728
try (BufferedWriter file =
803729
Files.newBufferedWriter(path.toFile().toPath(), Charset.defaultCharset())) {
804730
file.write(json.toString());

0 commit comments

Comments
 (0)