Skip to content

Commit 144b39a

Browse files
committed
using treesitter queries
1 parent 2547dd6 commit 144b39a

File tree

1 file changed

+93
-34
lines changed

1 file changed

+93
-34
lines changed

app/api/repo/route.ts

+93-34
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,108 @@
1-
import { NextRequest, NextResponse } from "next/server";
2-
import { Graph, RedisClientType, RedisDefaultModules, createClient } from 'falkordb';
3-
import Parser from 'web-tree-sitter';
41
import os from 'os';
52
import fs from 'fs';
63
import path from 'path';
74
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);
874

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+
}
1180

1281
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
1683
await Parser.init({
1784
locateFile(scriptName: string, scriptDirectory: string) {
1885
return scriptName;
1986
},
2087
});
21-
const parser = new Parser();
22-
console.log("Parser: " + parser);
2388

89+
parser = new Parser();
2490
const Python = await Parser.Language.load('tree-sitter-python.wasm');
25-
console.log("Python: " + Python);
2691

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();
3292
parser.setLanguage(Python);
3393

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+
34103
// Download Github Repo into a temporary folder
35104
// Create temporary folder
36105

37-
38106
const tmp_dir = os.tmpdir();
39107
console.log("Temporary directory: " + tmp_dir);
40108

@@ -71,29 +139,20 @@ export async function POST(request: NextRequest) {
71139
for (let file of files) {
72140
let file_path = path.join(dir, file);
73141
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); }
82144
}
83145
}
84146
walk(repo_root);
147+
148+
//--------------------------------------------------------------------------
149+
// process each source file
150+
//--------------------------------------------------------------------------
85151

86152
for (let source_file of source_files) {
87153
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);
96155
}
97156

98157
return NextResponse.json({ message: "in progress..." }, { status: 201 })
99-
}
158+
}

0 commit comments

Comments
 (0)