@@ -16,14 +16,48 @@ export class FastapiEndpointExtractor implements IEndpointExtractor
16
16
// Ensure fastapi module was imported
17
17
if ( ! tokens . any ( t => t . text == 'fastapi' && t . type == TokenType . module ) )
18
18
return [ ] ;
19
+
20
+ let prefix = '' ;
19
21
20
22
// Search for "@app.get" decorators
21
- const results : EndpointInfo [ ] = [ ]
23
+ const results : EndpointInfo [ ] = [ ] ;
22
24
for ( let i = 0 ; i < tokens . length - 1 ; i ++ )
23
25
{
24
26
const appToken = tokens [ i ] ;
25
27
const methodToken = tokens [ i + 1 ] ;
26
- if ( appToken . text != 'app' || appToken . type != TokenType . variable || methodToken . type != TokenType . method )
28
+
29
+ //Check if this is a router variable
30
+ if ( appToken . type === TokenType . variable
31
+ && methodToken . type === TokenType . class && methodToken . text === 'APIRouter' ) {
32
+
33
+ const routerLine = document . getText ( new vscode . Range (
34
+ appToken . range . start ,
35
+ new vscode . Position ( methodToken . range . end . line , 1000 ) ) ) ;
36
+
37
+ //extract the prefix
38
+ let match = new RegExp ( `^${ appToken . text } \\s*=\\s*\\APIRouter\\s*\\((.*=.*,\\s*)*prefix=\\s*["'](.*?)["'](ֿֿֿ\\s*,.*=.*)*\\)*\\)` ) . exec ( routerLine ) ;
39
+ if ( match ) {
40
+ prefix = match [ 2 ] ;
41
+ }
42
+
43
+ //Future: use the references to extract the 'include' statement to the router if it contains a prefix
44
+
45
+ // const position =new vscode.Position(appToken.range.start.line,appToken.range.start.character );
46
+
47
+ // let references : vscode.Location[] = await vscode.commands.executeCommand("vscode.executeReferenceProvider", document.uri,position);
48
+ // references = references.filter(x=>x.uri.fsPath!==document.uri.fsPath);
49
+ // if (references.length>0){
50
+ // let referencedDocument = vscode.workspace.openTextDocument(references[0].uri);
51
+ // let text = (await referencedDocument).getText(references[0].range);
52
+ // console.log(text);
53
+
54
+ // }
55
+
56
+
57
+ }
58
+
59
+
60
+ if ( ( appToken . text != 'app' && appToken . text != 'router' ) || appToken . type != TokenType . variable || methodToken . type != TokenType . method )
27
61
continue ;
28
62
29
63
const method = methodToken . text ;
@@ -33,21 +67,37 @@ export class FastapiEndpointExtractor implements IEndpointExtractor
33
67
const lineText = document . getText ( new vscode . Range (
34
68
appToken . range . start ,
35
69
new vscode . Position ( methodToken . range . end . line , 1000 ) ) ) ;
36
- const match = new RegExp ( `^app\\.${ method } \\(["'](.*?)["']` ) . exec ( lineText ) ;
70
+
71
+ let index = 2 ;
72
+ let match = new RegExp ( `^(app|router)\\.${ method } \\(["'](\/.*?)["']` ) . exec ( lineText ) ;
73
+ if ( ! match ) {
74
+ //Different regex for optional params (named)
75
+ match = new RegExp ( `^(app|router)\\.${ method } \\((.*=.*,\\s*)*path=\\s*["'](\\/.*?)["'](ֿֿֿ\\s*,.*=.*)*\\)` ) . exec ( lineText ) ;
76
+ index = 3 ;
77
+ }
78
+
37
79
if ( ! match )
38
80
continue ;
39
81
40
82
const relevantFunc = symbolInfo . firstOrDefault ( s => s . range . contains ( methodToken . range ) )
41
83
if ( ! relevantFunc )
42
84
continue ;
43
85
44
- const path = match [ 1 ] ;
45
- results . push ( new EndpointInfo (
46
- vscode . workspace . getWorkspaceFolder ( document . uri ) ! . name + '$_$' + method + ' ' + match [ 1 ] ,
47
- method ,
48
- path ,
49
- relevantFunc . range ,
50
- document . uri ) ) ;
86
+ const path = match [ index ] ;
87
+ let folder = vscode . workspace . getWorkspaceFolder ( document . uri ) ;
88
+ let folderPrefix = folder ?. uri . path . split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' ) ;
89
+ let relevantPath = document . uri . path . substring ( folderPrefix ! . length ) ;
90
+ let pathParts = relevantPath . split ( '/' ) . filter ( x => x ) ;
91
+ for ( let j = 0 ; j < pathParts . length - 1 ; j ++ ) {
92
+ let possibleRoot = pathParts [ j ] ;
93
+ results . push ( new EndpointInfo (
94
+ possibleRoot + '$_$' + method + ' ' + prefix + path ,
95
+ method ,
96
+ path ,
97
+ relevantFunc . range ,
98
+ document . uri ) ) ;
99
+ }
100
+
51
101
}
52
102
return results ;
53
103
}
0 commit comments