@@ -23,7 +23,7 @@ mod tests;
2323
2424#[ rustfmt:: skip]
2525query ! {
26- PyCompletions ( Request , XmlId , Mapped , MappedTarget , Depends , ReadFn , Model , Prop , ForXmlId , Scope , FieldDescriptor ) ;
26+ PyCompletions ( Request , XmlId , Mapped , MappedTarget , Depends , ReadFn , Model , Prop , ForXmlId , Scope , FieldDescriptor , FieldType ) ;
2727
2828( call [
2929 ( attribute [
@@ -55,9 +55,11 @@ query! {
5555 ( list ( ( string) @MODEL "," ?) * )
5656 ( call
5757 ( attribute
58- ( identifier) @_fields ( identifier) ( #eq? @_fields "fields" ) )
58+ ( identifier) @_fields ( identifier) @ FIELD_TYPE ( #eq? @_fields "fields" ) )
5959 ( argument_list
60- . ( ( comment) * ( string) ? @MODEL )
60+ . [
61+ ( ( comment) + ( string) @MODEL )
62+ ( string) @MODEL ] ?
6163 // handles `related` `compute` `search` and `inverse`
6264 ( ( keyword_argument ( identifier) @FIELD_DESCRIPTOR ( _) ) "," ?) * ) ) ] ) ) ) ) )
6365
@@ -71,15 +73,6 @@ query! {
7173 ( #eq? @_api "api" )
7274 ( #match ? @DEPENDS "^(depends|constrains|onchange)$" ) )
7375
74- ( call [
75- ( identifier) @_Field
76- ( attribute ( identifier) @_fields ( identifier) @_Field) ]
77- ( argument_list
78- . ( ( comment) * . ( string) @MODEL ) ?
79- ( ( keyword_argument ( identifier) @FIELD_DESCRIPTOR ( _) ) "," ?) * )
80- ( #eq? @_fields "fields" )
81- ( #match ? @_Field "^(Many2one|One2many|Many2many)$" ) )
82-
8376( ( call
8477 ( attribute
8578 ( _) @MAPPED_TARGET ( identifier) @_search)
@@ -305,9 +298,6 @@ impl Backend {
305298 if let Some ( local_model) = match_. nodes_for_capture_index ( PyCompletions :: MappedTarget as _ ) . next ( ) {
306299 let model_ = ( self . index ) . model_of_range ( root, local_model. byte_range ( ) . map_unit ( ByteOffset ) , contents) ?;
307300 model = _R ( model_) . to_string ( ) ;
308- } else if let Some ( field_model) = match_. nodes_for_capture_index ( PyCompletions :: Model as _ ) . next ( ) {
309- // A sibling @MODEL node; this is defined on the `fields.*(comodel_name='@MODEL', domain=[..])` pattern
310- model = String :: from_utf8_lossy ( & contents[ field_model. byte_range ( ) . shrink ( 1 ) ] ) . into_owned ( ) ;
311301 } else if let Some ( this_model) = & this_model {
312302 model = String :: from_utf8_lossy ( this_model) . to_string ( ) ;
313303 } else {
@@ -359,6 +349,7 @@ impl Backend {
359349 let query = PyCompletions :: query ( ) ;
360350 let mut cursor = tree_sitter:: QueryCursor :: new ( ) ;
361351 let mut this_model = ThisModel :: default ( ) ;
352+
362353 for match_ in cursor. matches ( query, root, contents) {
363354 for capture in match_. captures {
364355 let range = capture. node . byte_range ( ) ;
@@ -376,12 +367,17 @@ impl Backend {
376367 . next ( )
377368 . map ( |prop| matches ! ( & contents[ prop. byte_range( ) ] , b"_name" | b"_inherit" ) )
378369 . unwrap_or ( true ) ;
379- if is_meta && range. contains ( & offset) {
370+ if range. contains ( & offset) {
380371 let range = range. shrink ( 1 ) ;
381372 let slice = some ! ( rope. get_byte_slice( range. clone( ) ) ) ;
382373 let slice = Cow :: from ( slice) ;
383374 return self . jump_def_model ( & slice) ;
384- } else if range. end < offset {
375+ } else if range. end < offset && is_meta
376+ // match_
377+ // .nodes_for_capture_index(PyCompletions::FieldType as _)
378+ // .next()
379+ // .is_none()
380+ {
385381 this_model. tag_model ( capture. node , & match_, root. byte_range ( ) , contents) ;
386382 }
387383 }
@@ -454,6 +450,7 @@ impl Backend {
454450 | Some ( PyCompletions :: Prop )
455451 | Some ( PyCompletions :: ReadFn )
456452 | Some ( PyCompletions :: Scope )
453+ | Some ( PyCompletions :: FieldType )
457454 | None => { }
458455 }
459456 }
@@ -601,7 +598,12 @@ impl Backend {
601598 let slice = Cow :: from ( slice) ;
602599 let slice = some ! ( _G( slice) ) ;
603600 return self . model_references ( & path, & slice. into ( ) ) ;
604- } else if range. end < offset {
601+ } else if range. end < offset
602+ && match_
603+ . nodes_for_capture_index ( PyCompletions :: FieldType as _ )
604+ . next ( )
605+ . is_none ( )
606+ {
605607 this_model. tag_model ( capture. node , & match_, root. byte_range ( ) , contents) ;
606608 }
607609 }
@@ -639,6 +641,7 @@ impl Backend {
639641 | Some ( PyCompletions :: Prop )
640642 | Some ( PyCompletions :: ReadFn )
641643 | Some ( PyCompletions :: Scope )
644+ | Some ( PyCompletions :: FieldType )
642645 | None => { }
643646 }
644647 }
@@ -770,6 +773,7 @@ impl Backend {
770773 | Some ( PyCompletions :: ReadFn )
771774 | Some ( PyCompletions :: Scope )
772775 | Some ( PyCompletions :: Prop )
776+ | Some ( PyCompletions :: FieldType )
773777 | None => { }
774778 }
775779 }
@@ -799,10 +803,7 @@ impl Backend {
799803 }
800804 }
801805
802- pub ( crate ) async fn python_signature_help (
803- & self ,
804- params : SignatureHelpParams ,
805- ) -> anyhow:: Result < Option < SignatureHelp > > {
806+ pub ( crate ) fn python_signature_help ( & self , params : SignatureHelpParams ) -> anyhow:: Result < Option < SignatureHelp > > {
806807 use std:: fmt:: Write ;
807808
808809 let document =
@@ -856,7 +857,7 @@ impl Backend {
856857 } ;
857858 let method_key = some ! ( _G( & method) ) ;
858859 let rtype = ( self . index ) . resolve_method_returntype ( method_key. into ( ) , model_key. into ( ) ) ;
859- let model = some ! ( ( self . index) . models. get( & model_key. into ( ) ) ) ;
860+ let model = some ! ( ( self . index) . models. get( & model_key) ) ;
860861 let method_obj = some ! ( some!( model. methods. as_ref( ) ) . get( & method_key. into( ) ) ) ;
861862
862863 let mut label = format ! ( "{}(" , method) ;
@@ -944,21 +945,13 @@ impl<'this> ThisModel<'this> {
944945 top_level_range : core:: ops:: Range < usize > ,
945946 contents : & ' this [ u8 ] ,
946947 ) {
947- // sanity check: if tagged as part of a call expression, it must be a relational field declaration
948- match model. parent ( ) {
949- Some ( parent) if parent. kind ( ) == "argument_list" => {
950- // (call (argument_list ..))
951- let call = parent. parent ( ) . unwrap ( ) ;
952- // either fields.Many2one OR Many2one
953- let mut attr = call. named_child ( 0 ) . unwrap ( ) ;
954- if attr. kind ( ) == "attribute" {
955- attr = attr. named_child ( 1 ) . unwrap ( ) ;
956- }
957- if !matches ! ( & contents[ attr. byte_range( ) ] , b"Many2one" | b"One2many" | b"Many2many" ) {
958- return ;
959- }
960- }
961- _ => { }
948+ if match_
949+ . nodes_for_capture_index ( PyCompletions :: FieldType as _ )
950+ . next ( )
951+ . is_some ( )
952+ {
953+ // debug_assert!(false, "tag_model called on a class model; handle this manually");
954+ return ;
962955 }
963956
964957 debug_assert_eq ! ( model. kind( ) , "string" ) ;
0 commit comments