@@ -5,17 +5,63 @@ import Parser, { type SyntaxNode } from "web-tree-sitter";
55import { Graphviz } from "@hpcc-js/wasm-graphviz" ;
66import { graphToDot } from "../control-flow/render" ;
77import { simplifyCFG , trimFor } from "../control-flow/graph-ops" ;
8- import { newCFGBuilder } from "../control-flow/cfg" ;
8+ import { newCFGBuilder , type Language } from "../control-flow/cfg" ;
99
1010let graphviz : Graphviz ;
11+ interface SupportedLanguage {
12+ languageId : string ;
13+ language : Language ;
14+ parserName : string ;
15+ }
16+ const supportedLanguages : SupportedLanguage [ ] = [
17+ {
18+ languageId : "c" ,
19+ language : "C" as Language ,
20+ parserName : "tree-sitter-c.wasm" ,
21+ } ,
22+ {
23+ languageId : "go" ,
24+ language : "Go" as Language ,
25+ parserName : "tree-sitter-go.wasm" ,
26+ } ,
27+ ] ;
28+
29+ const functionNodeTypes : { [ key : string ] : string [ ] } = {
30+ go : [ "function_declaration" , "method_declaration" , "func_literal" ] ,
31+ c : [ "function_definition" ] ,
32+ } ;
33+
34+ const supportedLanguageIds = supportedLanguages . map ( ( lang ) => lang . languageId ) ;
35+ const idToLanguage = ( languageId : string ) : Language | null => {
36+ for ( const lang of supportedLanguages ) {
37+ if ( lang . languageId === languageId ) {
38+ return lang . language ;
39+ }
40+ }
41+ return null ;
42+ } ;
43+
44+ async function initializeParsers ( context : vscode . ExtensionContext ) {
45+ const parsers : { [ key : string ] : Parser } = { } ;
46+
47+ for ( const lang of supportedLanguages ) {
48+ const languagePath = vscode . Uri . joinPath (
49+ context . extensionUri ,
50+ "parsers" ,
51+ lang . parserName ,
52+ ) . fsPath ;
53+ parsers [ lang . languageId ] = await initializeParser ( context , languagePath ) ;
54+ }
55+
56+ return parsers ;
57+ }
1158
1259async function initializeParser (
1360 context : vscode . ExtensionContext ,
1461 languagePath : string ,
1562) {
1663 await Parser . init ( {
17- locateFile ( scriptName : string , scriptDirectory : string ) {
18- console . log ( "name" , scriptName , "dir" , scriptDirectory ) ;
64+ locateFile ( _scriptName : string , _scriptDirectory : string ) {
1965 return vscode . Uri . joinPath (
2066 context . extensionUri ,
2167 "parsers" ,
@@ -29,18 +75,21 @@ async function initializeParser(
2975 return parser ;
3076}
3177
32- function getCurrentGoCode ( ) : string | null {
78+ function getCurrentCode ( ) : { code : string ; languageId : string } | null {
3379 const editor = vscode . window . activeTextEditor ;
3480 if ( ! editor ) {
3581 return null ;
3682 }
3783
3884 const document = editor . document ;
39- if ( document . languageId !== "go" ) {
85+ const languageId = document . languageId ;
86+ if ( ! supportedLanguageIds . includes ( languageId ) ) {
4087 return null ;
4188 }
4289
43- return document . getText ( ) ;
90+ const code = document . getText ( ) ;
91+
92+ return { code, languageId } ;
4493}
4594
4695// This method is called when your extension is activated
@@ -63,20 +112,19 @@ export async function activate(context: vscode.ExtensionContext) {
63112 'Congratulations, your extension "function-graph-overview" is now active!' ,
64113 ) ;
65114
66- const wasmPath = vscode . Uri . joinPath (
67- context . extensionUri ,
68- "parsers" ,
69- "tree-sitter-go.wasm" ,
70- ) ;
71- const parser = await initializeParser ( context , wasmPath . fsPath ) ;
115+ const parsers = await initializeParsers ( context ) ;
72116
73117 const cursorMove = vscode . window . onDidChangeTextEditorSelection (
74118 ( event : vscode . TextEditorSelectionChangeEvent ) => {
75119 const editor = event . textEditor ;
76120 const position = editor . selection . active ;
77121
78- const code = getCurrentGoCode ( ) ?? "" ;
79- const tree = parser . parse ( code ) ;
122+ const { code, languageId } = getCurrentCode ( ) ?? { } ;
123+ if ( ! code || ! languageId ) {
124+ return null ;
125+ }
126+
127+ const tree = parsers [ languageId ] . parse ( code ) ;
80128
81129 console . log (
82130 `Cursor position changed: Line ${ position . line + 1 } , Column ${ position . character + 1 } ` ,
@@ -85,14 +133,9 @@ export async function activate(context: vscode.ExtensionContext) {
85133 row : position . line ,
86134 column : position . character ,
87135 } ) ;
88- const funcTypes = [
89- "function_declaration" ,
90- "method_declaration" ,
91- "func_literal" ,
92- ] ;
93136
94137 while ( node ) {
95- if ( funcTypes . includes ( node . type ) ) {
138+ if ( functionNodeTypes [ languageId ] . includes ( node . type ) ) {
96139 break ;
97140 }
98141 node = node . parent ;
@@ -121,7 +164,11 @@ export async function activate(context: vscode.ExtensionContext) {
121164 . getConfiguration ( "functionGraphOverview" )
122165 . get ( "flatSwitch" ) ,
123166 ) ;
124- const builder = newCFGBuilder ( "Go" , { flatSwitch } ) ;
167+ const language = idToLanguage ( languageId ) ;
168+ if ( ! language ) {
169+ return ;
170+ }
171+ const builder = newCFGBuilder ( language , { flatSwitch } ) ;
125172 let cfg = builder . buildCFG ( node ) ;
126173 cfg = trimFor ( cfg ) ;
127174 if (
0 commit comments