29
29
import com .google .common .collect .ImmutableSet ;
30
30
import com .google .common .collect .Sets ;
31
31
import com .google .gson .JsonArray ;
32
- import com .google .gson .JsonElement ;
33
- import com .google .gson .JsonNull ;
34
32
import com .google .gson .JsonObject ;
35
- import com .google .gson .JsonPrimitive ;
36
33
import edu .ucr .cs .riple .core .module .ModuleConfiguration ;
34
+ import edu .ucr .cs .riple .core .util .JsonParser ;
37
35
import edu .ucr .cs .riple .core .util .Utility ;
38
36
import edu .ucr .cs .riple .scanner .generatedcode .SourceType ;
39
37
import java .io .BufferedWriter ;
42
40
import java .nio .file .Files ;
43
41
import java .nio .file .Path ;
44
42
import java .nio .file .Paths ;
45
- import java .util .ArrayList ;
46
- import java .util .Arrays ;
47
43
import java .util .Collections ;
48
44
import java .util .HashSet ;
49
45
import java .util .List ;
50
46
import java .util .Set ;
51
- import java .util .function .Function ;
52
47
import java .util .stream .Collectors ;
53
- import java .util .stream .Stream ;
54
- import java .util .stream .StreamSupport ;
55
48
import org .apache .commons .cli .CommandLine ;
56
49
import org .apache .commons .cli .CommandLineParser ;
57
50
import org .apache .commons .cli .DefaultParser ;
@@ -521,51 +514,54 @@ private ParserConfiguration.LanguageLevel getLanguageLevel(String languageLevelS
521
514
*/
522
515
public Config (Path configPath ) {
523
516
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 ();
528
521
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 ();
531
524
this .useParallelGraphProcessor =
532
- getValueFromKey (jsonObject , "PARALLEL_PROCESSING" ).orElse (true ).getAsBoolean ();
525
+ parser . getValueFromKey ("PARALLEL_PROCESSING" ).orElse (true ).getAsBoolean ();
533
526
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 ();
539
531
this .nullableAnnot =
540
- getValueFromKey (jsonObject , "ANNOTATION:NULLABLE" )
532
+ parser
533
+ .getValueFromKey ("ANNOTATION:NULLABLE" )
541
534
.orElse ("javax.annotation.Nullable" )
542
535
.getAsString ();
543
536
this .initializerAnnot =
544
- getValueFromKey (jsonObject , "ANNOTATION:INITIALIZER" )
537
+ parser
538
+ .getValueFromKey ("ANNOTATION:INITIALIZER" )
545
539
.orElse ("com.uber.nullaway.annotations.Initializer" )
546
540
.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 ());
549
542
List <ModuleConfiguration > moduleConfigurationList =
550
- getArrayValueFromKey (
551
- jsonObject ,
543
+ parser
544
+ . getArrayValueFromKey (
552
545
"CONFIG_PATHS" ,
553
546
moduleInfo ->
554
547
ModuleConfiguration .buildFromJson (
555
548
getNextModuleUniqueID (), globalDir , moduleInfo ))
556
549
.orElse (Collections .emptyList ());
557
550
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 ();
559
552
this .downStreamDependenciesAnalysisActivated =
560
- getValueFromKey (jsonObject , "DOWNSTREAM_DEPENDENCY_ANALYSIS:ACTIVATION" )
553
+ parser
554
+ .getValueFromKey ("DOWNSTREAM_DEPENDENCY_ANALYSIS:ACTIVATION" )
561
555
.orElse (false )
562
556
.getAsBoolean ();
563
557
this .downstreamDependenciesBuildCommand =
564
- getValueFromKey (jsonObject , "DOWNSTREAM_DEPENDENCY_ANALYSIS:BUILD_COMMAND" )
558
+ parser
559
+ .getValueFromKey ("DOWNSTREAM_DEPENDENCY_ANALYSIS:BUILD_COMMAND" )
565
560
.orElse (null )
566
561
.getAsString ();
567
562
String nullawayLibraryModelLoaderPathString =
568
- getValueFromKey (jsonObject , "DOWNSTREAM_DEPENDENCY_ANALYSIS:LIBRARY_MODEL_LOADER_PATH" )
563
+ parser
564
+ .getValueFromKey ("DOWNSTREAM_DEPENDENCY_ANALYSIS:LIBRARY_MODEL_LOADER_PATH" )
569
565
.orElse (null )
570
566
.getAsString ();
571
567
this .nullawayLibraryModelLoaderPath =
@@ -576,32 +572,35 @@ public Config(Path configPath) {
576
572
this .mode =
577
573
AnalysisMode .parseMode (
578
574
this .downStreamDependenciesAnalysisActivated ,
579
- getValueFromKey (jsonObject , "DOWNSTREAM_DEPENDENCY_ANALYSIS:ANALYSIS_MODE" )
575
+ parser
576
+ .getValueFromKey ("DOWNSTREAM_DEPENDENCY_ANALYSIS:ANALYSIS_MODE" )
580
577
.orElse ("default" )
581
578
.getAsString ());
582
-
583
579
this .downstreamConfigurations = ImmutableSet .copyOf (moduleConfigurationList );
584
580
this .moduleCounterID = 0 ;
585
581
this .suppressRemainingErrors =
586
- getValueFromKey (jsonObject , "SUPPRESS_REMAINING_ERRORS" ).orElse (false ).getAsBoolean ();
582
+ parser . getValueFromKey ("SUPPRESS_REMAINING_ERRORS" ).orElse (false ).getAsBoolean ();
587
583
this .inferenceActivated =
588
- getValueFromKey (jsonObject , "INFERENCE_ACTIVATION" ).orElse (true ).getAsBoolean ();
584
+ parser . getValueFromKey ("INFERENCE_ACTIVATION" ).orElse (true ).getAsBoolean ();
589
585
this .nullUnMarkedAnnotation =
590
- getValueFromKey (jsonObject , "ANNOTATION:NULL_UNMARKED" )
586
+ parser
587
+ .getValueFromKey ("ANNOTATION:NULL_UNMARKED" )
591
588
.orElse ("org.jspecify.annotations.NullUnmarked" )
592
589
.getAsString ();
593
590
boolean lombokCodeDetectorActivated =
594
- getValueFromKey (jsonObject , "PROCESSORS:" + SourceType .LOMBOK .name () + ":ACTIVATION" )
591
+ parser
592
+ .getValueFromKey ("PROCESSORS:" + SourceType .LOMBOK .name () + ":ACTIVATION" )
595
593
.orElse (true )
596
594
.getAsBoolean ();
597
595
this .generatedCodeDetectors =
598
596
lombokCodeDetectorActivated ? Sets .immutableEnumSet (SourceType .LOMBOK ) : ImmutableSet .of ();
599
597
this .languageLevel =
600
- getLanguageLevel (getValueFromKey (jsonObject , "LANGUAGE_LEVEL" ).orElse ("17" ).getAsString ());
598
+ getLanguageLevel (parser . getValueFromKey ("LANGUAGE_LEVEL" ).orElse ("17" ).getAsString ());
601
599
this .nonnullAnnotations =
602
600
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 ())
605
604
.orElse (List .of ()));
606
605
}
607
606
@@ -628,78 +627,7 @@ private static void showHelp(HelpFormatter formatter, Options options) {
628
627
formatter .printHelp ("Annotator context Flags" , options );
629
628
}
630
629
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. */
703
631
public static class Builder {
704
632
705
633
public String buildCommand ;
@@ -789,7 +717,6 @@ public void write(Path path) {
789
717
downstreamDependency .addProperty ("ANALYSIS_MODE" , mode .name ());
790
718
}
791
719
json .add ("DOWNSTREAM_DEPENDENCY_ANALYSIS" , downstreamDependency );
792
-
793
720
JsonObject processors = new JsonObject ();
794
721
sourceTypes .forEach (
795
722
sourceType -> {
@@ -798,7 +725,6 @@ public void write(Path path) {
798
725
processors .add (sourceType .name (), st );
799
726
});
800
727
json .add ("PROCESSORS" , processors );
801
-
802
728
try (BufferedWriter file =
803
729
Files .newBufferedWriter (path .toFile ().toPath (), Charset .defaultCharset ())) {
804
730
file .write (json .toString ());
0 commit comments