diff --git a/src/checkers/inference/InferenceLauncher.java b/src/checkers/inference/InferenceLauncher.java index 4908d34e..0af6c426 100644 --- a/src/checkers/inference/InferenceLauncher.java +++ b/src/checkers/inference/InferenceLauncher.java @@ -202,6 +202,7 @@ public void infer() { addIfNotNull("--cfArgs", InferenceOptions.cfArgs, argList); addIfTrue("--hacks", InferenceOptions.hacks, argList); + addIfTrue("--writeDefaultAnnotations", InferenceOptions.writeDefaultAnnotations, argList); Mode mode = Mode.valueOf(InferenceOptions.mode); if (InferenceOptions.makeDefaultsExplicit @@ -209,6 +210,9 @@ public void infer() { // Two conditions have to be met to make defaults explicit: // 1. the command-line flag `makeDefaultsExplicit` is provided // 2. the inference solution will be written back to the source code (roundtrip `mode`) + if (InferenceOptions.writeDefaultAnnotations) { + outStream.println("writeDefaultAnnotations will have no effect when makeDefaultsExplicit is true"); + } argList.add("--makeDefaultsExplicit"); } diff --git a/src/checkers/inference/InferenceMain.java b/src/checkers/inference/InferenceMain.java index 3e1333a8..754a996c 100644 --- a/src/checkers/inference/InferenceMain.java +++ b/src/checkers/inference/InferenceMain.java @@ -106,6 +106,8 @@ public class InferenceMain { // Eventually we will get rid of this. private boolean hackMode; + private boolean writeDefaultAnnotations; + private ResultHandler resultHandler; public void setResultHandler(ResultHandler resultHandler) { @@ -149,7 +151,7 @@ public void run() { solve(); // solverResult = null covers case when debug solver is used, but in this case // shouldn't exit - if (solverResult != null && !solverResult.hasSolution()) { + if (solverResult != null && !solverResult.hasSolution() && !writeDefaultAnnotations) { logger.info("No solution, exiting..."); System.exit(1); } @@ -185,6 +187,10 @@ private void startCheckerFramework() { hackMode = true; } + if (InferenceOptions.writeDefaultAnnotations) { + writeDefaultAnnotations = true; + } + if (InferenceOptions.javacOptions != null) { checkerFrameworkArgs.addAll(InferenceOptions.javacOptions); } @@ -248,7 +254,11 @@ private void writeJaif() { } } - JaifBuilder builder = new JaifBuilder(values, annotationClasses, realChecker.isInsertMainModOfLocalVar()); + boolean insertMainModOfLocalVar = realChecker.isInsertMainModOfLocalVar(); + if (writeDefaultAnnotations) { + insertMainModOfLocalVar = true; // insert annotations of main modifier of local variables + } + JaifBuilder builder = new JaifBuilder(values, annotationClasses, insertMainModOfLocalVar); String jaif = builder.createJaif(); writer.println(jaif); @@ -294,12 +304,20 @@ private void solve() { AnnotationMirror result = solverResult.getSolutionForVariable(slot.getId()); if (result != null && slot instanceof SourceVariableSlot) { AnnotationMirror defaultAnnotation = ((SourceVariableSlot) slot).getDefaultAnnotation(); - if (defaultAnnotation != null && AnnotationUtils.areSame(defaultAnnotation, result)) { // Don't need to write a solution that's equivalent to the default annotation. result = null; } } + + else if (writeDefaultAnnotations && slot instanceof SourceVariableSlot) { + AnnotationMirror defaultAnnotation = ((SourceVariableSlot) slot).getDefaultAnnotation(); + System.out.println("For " + slot.getId() + "Result: " + result + " Default: " + defaultAnnotation); + if (defaultAnnotation != null) { + result = defaultAnnotation; + } + } + return result; } diff --git a/src/checkers/inference/InferenceOptions.java b/src/checkers/inference/InferenceOptions.java index 3f72dbfb..2fedebb8 100644 --- a/src/checkers/inference/InferenceOptions.java +++ b/src/checkers/inference/InferenceOptions.java @@ -49,6 +49,9 @@ public class InferenceOptions { @Option("Should we log certain exceptions rather than crash") public static boolean hacks; + @Option("Should we annotate source code with default annotations") + public static boolean writeDefaultAnnotations; + /** * The type system to use for checker, solver, and related command-line * options. If you use this option, all required command-line