1
- import { NextRequest , NextResponse } from "next/server" ;
2
- import { Graph , RedisClientType , RedisDefaultModules , createClient } from 'falkordb' ;
3
- import Parser from 'web-tree-sitter' ;
4
1
import os from 'os' ;
5
2
import fs from 'fs' ;
6
3
import path from 'path' ;
7
4
import simpleGit from 'simple-git' ;
5
+ import Parser from 'web-tree-sitter' ;
6
+ import { NextRequest , NextResponse } from "next/server" ;
7
+ import { Graph , RedisClientType , RedisDefaultModules , createClient } from 'falkordb' ;
8
+
9
+ // const client = createClient();
10
+ // client.connect()
11
+
12
+ //-----------------------------------------------------------------------------
13
+ // Tree-Sitter queries
14
+ //-----------------------------------------------------------------------------
15
+
16
+ let parser ;
17
+
18
+ // class definition tree-sitter query
19
+ // responsible for matching class definition, in addition to extracting the class name
20
+ let class_definition_query ;
21
+
22
+ // function definition tree-sitter query
23
+ // responsible for matching function definition, in addition to extracting the function name
24
+ let function_definition_query ;
25
+
26
+ // function call tree-sitter query
27
+ // responsible for matching function calls, in addition to extracting the callee function name
28
+ let function_call_query ;
29
+
30
+ // Process Python file (Module)
31
+ function processPythonSource ( source_file ) {
32
+ // read file
33
+ fs . readFile ( source_file , 'utf8' , function ( err : any , source : string ) {
34
+ if ( err ) {
35
+ return console . log ( err ) ;
36
+ }
37
+
38
+ // Construct an AST from source
39
+ const tree = parser . parse ( source ) ;
40
+
41
+ // match all Class definitions
42
+ let class_matches = class_definition_query . matches ( tree . rootNode ) ;
43
+
44
+ // Iterate over each matched Class
45
+ for ( let class_match of class_matches ) {
46
+ processClassDeclaration ( source_file , class_match ) ;
47
+ }
48
+ } ) ;
49
+ }
50
+
51
+ // Process Class declaration
52
+ function processClassDeclaration ( source_file , match ) {
53
+ let class_node = match . captures [ 0 ] . node ;
54
+ let class_name = match . captures [ 1 ] . node . text ;
55
+ //console.log("Class node: " + class_node);
56
+ console . log ( "Class name: " + class_name ) ;
57
+
58
+ // Match all function definition within the current class
59
+ let function_matches = function_definition_query . matches ( class_node ) ;
60
+ for ( let function_match of function_matches ) {
61
+ processFunctionDeclaration ( source_file , function_match ) ;
62
+ }
63
+ }
64
+
65
+ // Process function declaration
66
+ function processFunctionDeclaration ( source_file , match ) {
67
+ let function_node = match . captures [ 0 ] . node ;
68
+ let function_name = match . captures [ 1 ] . node . text ;
69
+ //console.log("Function definition Node: " + function_node);
70
+ console . log ( "Function name: " + function_name ) ;
71
+
72
+ // Match all function calls within the current function
73
+ let function_call_matches = function_call_query . matches ( function_node ) ;
8
74
9
- //const client = createClient();
10
- //client.connect()
75
+ for ( let function_call of function_call_matches ) {
76
+ let callee = function_call . captures [ 0 ] . node . text ;
77
+ console . log ( function_name + " calls: " + callee ) ;
78
+ }
79
+ }
11
80
12
81
export async function POST ( request : NextRequest ) {
13
- // parse source files
14
- // const Parser = require('tree-sitter');
15
- //await Parser.init();
82
+ // Initialize Tree-Sitter parser
16
83
await Parser . init ( {
17
84
locateFile ( scriptName : string , scriptDirectory : string ) {
18
85
return scriptName ;
19
86
} ,
20
87
} ) ;
21
- const parser = new Parser ( ) ;
22
- console . log ( "Parser: " + parser ) ;
23
88
89
+ parser = new Parser ( ) ;
24
90
const Python = await Parser . Language . load ( 'tree-sitter-python.wasm' ) ;
25
- console . log ( "Python: " + Python ) ;
26
91
27
- // const Python = require('tree-sitter-python');
28
- //const JavaScript = require('tree-sitter-javascript');
29
- // console.log("Python: " + Python);
30
-
31
- //const parser = new Parser();
32
92
parser . setLanguage ( Python ) ;
33
93
94
+ //-------------------------------------------------------------------------
95
+ // Tree-Sitter AST queries
96
+ //-------------------------------------------------------------------------
97
+
98
+ function_call_query = Python . query ( `((call function: (identifier) @function-name))` ) ;
99
+ //function_call_query = Python.query(`(call_expression function: (identifier) @function-name)`);
100
+ class_definition_query = Python . query ( `(class_definition name: (identifier) @class-name) @class-definition` ) ;
101
+ function_definition_query = Python . query ( `(function_definition name: (identifier) @function-name) @function-definition` ) ;
102
+
34
103
// Download Github Repo into a temporary folder
35
104
// Create temporary folder
36
105
37
-
38
106
const tmp_dir = os . tmpdir ( ) ;
39
107
console . log ( "Temporary directory: " + tmp_dir ) ;
40
108
@@ -71,29 +139,20 @@ export async function POST(request: NextRequest) {
71
139
for ( let file of files ) {
72
140
let file_path = path . join ( dir , file ) ;
73
141
let file_stat = fs . statSync ( file_path ) ;
74
- if ( file_stat . isDirectory ( ) ) {
75
- walk ( file_path ) ;
76
- }
77
- else {
78
- if ( file . endsWith ( ".py" ) ) {
79
- source_files . push ( file_path ) ;
80
- }
81
- }
142
+ if ( file_stat . isDirectory ( ) ) { walk ( file_path ) ; }
143
+ else if ( file . endsWith ( ".py" ) ) { source_files . push ( file_path ) ; }
82
144
}
83
145
}
84
146
walk ( repo_root ) ;
147
+
148
+ //--------------------------------------------------------------------------
149
+ // process each source file
150
+ //--------------------------------------------------------------------------
85
151
86
152
for ( let source_file of source_files ) {
87
153
console . log ( "Processing file: " + source_file ) ;
88
- // read file
89
- fs . readFile ( source_file , 'utf8' , function ( err : any , source : string ) {
90
- if ( err ) {
91
- return console . log ( err ) ;
92
- }
93
- const tree = parser . parse ( source ) ;
94
- console . log ( "Tree: " + tree ) ;
95
- } ) ;
154
+ processPythonSource ( source_file ) ;
96
155
}
97
156
98
157
return NextResponse . json ( { message : "in progress..." } , { status : 201 } )
99
- }
158
+ }
0 commit comments