11use lsp_types:: notification:: { Notification , PublishDiagnostics } ;
22use ropey:: Rope ;
3- use ruff_python_ast:: Mod ;
3+ use ruff_python_ast:: { AnyRootNodeRef , Mod , ModModule , PySourceType , Stmt } ;
44use ruff_python_parser:: { Mode , ParseOptions , Parsed , Token , TokenKind } ;
55use lsp_types:: { Diagnostic , DiagnosticSeverity , MessageType , NumberOrString , Position , PublishDiagnosticsParams , Range , TextDocumentContentChangeEvent } ;
66use tracing:: { error, warn} ;
@@ -9,9 +9,11 @@ use std::collections::HashSet;
99use std:: hash:: { Hash , Hasher } ;
1010use std:: path:: PathBuf ;
1111use std:: str:: FromStr ;
12+ use std:: sync:: Arc ;
1213use std:: { collections:: HashMap , fs} ;
1314use crate :: core:: config:: DiagnosticFilter ;
1415use crate :: core:: diagnostics:: { create_diagnostic, DiagnosticCode , DiagnosticSetting } ;
16+ use crate :: features:: node_index_ast:: IndexedModule ;
1517use crate :: threads:: SessionInfo ;
1618use crate :: utils:: PathSanitizer ;
1719use std:: rc:: Rc ;
@@ -58,10 +60,16 @@ pub enum AstType {
5860pub struct FileInfoAst {
5961 pub text_hash : u64 ,
6062 pub text_rope : Option < ropey:: Rope > ,
61- pub ast : Option < Vec < ruff_python_ast :: Stmt > > ,
63+ pub indexed_module : Option < Arc < IndexedModule > > ,
6264 pub ast_type : AstType ,
6365}
6466
67+ impl FileInfoAst {
68+ pub fn get_stmts ( & self ) -> Option < & Vec < Stmt > > {
69+ self . indexed_module . as_ref ( ) . map ( |module| & module. parsed . syntax ( ) . body )
70+ }
71+ }
72+
6573#[ derive( Debug ) ]
6674pub struct FileInfo {
6775 pub version : i32 ,
@@ -87,7 +95,7 @@ impl FileInfo {
8795 file_info_ast : Rc :: new ( RefCell :: new ( FileInfoAst {
8896 text_hash : 0 ,
8997 text_rope : None ,
90- ast : None ,
98+ indexed_module : None ,
9199 ast_type : AstType :: Python ,
92100 } ) ) ,
93101 diagnostics : HashMap :: new ( ) ,
@@ -159,14 +167,20 @@ impl FileInfo {
159167 let content = & fia. text_rope . as_ref ( ) . unwrap ( ) . slice ( ..) ;
160168 let source = content. to_string ( ) ; //cast to string to get a version with all changes
161169 drop ( fia) ;
162- let ast = ruff_python_parser:: parse_unchecked ( source. as_str ( ) , ParseOptions :: from ( Mode :: Module ) ) ;
170+ let mut python_source_type = PySourceType :: Python ;
171+ if self . uri . ends_with ( ".pyi" ) {
172+ python_source_type = PySourceType :: Stub ;
173+ } else if self . uri . ends_with ( ".ipynb" ) {
174+ python_source_type = PySourceType :: Ipynb ;
175+ }
176+ let parsed_module = ruff_python_parser:: parse_unchecked_source ( source. as_str ( ) , python_source_type) ;
163177 if in_workspace {
164178 self . noqas_blocs . clear ( ) ;
165179 self . noqas_lines . clear ( ) ;
166- self . extract_tokens ( & ast , & source) ;
180+ self . extract_tokens ( & parsed_module , & source) ;
167181 }
168182 self . valid = true ;
169- for error in ast . errors ( ) . iter ( ) {
183+ for error in parsed_module . errors ( ) . iter ( ) {
170184 self . valid = false ;
171185 if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS01000 , & [ ] ) {
172186 diagnostics. push ( Diagnostic {
@@ -179,15 +193,7 @@ impl FileInfo {
179193 } ) ;
180194 }
181195 }
182- match ast. into_syntax ( ) {
183- Mod :: Expression ( _expr) => {
184- warn ! ( "No support for expression-file only" ) ;
185- self . file_info_ast . borrow_mut ( ) . ast = None
186- } ,
187- Mod :: Module ( module) => {
188- self . file_info_ast . borrow_mut ( ) . ast = Some ( module. body ) ;
189- }
190- }
196+ self . file_info_ast . borrow_mut ( ) . indexed_module = Some ( IndexedModule :: new ( parsed_module) ) ;
191197 self . replace_diagnostics ( BuildSteps :: SYNTAX , diagnostics) ;
192198 }
193199
@@ -209,11 +215,11 @@ impl FileInfo {
209215 self . _build_ast ( session, session. sync_odoo . get_file_mgr ( ) . borrow ( ) . is_in_workspace ( & self . uri ) ) ;
210216 }
211217
212- pub fn extract_tokens ( & mut self , ast : & Parsed < Mod > , source : & String ) {
218+ pub fn extract_tokens ( & mut self , parsed_module : & Parsed < ModModule > , source : & String ) {
213219 let mut is_first_expr: bool = true ;
214220 let mut noqa_to_add = None ;
215221 let mut previous_token: Option < & Token > = None ;
216- for token in ast . tokens ( ) . iter ( ) {
222+ for token in parsed_module . tokens ( ) . iter ( ) {
217223 match token. kind ( ) {
218224 TokenKind :: Comment => {
219225 let text = & source[ token. range ( ) ] ;
0 commit comments