Skip to content

Commit 1126b0b

Browse files
author
Евгений Балякин
committed
improvements for python
1 parent 27368d8 commit 1126b0b

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

src/core/skeleton.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,24 @@ function extractPythonLandmarks(lines: string[]): Candidate[] {
249249

250250
function pythonRoute(lines: string[], index: number): { method: string; path: string; handler?: string; signature: string; endLine: number } | undefined {
251251
const trimmed = lines[index].trim();
252+
const handlerPattern = '([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)?(?:\\([^)]*\\))?)';
252253
const decorator = trimmed.match(/^@\w+(?:\.\w+)*\.(get|post|put|patch|delete|route)\(\s*['"]([^'"]+)['"]/);
253254
if (decorator) return { method: decorator[1].toUpperCase(), path: decorator[2], signature: trimmed, endLine: index + 1 };
254255

255-
const addRoute = trimmed.match(/(?:\w+\.)?router\.add_(get|post|put|patch|delete|route)\(\s*['"]([^'"]+)['"]\s*(?:,\s*([A-Za-z_]\w*(?:\.[A-Za-z_]\w*)?))?/);
256+
const genericAddRoute = trimmed.match(new RegExp(`(?:\\w+\\.)?router\\.add_route\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]+)['"]\\s*,\\s*${handlerPattern}`));
257+
if (genericAddRoute) return { method: genericAddRoute[1].toUpperCase(), path: genericAddRoute[2], handler: genericAddRoute[3], signature: trimmed, endLine: index + 1 };
258+
259+
const addRoute = trimmed.match(new RegExp(`(?:\\w+\\.)?router\\.add_(get|post|put|patch|delete)\\(\\s*['"]([^'"]+)['"]\\s*(?:,\\s*${handlerPattern})?`));
256260
if (addRoute) return { method: addRoute[1].toUpperCase(), path: addRoute[2], handler: addRoute[3], signature: trimmed, endLine: index + 1 };
257261

258-
const webRoute = trimmed.match(/\bweb\.(get|post|put|patch|delete|route)\(\s*['"]([^'"]+)['"]\s*(?:,\s*([A-Za-z_]\w*(?:\.[A-Za-z_]\w*)?))?/);
262+
const genericWebRoute = trimmed.match(new RegExp(`\\bweb\\.route\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]+)['"]\\s*,\\s*${handlerPattern}`));
263+
if (genericWebRoute) return { method: genericWebRoute[1].toUpperCase(), path: genericWebRoute[2], handler: genericWebRoute[3], signature: trimmed, endLine: index + 1 };
264+
265+
const webRoute = trimmed.match(new RegExp(`\\bweb\\.(get|post|put|patch|delete)\\(\\s*['"]([^'"]+)['"]\\s*(?:,\\s*${handlerPattern})?`));
259266
if (webRoute) return { method: webRoute[1].toUpperCase(), path: webRoute[2], handler: webRoute[3], signature: trimmed, endLine: index + 1 };
260267

261268
const windowText = lines.slice(index, Math.min(lines.length, index + 8)).map((line) => line.trim()).join(' ');
262-
const multilineWeb = windowText.match(/\bweb\.(get|post|put|patch|delete|route)\(\s*['"]([^'"]+)['"]\s*,\s*([A-Za-z_]\w*(?:\.[A-Za-z_]\w*)?)/);
269+
const multilineWeb = windowText.match(new RegExp(`\\bweb\\.(get|post|put|patch|delete)\\(\\s*['"]([^'"]+)['"]\\s*,\\s*${handlerPattern}`));
263270
if (multilineWeb) return { method: multilineWeb[1].toUpperCase(), path: multilineWeb[2], handler: multilineWeb[3], signature: windowText, endLine: Math.min(lines.length, index + 8) };
264271

265272
return undefined;

tests/skeleton.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,20 @@ describe('codebone core', () => {
9191
' request.app["dao"]',
9292
' return None',
9393
'',
94+
"app.router.add_route('*', '/jsonrpc/users', UserService)",
95+
"app.router.add_route('GET', '/jsonrpc/users/doc', handle_jsonrpc_doc(UserService))",
96+
"app.router.add_route('GET', '/cron/users', cron.handler_users)",
97+
"web.get('/health', health_handler)",
98+
'',
9499
].join('\n'));
95100

96101
const skeleton = await skeletonPath(tempRoot, 'app/api.py');
97102
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'table', name: 'users' }));
98103
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'route', name: 'GET /users/{user_id}' }));
104+
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'route', name: '* /jsonrpc/users', source: 'UserService' }));
105+
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'route', name: 'GET /jsonrpc/users/doc', source: 'handle_jsonrpc_doc(UserService)' }));
106+
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'route', name: 'GET /cron/users', source: 'cron.handler_users' }));
107+
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'route', name: 'GET /health', source: 'health_handler' }));
99108
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'dependency', name: 'dao' }));
100109
expect(skeleton.symbols).toContainEqual(expect.objectContaining({ kind: 'function', name: 'rpc_get_user' }));
101110
});

0 commit comments

Comments
 (0)