Skip to content

Commit 5c6628e

Browse files
committed
Restored json-only dumping of cfg inputs #230
1 parent fcf9462 commit 5c6628e

File tree

10 files changed

+104
-30
lines changed

10 files changed

+104
-30
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"warnings" : [ ],
3+
"files" : [ "untyped_A.A(A__this)_cfg.json", "untyped_A.getOne(A__this)_cfg.json", "untyped_A.getPositive(A__this,_untyped_i)_cfg.json", "untyped_A.identity(A__this,_untyped_i)_cfg.json", "untyped_tests.helper(tests__this,_untyped_i,_untyped_dispatcher)_cfg.json", "untyped_tests.main(tests__this)_cfg.json" ]
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"untyped A::A(A* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"i1 = 0"},{"id":1,"text":"i1"},{"id":2,"text":"0"},{"id":3,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"}],"descriptions":[]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"untyped A::getOne(A* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"rec = new tests()"},{"id":1,"text":"rec"},{"id":2,"text":"new tests()"},{"id":3,"subNodes":[4,5],"text":"x = open(rec)"},{"id":4,"text":"x"},{"id":5,"subNodes":[6],"text":"open(rec)"},{"id":6,"text":"rec"},{"id":7,"subNodes":[8,9],"text":"<(x, 10)"},{"id":8,"text":"x"},{"id":9,"text":"10"},{"id":10,"subNodes":[11,12],"text":"x = +(x, 1)"},{"id":11,"text":"x"},{"id":12,"subNodes":[13,14],"text":"+(x, 1)"},{"id":13,"text":"x"},{"id":14,"text":"1"},{"id":15,"subNodes":[16],"text":"return 1"},{"id":16,"text":"1"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":7,"kind":"SequentialEdge"},{"sourceId":7,"destId":10,"kind":"TrueEdge"},{"sourceId":7,"destId":15,"kind":"FalseEdge"},{"sourceId":10,"destId":7,"kind":"SequentialEdge"}],"descriptions":[]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"untyped A::getPositive(A* this, untyped i)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"<=(i, 0)"},{"id":1,"text":"i"},{"id":2,"text":"0"},{"id":3,"subNodes":[4,5],"text":"i = 1"},{"id":4,"text":"i"},{"id":5,"text":"1"},{"id":6,"subNodes":[7,8],"text":"i = 10"},{"id":7,"text":"i"},{"id":8,"text":"10"},{"id":9,"subNodes":[10],"text":"return i"},{"id":10,"text":"i"}],"edges":[{"sourceId":0,"destId":3,"kind":"TrueEdge"},{"sourceId":0,"destId":6,"kind":"FalseEdge"},{"sourceId":3,"destId":9,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"}],"descriptions":[]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"untyped A::identity(A* this, untyped i)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"i3 = 1"},{"id":1,"text":"i3"},{"id":2,"text":"1"},{"id":3,"subNodes":[4],"text":"return i"},{"id":4,"text":"i"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"}],"descriptions":[]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"untyped tests::helper(tests* this, untyped i, untyped dispatcher)","description":null,"nodes":[{"id":0,"subNodes":[1],"text":"return identity(dispatcher, i)"},{"id":1,"subNodes":[2,3],"text":"identity(dispatcher, i)"},{"id":2,"text":"dispatcher"},{"id":3,"text":"i"}],"edges":[],"descriptions":[]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"untyped tests::main(tests* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = new A()"},{"id":1,"text":"a"},{"id":2,"text":"new A()"},{"id":3,"subNodes":[4,5],"text":"one = getPositive(a, getOne(a))"},{"id":4,"text":"one"},{"id":5,"subNodes":[6,7],"text":"getPositive(a, getOne(a))"},{"id":6,"text":"a"},{"id":7,"subNodes":[8],"text":"getOne(a)"},{"id":8,"text":"a"},{"id":9,"subNodes":[10,11],"text":"positive = identity(a, one)"},{"id":10,"text":"positive"},{"id":11,"subNodes":[12,13],"text":"identity(a, one)"},{"id":12,"text":"a"},{"id":13,"text":"one"},{"id":14,"subNodes":[15,16],"text":"minusone = -1"},{"id":15,"text":"minusone"},{"id":16,"text":"-1"},{"id":17,"subNodes":[18,19],"text":"negative = identity(a, minusone)"},{"id":18,"text":"negative"},{"id":19,"subNodes":[20,21],"text":"identity(a, minusone)"},{"id":20,"text":"a"},{"id":21,"text":"minusone"},{"id":22,"subNodes":[23,24],"text":"top = helper(this, one, a)"},{"id":23,"text":"top"},{"id":24,"subNodes":[25,26,27],"text":"helper(this, one, a)"},{"id":25,"text":"this"},{"id":26,"text":"one"},{"id":27,"text":"a"},{"id":28,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":14,"kind":"SequentialEdge"},{"sourceId":14,"destId":17,"kind":"SequentialEdge"},{"sourceId":17,"destId":22,"kind":"SequentialEdge"},{"sourceId":22,"destId":28,"kind":"SequentialEdge"}],"descriptions":[]}

lisa/lisa-core/src/main/java/it/unive/lisa/LiSAConfiguration.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ public static enum GraphType {
114114
*/
115115
private GraphType analysisGraphs;
116116

117+
/**
118+
* Whether or not the inputs {@link CFG}s to the analysis should be dumped
119+
* in json format
120+
*/
121+
private boolean serializeInputs;
122+
117123
/**
118124
* Whether or not the result of the analysis should be dumped in json
119125
* format, if it is executed
@@ -307,6 +313,19 @@ public LiSAConfiguration setJsonOutput(boolean jsonOutput) {
307313
return this;
308314
}
309315

316+
/**
317+
* Sets whether or not the the inputs {@link CFG}s to the analysis should be
318+
* dumped in json format.
319+
*
320+
* @param serializeInputs whether or not the graphs should be produced
321+
*
322+
* @return the current (modified) configuration
323+
*/
324+
public LiSAConfiguration setSerializeInputs(boolean serializeInputs) {
325+
this.serializeInputs = serializeInputs;
326+
return this;
327+
}
328+
310329
/**
311330
* Sets whether or not the results of the analyses should be dumped in the
312331
* form of json graphs.
@@ -443,6 +462,16 @@ public boolean isJsonOutput() {
443462
return jsonOutput;
444463
}
445464

465+
/**
466+
* Yields whether or not the the inputs {@link CFG}s to the analysis should
467+
* be dumped in json format.
468+
*
469+
* @return {@code true} if the graphs should be produced
470+
*/
471+
public boolean isSerializeInputs() {
472+
return serializeInputs;
473+
}
474+
446475
/**
447476
* Yields whether or not the results of the analyses should be dumped in the
448477
* form of json graphs.
@@ -504,6 +533,7 @@ public int hashCode() {
504533
result = prime * result + (jsonOutput ? 1231 : 1237);
505534
result = prime * result + ((openCallPolicy == null) ? 0 : openCallPolicy.hashCode());
506535
result = prime * result + ((semanticChecks == null) ? 0 : semanticChecks.hashCode());
536+
result = prime * result + (serializeInputs ? 1231 : 1237);
507537
result = prime * result + (serializeResults ? 1231 : 1237);
508538
result = prime * result + ((syntacticChecks == null) ? 0 : syntacticChecks.hashCode());
509539
result = prime * result + wideningThreshold;
@@ -554,6 +584,8 @@ public boolean equals(Object obj) {
554584
return false;
555585
} else if (!semanticChecks.equals(other.semanticChecks))
556586
return false;
587+
if (serializeInputs != other.serializeInputs)
588+
return false;
557589
if (serializeResults != other.serializeResults)
558590
return false;
559591
if (syntacticChecks == null) {
@@ -577,6 +609,8 @@ public String toString() {
577609
res.append("LiSA configuration:")
578610
.append("\n workdir: ")
579611
.append(String.valueOf(workdir))
612+
.append("\n serialize inputs: ")
613+
.append(serializeInputs)
580614
.append("\n serialize results: ")
581615
.append(serializeResults)
582616
.append("\n analysis results format: ")

lisa/lisa-core/src/main/java/it/unive/lisa/LiSARunner.java

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Collection;
3636
import java.util.IdentityHashMap;
3737
import java.util.Map;
38+
import java.util.concurrent.atomic.AtomicBoolean;
3839
import org.apache.logging.log4j.LogManager;
3940
import org.apache.logging.log4j.Logger;
4041

@@ -97,6 +98,23 @@ Collection<Warning> run(Application app, FileManager fileManager) {
9798

9899
Collection<CFG> allCFGs = app.getAllCFGs();
99100

101+
AtomicBoolean htmlViewer = new AtomicBoolean(false), subnodes = new AtomicBoolean(false);
102+
if (conf.isSerializeInputs())
103+
for (CFG cfg : IterationLogger.iterate(LOG, allCFGs, "Dumping input cfgs", "cfgs")) {
104+
SerializableGraph graph = cfg.toSerializableGraph();
105+
String filename = cfg.getDescriptor().getFullSignatureWithParNames() + "_cfg";
106+
107+
try {
108+
fileManager.mkJsonFile(filename, writer -> graph.dump(writer));
109+
110+
dump(fileManager, filename, conf.getAnalysisGraphs(), graph, htmlViewer, subnodes);
111+
} catch (IOException e) {
112+
LOG.error("Exception while dumping the analysis results on {}",
113+
cfg.getDescriptor().getFullSignature());
114+
LOG.error(e);
115+
}
116+
}
117+
100118
CheckTool tool = new CheckTool();
101119
if (!conf.getSyntacticChecks().isEmpty())
102120
ChecksExecutor.executeAll(tool, app, conf.getSyntacticChecks());
@@ -119,7 +137,7 @@ Collection<Warning> run(Application app, FileManager fileManager) {
119137
}
120138

121139
if (state != null) {
122-
analyze(allCFGs, fileManager);
140+
analyze(allCFGs, fileManager, htmlViewer, subnodes);
123141
Map<CFG, Collection<CFGWithAnalysisResults<A, H, V, T>>> results = new IdentityHashMap<>(allCFGs.size());
124142
for (CFG cfg : allCFGs)
125143
results.put(cfg, interproc.getAnalysisResultsOf(cfg));
@@ -141,7 +159,8 @@ Collection<Warning> run(Application app, FileManager fileManager) {
141159
return tool.getWarnings();
142160
}
143161

144-
private void analyze(Collection<CFG> allCFGs, FileManager fileManager) {
162+
private void analyze(Collection<CFG> allCFGs, FileManager fileManager, AtomicBoolean htmlViewer,
163+
AtomicBoolean subnodes) {
145164
A state = this.state.top();
146165
TimerLogger.execAction(LOG, "Computing fixpoint over the whole program",
147166
() -> {
@@ -158,7 +177,6 @@ private void analyze(Collection<CFG> allCFGs, FileManager fileManager) {
158177
GraphType type = conf.getAnalysisGraphs();
159178
if (conf.isSerializeResults() || type != GraphType.NONE) {
160179
int nfiles = fileManager.createdFiles().size();
161-
boolean htmlViewer = false, subnodes = false;
162180

163181
for (CFG cfg : IterationLogger.iterate(LOG, allCFGs, "Dumping analysis results", "cfgs"))
164182
for (CFGWithAnalysisResults<A, H, V, T> result : interproc.getAnalysisResultsOf(cfg)) {
@@ -172,50 +190,55 @@ private void analyze(Collection<CFG> allCFGs, FileManager fileManager) {
172190
if (conf.isSerializeResults())
173191
fileManager.mkJsonFile(filename, writer -> graph.dump(writer));
174192

175-
switch (type) {
176-
case DOT:
177-
fileManager.mkDotFile(filename, writer -> graph.toDot().dump(writer));
178-
break;
179-
case GRAPHML:
180-
fileManager.mkGraphmlFile(filename, writer -> graph.toGraphml(false).dump(writer));
181-
break;
182-
case GRAPHML_WITH_SUBNODES:
183-
fileManager.mkGraphmlFile(filename, writer -> graph.toGraphml(true).dump(writer));
184-
subnodes = true;
185-
break;
186-
case HTML:
187-
fileManager.mkHtmlFile(filename, writer -> graph.toHtml(false, "results").dump(writer));
188-
htmlViewer = true;
189-
break;
190-
case HTML_WITH_SUBNODES:
191-
fileManager.mkHtmlFile(filename, writer -> graph.toHtml(true, "results").dump(writer));
192-
htmlViewer = true;
193-
subnodes = true;
194-
break;
195-
case NONE:
196-
break;
197-
default:
198-
throw new AnalysisExecutionException("Unknown graph type: " + type);
199-
}
193+
dump(fileManager, filename, type, graph, htmlViewer, subnodes);
200194
} catch (IOException e) {
201195
LOG.error("Exception while dumping the analysis results on {}",
202196
cfg.getDescriptor().getFullSignature());
203197
LOG.error(e);
204198
}
205199
}
206200

207-
if (htmlViewer && fileManager.createdFiles().size() != nfiles)
201+
if (htmlViewer.get() && fileManager.createdFiles().size() != nfiles)
208202
try {
209203
// we dumped at least one file: need to copy the
210204
// javascript files
211-
fileManager.generateHtmlViewerSupportFiles(subnodes);
205+
fileManager.generateHtmlViewerSupportFiles(subnodes.get());
212206
} catch (IOException e) {
213207
LOG.error("Exception while generating supporting files for the html viwer");
214208
LOG.error(e);
215209
}
216210
}
217211
}
218212

213+
private static void dump(FileManager fileManager, String filename, GraphType type, SerializableGraph graph,
214+
AtomicBoolean htmlViewer, AtomicBoolean subnodes) throws IOException {
215+
switch (type) {
216+
case DOT:
217+
fileManager.mkDotFile(filename, writer -> graph.toDot().dump(writer));
218+
break;
219+
case GRAPHML:
220+
fileManager.mkGraphmlFile(filename, writer -> graph.toGraphml(false).dump(writer));
221+
break;
222+
case GRAPHML_WITH_SUBNODES:
223+
fileManager.mkGraphmlFile(filename, writer -> graph.toGraphml(true).dump(writer));
224+
subnodes.set(true);
225+
break;
226+
case HTML:
227+
fileManager.mkHtmlFile(filename, writer -> graph.toHtml(false, "results").dump(writer));
228+
htmlViewer.set(true);
229+
break;
230+
case HTML_WITH_SUBNODES:
231+
fileManager.mkHtmlFile(filename, writer -> graph.toHtml(true, "results").dump(writer));
232+
htmlViewer.set(true);
233+
subnodes.set(true);
234+
break;
235+
case NONE:
236+
break;
237+
default:
238+
throw new AnalysisExecutionException("Unknown graph type: " + type);
239+
}
240+
}
241+
219242
private static void finalizeApp(Application app) {
220243
for (Program p : app.getPrograms()) {
221244
TypeSystem types = p.getTypes();

lisa/lisa-core/src/test/java/it/unive/lisa/cron/visualization/VisualizationTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ public static void ensureAllTested() {
4949
assertTrue("Not all visualization types have been tested", notTested.isEmpty());
5050
}
5151

52+
@Test
53+
public void testInputSerialization() throws AnalysisSetupException {
54+
LiSAConfiguration conf = config();
55+
conf.setSerializeInputs(true);
56+
perform("visualization", "inputs", "program.imp", conf);
57+
}
58+
5259
@Test
5360
public void testDOT() throws AnalysisSetupException {
5461
LiSAConfiguration conf = config();

0 commit comments

Comments
 (0)