@@ -73,7 +73,6 @@ export class AlertTable extends React.Component<
7373 render ( ) : JSX . Element {
7474 const { databaseUri, resultSet } = this . props ;
7575
76- const rows : JSX . Element [ ] = [ ] ;
7776 const { numTruncatedResults, sourceLocationPrefix } =
7877 resultSet . interpretation ;
7978
@@ -99,202 +98,211 @@ export class AlertTable extends React.Component<
9998 return < AlertTableNoResults { ...this . props } /> ;
10099 }
101100
102- resultSet . interpretation . data . runs [ 0 ] . results . forEach (
103- ( result , resultIndex ) => {
104- const resultKey : Keys . Result = { resultIndex } ;
105- const text = result . message . text || "[no text]" ;
106- const msg =
107- result . relatedLocations === undefined ? (
108- < span key = "0" > { text } </ span >
109- ) : (
110- < SarifMessageWithLocations
111- msg = { text }
112- relatedLocations = { result . relatedLocations }
113- sourceLocationPrefix = { sourceLocationPrefix }
114- databaseUri = { databaseUri }
115- onClick = { updateSelectionCallback ( resultKey ) }
116- />
117- ) ;
101+ const rows : JSX . Element [ ] =
102+ resultSet . interpretation . data . runs [ 0 ] . results . map (
103+ ( result , resultIndex ) => {
104+ const resultKey : Keys . Result = { resultIndex } ;
105+ const text = result . message . text || "[no text]" ;
106+ const msg =
107+ result . relatedLocations === undefined ? (
108+ < span key = "0" > { text } </ span >
109+ ) : (
110+ < SarifMessageWithLocations
111+ msg = { text }
112+ relatedLocations = { result . relatedLocations }
113+ sourceLocationPrefix = { sourceLocationPrefix }
114+ databaseUri = { databaseUri }
115+ onClick = { updateSelectionCallback ( resultKey ) }
116+ />
117+ ) ;
118118
119- const currentResultExpanded = this . state . expanded . has (
120- Keys . keyToString ( resultKey ) ,
121- ) ;
122- const location = result . locations !== undefined &&
123- result . locations . length > 0 && (
124- < SarifLocation
125- loc = { result . locations [ 0 ] }
126- sourceLocationPrefix = { sourceLocationPrefix }
127- databaseUri = { databaseUri }
128- onClick = { updateSelectionCallback ( resultKey ) }
129- />
119+ const currentResultExpanded = this . state . expanded . has (
120+ Keys . keyToString ( resultKey ) ,
130121 ) ;
131- const locationCells = (
132- < td className = "vscode-codeql__location-cell" > { location } </ td >
133- ) ;
134-
135- const selectedItem = this . state . selectedItem ;
136- const resultRowIsSelected =
137- selectedItem ?. resultIndex === resultIndex &&
138- selectedItem . pathIndex === undefined ;
139-
140- if ( result . codeFlows === undefined ) {
141- rows . push (
142- < tr
143- ref = { this . scroller . ref ( resultRowIsSelected ) }
144- key = { resultIndex }
145- { ...selectableZebraStripe ( resultRowIsSelected , resultIndex ) }
146- >
147- < td className = "vscode-codeql__icon-cell" > { info } </ td >
148- < td colSpan = { 3 } > { msg } </ td >
149- { locationCells }
150- </ tr > ,
122+ const location = result . locations !== undefined &&
123+ result . locations . length > 0 && (
124+ < SarifLocation
125+ loc = { result . locations [ 0 ] }
126+ sourceLocationPrefix = { sourceLocationPrefix }
127+ databaseUri = { databaseUri }
128+ onClick = { updateSelectionCallback ( resultKey ) }
129+ />
130+ ) ;
131+ const locationCells = (
132+ < td className = "vscode-codeql__location-cell" > { location } </ td >
151133 ) ;
152- } else {
153- const paths : Sarif . ThreadFlow [ ] = Keys . getAllPaths ( result ) ;
154134
155- const indices =
156- paths . length === 1
157- ? [ resultKey , { ...resultKey , pathIndex : 0 } ]
158- : /* if there's exactly one path, auto-expand
159- * the path when expanding the result */
160- [ resultKey ] ;
135+ const selectedItem = this . state . selectedItem ;
136+ const resultRowIsSelected =
137+ selectedItem ?. resultIndex === resultIndex &&
138+ selectedItem . pathIndex === undefined ;
161139
162- rows . push (
163- < tr
164- ref = { this . scroller . ref ( resultRowIsSelected ) }
165- { ...selectableZebraStripe ( resultRowIsSelected , resultIndex ) }
166- key = { resultIndex }
167- >
168- < AlertTableDropdownIndicatorCell
169- expanded = { currentResultExpanded }
170- onClick = { toggler ( indices ) }
171- />
172- < td className = "vscode-codeql__icon-cell" > { listUnordered } </ td >
173- < td colSpan = { 2 } > { msg } </ td >
174- { locationCells }
175- </ tr > ,
176- ) ;
140+ if ( result . codeFlows === undefined ) {
141+ return (
142+ < tr
143+ ref = { this . scroller . ref ( resultRowIsSelected ) }
144+ key = { resultIndex }
145+ { ...selectableZebraStripe ( resultRowIsSelected , resultIndex ) }
146+ >
147+ < td className = "vscode-codeql__icon-cell" > { info } </ td >
148+ < td colSpan = { 3 } > { msg } </ td >
149+ { locationCells }
150+ </ tr >
151+ ) ;
152+ } else {
153+ const paths : Sarif . ThreadFlow [ ] = Keys . getAllPaths ( result ) ;
154+
155+ const indices =
156+ paths . length === 1
157+ ? [ resultKey , { ...resultKey , pathIndex : 0 } ]
158+ : /* if there's exactly one path, auto-expand
159+ * the path when expanding the result */
160+ [ resultKey ] ;
177161
178- paths . forEach ( ( path , pathIndex ) => {
179- const pathKey = { resultIndex, pathIndex } ;
180- const currentPathExpanded = this . state . expanded . has (
181- Keys . keyToString ( pathKey ) ,
162+ const resultRow = (
163+ < tr
164+ ref = { this . scroller . ref ( resultRowIsSelected ) }
165+ { ...selectableZebraStripe ( resultRowIsSelected , resultIndex ) }
166+ key = { resultIndex }
167+ >
168+ < AlertTableDropdownIndicatorCell
169+ expanded = { currentResultExpanded }
170+ onClick = { toggler ( indices ) }
171+ />
172+ < td className = "vscode-codeql__icon-cell" > { listUnordered } </ td >
173+ < td colSpan = { 2 } > { msg } </ td >
174+ { locationCells }
175+ </ tr >
182176 ) ;
183- if ( currentResultExpanded ) {
184- const isPathSpecificallySelected = Keys . equalsNotUndefined (
185- pathKey ,
186- selectedItem ,
187- ) ;
188- rows . push (
189- < tr
190- ref = { this . scroller . ref ( isPathSpecificallySelected ) }
191- { ...selectableZebraStripe (
192- isPathSpecificallySelected ,
193- resultIndex ,
194- ) }
195- key = { `${ resultIndex } -${ pathIndex } ` }
196- >
197- < td className = "vscode-codeql__icon-cell" >
198- < span className = "vscode-codeql__vertical-rule" > </ span >
199- </ td >
200- < AlertTableDropdownIndicatorCell
201- expanded = { currentPathExpanded }
202- onClick = { toggler ( [ pathKey ] ) }
203- />
204- < td className = "vscode-codeql__text-center" colSpan = { 3 } >
205- Path
206- </ td >
207- </ tr > ,
208- ) ;
209- }
210177
211- if ( currentResultExpanded && currentPathExpanded ) {
212- const pathNodes = path . locations ;
213- for (
214- let pathNodeIndex = 0 ;
215- pathNodeIndex < pathNodes . length ;
216- ++ pathNodeIndex
217- ) {
218- const pathNodeKey : Keys . PathNode = {
219- ...pathKey ,
220- pathNodeIndex,
221- } ;
222- const step = pathNodes [ pathNodeIndex ] ;
223- const msg =
224- step . location !== undefined &&
225- step . location . message !== undefined ? (
226- < SarifLocation
227- text = { step . location . message . text }
228- loc = { step . location }
229- sourceLocationPrefix = { sourceLocationPrefix }
230- databaseUri = { databaseUri }
231- onClick = { updateSelectionCallback ( pathNodeKey ) }
232- />
233- ) : (
234- "[no location]"
235- ) ;
236- const additionalMsg =
237- step . location !== undefined ? (
238- < SarifLocation
239- loc = { step . location }
240- sourceLocationPrefix = { sourceLocationPrefix }
241- databaseUri = { databaseUri }
242- onClick = { updateSelectionCallback ( pathNodeKey ) }
243- />
244- ) : (
245- ""
246- ) ;
247- const isSelected = Keys . equalsNotUndefined (
248- this . state . selectedItem ,
249- pathNodeKey ,
178+ const pathRows =
179+ currentResultExpanded &&
180+ paths . map ( ( path , pathIndex ) => {
181+ const pathKey = { resultIndex, pathIndex } ;
182+ const currentPathExpanded = this . state . expanded . has (
183+ Keys . keyToString ( pathKey ) ,
184+ ) ;
185+ const isPathSpecificallySelected = Keys . equalsNotUndefined (
186+ pathKey ,
187+ selectedItem ,
250188 ) ;
251- const stepIndex = pathNodeIndex + 1 ; // Convert to 1-based
252- const zebraIndex = resultIndex + stepIndex ;
253- rows . push (
189+ const pathRow = (
254190 < tr
255- ref = { this . scroller . ref ( isSelected ) }
256- className = {
257- isSelected
258- ? "vscode-codeql__selected-path-node"
259- : undefined
260- }
261- key = { `${ resultIndex } -${ pathIndex } -${ pathNodeIndex } ` }
191+ ref = { this . scroller . ref ( isPathSpecificallySelected ) }
192+ { ...selectableZebraStripe (
193+ isPathSpecificallySelected ,
194+ resultIndex ,
195+ ) }
196+ key = { `${ resultIndex } -${ pathIndex } ` }
262197 >
263198 < td className = "vscode-codeql__icon-cell" >
264199 < span className = "vscode-codeql__vertical-rule" > </ span >
265200 </ td >
266- < td className = "vscode-codeql__icon-cell" >
267- < span className = "vscode-codeql__vertical-rule" > </ span >
268- </ td >
269- < td
270- { ...selectableZebraStripe (
271- isSelected ,
272- zebraIndex ,
273- "vscode-codeql__path-index-cell" ,
274- ) }
275- >
276- { stepIndex }
277- </ td >
278- < td { ...selectableZebraStripe ( isSelected , zebraIndex ) } >
279- { msg } { " " }
280- </ td >
281- < td
282- { ...selectableZebraStripe (
283- isSelected ,
284- zebraIndex ,
285- "vscode-codeql__location-cell" ,
286- ) }
287- >
288- { additionalMsg }
201+ < AlertTableDropdownIndicatorCell
202+ expanded = { currentPathExpanded }
203+ onClick = { toggler ( [ pathKey ] ) }
204+ />
205+ < td className = "vscode-codeql__text-center" colSpan = { 3 } >
206+ Path
289207 </ td >
290- </ tr > ,
208+ </ tr >
291209 ) ;
292- }
293- }
294- } ) ;
295- }
296- } ,
297- ) ;
210+
211+ const pathNodeRows =
212+ currentPathExpanded &&
213+ path . locations . map ( ( step , pathNodeIndex ) => {
214+ const pathNodeKey : Keys . PathNode = {
215+ ...pathKey ,
216+ pathNodeIndex,
217+ } ;
218+ const msg =
219+ step . location !== undefined &&
220+ step . location . message !== undefined ? (
221+ < SarifLocation
222+ text = { step . location . message . text }
223+ loc = { step . location }
224+ sourceLocationPrefix = { sourceLocationPrefix }
225+ databaseUri = { databaseUri }
226+ onClick = { updateSelectionCallback ( pathNodeKey ) }
227+ />
228+ ) : (
229+ "[no location]"
230+ ) ;
231+ const additionalMsg =
232+ step . location !== undefined ? (
233+ < SarifLocation
234+ loc = { step . location }
235+ sourceLocationPrefix = { sourceLocationPrefix }
236+ databaseUri = { databaseUri }
237+ onClick = { updateSelectionCallback ( pathNodeKey ) }
238+ />
239+ ) : (
240+ ""
241+ ) ;
242+ const isSelected = Keys . equalsNotUndefined (
243+ this . state . selectedItem ,
244+ pathNodeKey ,
245+ ) ;
246+ const stepIndex = pathNodeIndex + 1 ; // Convert to 1-based
247+ const zebraIndex = resultIndex + stepIndex ;
248+ return (
249+ < tr
250+ ref = { this . scroller . ref ( isSelected ) }
251+ className = {
252+ isSelected
253+ ? "vscode-codeql__selected-path-node"
254+ : undefined
255+ }
256+ key = { `${ resultIndex } -${ pathIndex } -${ pathNodeIndex } ` }
257+ >
258+ < td className = "vscode-codeql__icon-cell" >
259+ < span className = "vscode-codeql__vertical-rule" > </ span >
260+ </ td >
261+ < td className = "vscode-codeql__icon-cell" >
262+ < span className = "vscode-codeql__vertical-rule" > </ span >
263+ </ td >
264+ < td
265+ { ...selectableZebraStripe (
266+ isSelected ,
267+ zebraIndex ,
268+ "vscode-codeql__path-index-cell" ,
269+ ) }
270+ >
271+ { stepIndex }
272+ </ td >
273+ < td { ...selectableZebraStripe ( isSelected , zebraIndex ) } >
274+ { msg } { " " }
275+ </ td >
276+ < td
277+ { ...selectableZebraStripe (
278+ isSelected ,
279+ zebraIndex ,
280+ "vscode-codeql__location-cell" ,
281+ ) }
282+ >
283+ { additionalMsg }
284+ </ td >
285+ </ tr >
286+ ) ;
287+ } ) ;
288+
289+ return (
290+ < >
291+ { pathRow }
292+ { pathNodeRows }
293+ </ >
294+ ) ;
295+ } ) ;
296+
297+ return (
298+ < >
299+ { resultRow }
300+ { pathRows }
301+ </ >
302+ ) ;
303+ }
304+ } ,
305+ ) ;
298306
299307 return (
300308 < table className = { className } >
0 commit comments