1+ package org.utbot.visual
2+
3+ import org.utbot.summary.tag.BasicTypeTag
4+ import org.utbot.summary.tag.ExecutionTag
5+ import org.utbot.summary.tag.UniquenessTag
6+ import org.utbot.summary.tag.StatementTag
7+ import org.utbot.summary.tag.TraceTag
8+ import soot.jimple.JimpleBody
9+
10+ class TracePathReport : AbstractHtmlReport (bodyWidth = 1200 ) {
11+ private val tab = " "
12+
13+ private val freqSymbols = mapOf (
14+ UniquenessTag .Common to " " ,
15+ UniquenessTag .Unique to " ★ </mark>" ,
16+ UniquenessTag .Partly to " ► "
17+ )
18+
19+ private val basicTagColors = mapOf (
20+ BasicTypeTag .Initialization to " #aab7b8" ,
21+ BasicTypeTag .Condition to " black" ,
22+ BasicTypeTag .Return to " #28b463" ,
23+ BasicTypeTag .Assignment to " black" ,
24+ BasicTypeTag .Basic to " black" ,
25+ BasicTypeTag .ExceptionAssignment to " red" ,
26+ BasicTypeTag .ExceptionThrow to " red" ,
27+ BasicTypeTag .Invoke to " black" ,
28+ BasicTypeTag .IterationStart to " blue" ,
29+ BasicTypeTag .IterationEnd to " #2874a6"
30+ )
31+
32+ private val executionPostfix = mapOf (
33+ ExecutionTag .True to " : ✓" ,
34+ ExecutionTag .False to " : ✗" ,
35+ ExecutionTag .Executed to " "
36+ )
37+
38+ fun addJimpleBody (jimpleBody : JimpleBody ? ) {
39+ if (jimpleBody == null )
40+ return
41+ var result = " <h2>Jimple Body</h2>\n "
42+ jimpleBody.units.forEach {
43+ result + = " ${it.javaSourceStartLineNumber} :$tab $it <br>\n "
44+ }
45+
46+ builder.addRawHTML(result)
47+ }
48+
49+ private fun buildStructViewStatementTag (statementTag : StatementTag ? ): String {
50+ if (statementTag == null )
51+ return " "
52+ var result = " <li> ${statementTag.step.stmt} \n " +
53+ " <br> Decision = <strong>${markDecision(statementTag.executionTag)} </strong>\n " +
54+ " <br> Line = <strong>${statementTag.line} </strong> \n " +
55+ " <br> Type = <strong>${statementTag.basicTypeTag} </strong> \n " +
56+ " <br> Frequency = <strong>${statementTag.uniquenessTag} </strong> \n " +
57+ " <br> Call times = <strong>${statementTag.callOrderTag} </strong> <br>\n " +
58+ " </li>"
59+
60+ if (statementTag.invoke != null ) {
61+ result + = " \n <br><strong>Invocation:</strong> <br>\n " +
62+ " <ul>${buildStructViewStatementTag(statementTag.invoke)} </ul>\n "
63+ }
64+ if (statementTag.iterations.size > 0 ) {
65+ result + = " <strong>Iterations:</strong>\n "
66+ result + = " <ul>"
67+ for (i in 0 until statementTag.iterations.size) {
68+ result + = " <br><strong>Iteration $i </strong><br> ${buildStructViewStatementTag(statementTag.iterations[i])} \n "
69+ }
70+ result + = " </ul>"
71+ }
72+ if (statementTag.next != null ) {
73+ result + = " <br>${buildStructViewStatementTag(statementTag.next)} \n "
74+ }
75+ return result
76+ }
77+
78+ fun addStructViewTraces (tracesTags : Iterable <TraceTag >) {
79+ var table = " <h2> Struct View </h2>\n <table style=\" width:100%; vertical-align:top;\" >" +
80+ " <tr>\n "
81+ tracesTags.forEach {
82+ table + = " <td style=\" vertical-align:top;\" > <ul> ${buildStructViewStatementTag(it.rootStatementTag)} </ul></td>\n "
83+ }
84+ table + = " </tr>\n "
85+ builder.addRawHTML(table)
86+ }
87+
88+ fun addTracesTable (tagsToKeywords : List <List <TraceTag >>, name : String ) {
89+ var table = " <h2>$name </h2>\n " +
90+ " <table style=\" width:100%\" >"
91+
92+ table + = " <th>№ </th>"
93+ table + = " <th>Jimple code</th>"
94+ table + = " <th>Source code</th>"
95+ table + = " <th>Keywords</th> "
96+ table + = " <th>Comment</th>"
97+
98+ for ((clusterNum, clusterTraceTags) in tagsToKeywords.withIndex()) {
99+
100+ for (traceTags in clusterTraceTags) {
101+ table + = " <tr>"
102+ val traceTagsVisual = traceTags.rootStatementTag?.let { visualizeStatementTag(it) }
103+ table + = " <td>$clusterNum </td>"
104+
105+ table + = " <td><pre>"
106+ table + = traceTagsVisual ? : " None"
107+ table + = " </pre></td>"
108+
109+ table + = " <td><pre>"
110+ table + = " No source code yet"
111+ table + = " </pre></td>"
112+
113+ table + = " <td><pre>"
114+ table + = traceTags.summary
115+ table + = " </pre></td>"
116+ table + = " </tr>"
117+ }
118+ }
119+ table + = " </table>"
120+ builder.addRawHTML(table)
121+ }
122+
123+ private fun markDecision (executionTag : ExecutionTag ): String {
124+ var result = when (executionTag) {
125+ ExecutionTag .True -> " <span style=\" color:green;\" >"
126+ ExecutionTag .False -> " <span style=\" color:red;\" >"
127+ else -> " <span style=\" color:black;\" >"
128+ }
129+ result + = " $executionTag </span>"
130+ return result
131+ }
132+
133+ fun addExecutionVisualisation (rootTag : StatementTag , name : String ){
134+ var visualization = " <h2>$name </h2>\n "
135+ visualization + = " <pre>"
136+ visualization + = visualizeStatementTag(rootTag)
137+ visualization + = " </pre>"
138+ builder.addRawHTML(visualization)
139+ }
140+
141+ private fun visualizeStatementTag (tag : StatementTag , tabPrefix : String = ""): String {
142+ var localTabPrefix = tabPrefix
143+ var visualization = " "
144+
145+ visualization + = " <font color=\" ${basicTagColors[tag.basicTypeTag]} \" >"
146+ visualization + = tag.line.toString().padEnd(3 , ' ' ) + ' :'
147+ visualization + = localTabPrefix
148+ visualization + = freqSymbols[tag.uniquenessTag]
149+ if (tag.uniquenessTag == UniquenessTag .Unique ) visualization + = " <mark>"
150+ visualization + = tag.step.stmt.toString()
151+ visualization + = executionPostfix[tag.executionTag]
152+ if (tag.uniquenessTag == UniquenessTag .Unique ) visualization + = " </mark>"
153+ visualization + = " </font>"
154+ visualization + = " \n "
155+
156+ if (tag.invoke != null ) visualization + = visualizeStatementTag(tag.invoke!! , localTabPrefix + " \t " )
157+ if (tag.iterations.size > 0 ) {
158+ for (cycle in tag.iterations) visualization + = visualizeStatementTag(cycle, localTabPrefix + " \t " )
159+ }
160+
161+ if (tag.basicTypeTag == BasicTypeTag .IterationEnd ) localTabPrefix = localTabPrefix.removePrefix(" \t " )
162+ if (tag.next != null ) visualization + = visualizeStatementTag(tag.next!! , localTabPrefix)
163+
164+ return visualization
165+ }
166+
167+ }
0 commit comments