@@ -6,8 +6,13 @@ import { Graphviz } from "@hpcc-js/wasm-graphviz";
6
6
import { graphToDot } from "../control-flow/render" ;
7
7
import { simplifyCFG , trimFor } from "../control-flow/graph-ops" ;
8
8
import { newCFGBuilder , type Language } from "../control-flow/cfg" ;
9
- import { mergeNodeAttrs } from "../control-flow/cfg-defs" ;
9
+ import {
10
+ mergeNodeAttrs ,
11
+ remapNodeTargets ,
12
+ type CFG ,
13
+ } from "../control-flow/cfg-defs" ;
10
14
import { OverviewViewProvider } from "./overview-view" ;
15
+ import { getValue } from "../control-flow/ranges" ;
11
16
12
17
let graphviz : Graphviz ;
13
18
interface SupportedLanguage {
@@ -111,14 +116,20 @@ function getCurrentCode(): {
111
116
return { code, languageId, language } ;
112
117
}
113
118
114
- type Settings = { flatSwitch ? : boolean ; simplify ? : boolean } ;
119
+ type Settings = { flatSwitch : boolean ; simplify : boolean } ;
115
120
function loadSettings ( ) : Settings {
116
121
const config = vscode . workspace . getConfiguration ( "functionGraphOverview" ) ;
122
+
117
123
return {
118
- flatSwitch : config . get ( "flatSwitch" ) ,
119
- simplify : config . get ( "simplify" ) ,
124
+ flatSwitch : config . get ( "flatSwitch" ) ?? false ,
125
+ simplify : config . get ( "simplify" ) ?? false ,
120
126
} ;
121
127
}
128
+ type CFGKey = { functionText : string ; flatSwitch : boolean ; simplify : boolean } ;
129
+
130
+ function isSameKey ( a : CFGKey , b : CFGKey ) : boolean {
131
+ return JSON . stringify ( a ) === JSON . stringify ( b ) ;
132
+ }
122
133
123
134
function getFunctionAtPosition (
124
135
tree : Parser . Tree ,
@@ -164,11 +175,14 @@ export async function activate(context: vscode.ExtensionContext) {
164
175
165
176
const parsers = await initializeParsers ( context ) ;
166
177
178
+ let cfgKey : CFGKey | undefined ;
179
+ let savedCFG : CFG ;
180
+
167
181
const cursorMove = vscode . window . onDidChangeTextEditorSelection (
168
182
( event : vscode . TextEditorSelectionChangeEvent ) : void => {
169
183
const editor = event . textEditor ;
170
184
const position = editor . selection . active ;
171
- // const offset = editor.document.offsetAt(position);
185
+ const offset = editor . document . offsetAt ( position ) ;
172
186
173
187
console . log (
174
188
`Cursor position changed: Line ${ position . line + 1 } , Column ${ position . character + 1 } ` ,
@@ -182,7 +196,6 @@ export async function activate(context: vscode.ExtensionContext) {
182
196
const tree = parsers [ language ] . parse ( code ) ;
183
197
184
198
const functionSyntax = getFunctionAtPosition ( tree , position , language ) ;
185
-
186
199
if ( ! functionSyntax ) return ;
187
200
188
201
console . log ( functionSyntax ) ;
@@ -192,14 +205,31 @@ export async function activate(context: vscode.ExtensionContext) {
192
205
}
193
206
194
207
const { flatSwitch, simplify } = loadSettings ( ) ;
195
- const builder = newCFGBuilder ( language , { flatSwitch } ) ;
196
- let cfg = builder . buildCFG ( functionSyntax ) ;
197
- cfg = trimFor ( cfg ) ;
198
- if ( simplify ) {
199
- cfg = simplifyCFG ( cfg , mergeNodeAttrs ) ;
208
+ // We'd like to avoid re-running CFG generation for a function if nothing changed.
209
+ const newKey : CFGKey = {
210
+ flatSwitch,
211
+ simplify,
212
+ functionText : functionSyntax . text ,
213
+ } ;
214
+ let cfg : CFG ;
215
+ if ( cfgKey && isSameKey ( newKey , cfgKey ) ) {
216
+ cfg = savedCFG ;
217
+ } else {
218
+ cfgKey = newKey ;
219
+
220
+ const builder = newCFGBuilder ( language , { flatSwitch } ) ;
221
+ cfg = builder . buildCFG ( functionSyntax ) ;
222
+ cfg = trimFor ( cfg ) ;
223
+ if ( simplify ) {
224
+ cfg = simplifyCFG ( cfg , mergeNodeAttrs ) ;
225
+ }
226
+ cfg = remapNodeTargets ( cfg ) ;
227
+
228
+ savedCFG = cfg ;
200
229
}
201
230
202
- const dot = graphToDot ( cfg ) ;
231
+ const nodeToHighlight = getValue ( cfg . offsetToNode , offset ) ;
232
+ const dot = graphToDot ( cfg , false , nodeToHighlight ) ;
203
233
const svg = graphviz . dot ( dot ) ;
204
234
205
235
provider . setSVG ( svg ) ;
0 commit comments