@@ -4,8 +4,10 @@ use std::borrow::Cow;
44use std:: cmp:: Ordering ;
55use std:: path:: Path ;
66
7+ use lasso:: { Key , Spur , ThreadedRodeo } ;
78use log:: debug;
89use miette:: { diagnostic, IntoDiagnostic } ;
10+ use odoo_lsp:: model:: Field ;
911use ropey:: Rope ;
1012use tower_lsp:: lsp_types:: * ;
1113use xmlparser:: { StrSpan , Token , Tokenizer } ;
@@ -14,7 +16,7 @@ use odoo_lsp::record::Record;
1416use odoo_lsp:: { utils:: * , ImStr } ;
1517
1618enum RefKind {
17- InheritId ,
19+ Ref ( Spur ) ,
1820 Model ,
1921 Id ,
2022 FieldName ,
@@ -155,21 +157,40 @@ impl Backend {
155157 . expect ( "must be in a module" ) ;
156158
157159 let mut items = vec ! [ ] ;
158- let ( _, cursor_value, ref_kind, model_filter) = gather_refs ( cursor_by_char, & mut reader) ?;
160+ let ( _, cursor_value, ref_kind, model_filter) =
161+ gather_refs ( cursor_by_char, & mut reader, & self . module_index . interner ) ?;
159162 let ( Some ( value) , Some ( record_field) ) = ( cursor_value, ref_kind) else {
160163 return Ok ( None ) ;
161164 } ;
162165 let needle = & value. as_str ( ) [ ..cursor_by_char - value. range ( ) . start ] ;
163166 let replace_range = value. range ( ) . map_unit ( |unit| CharOffset ( unit + relative_offset) ) ;
164167 match record_field {
165- RefKind :: InheritId => self . complete_inherit_id (
166- needle,
167- replace_range,
168- rope. clone ( ) ,
169- model_filter. as_deref ( ) ,
170- & current_module,
171- & mut items,
172- ) ?,
168+ RefKind :: Ref ( relation) => {
169+ let Some ( model) = model_filter else { return Ok ( None ) } ;
170+ let Some ( mut entry) = self . module_index . models . get_mut ( model. as_str ( ) ) else {
171+ return Ok ( None ) ;
172+ } ;
173+ // TODO: Extract into method
174+ let fields = if let Some ( fields) = & entry. fields {
175+ fields
176+ } else {
177+ let range = char_range_to_lsp_range ( replace_range. clone ( ) , rope. clone ( ) ) . unwrap ( ) ;
178+ let fields = self . populate_field_names ( & entry, None , range) . await ?;
179+ entry. fields . insert ( fields)
180+ } ;
181+ let Some ( Field :: Relational ( relation) ) = dbg ! ( fields. get( dbg!( relation) . into_usize( ) as u64 ) ) else {
182+ return Ok ( None ) ;
183+ } ;
184+ self . complete_xml_id (
185+ needle,
186+ replace_range,
187+ rope. clone ( ) ,
188+ Some ( self . module_index . interner . resolve ( relation) ) ,
189+ & current_module,
190+ & mut items,
191+ )
192+ . await ?
193+ }
173194 RefKind :: Model => {
174195 self . complete_model ( needle, replace_range, rope. clone ( ) , & mut items)
175196 . await ?
@@ -194,13 +215,13 @@ impl Backend {
194215 let uri = & params. text_document_position_params . text_document . uri ;
195216 let ( slice, cursor_by_char, _) = self . record_slice ( & rope, uri, position) ?;
196217 let mut reader = Tokenizer :: from ( & slice[ ..] ) ;
197- let ( _, cursor_value, ref_, _) = gather_refs ( cursor_by_char, & mut reader) ?;
218+ let ( _, cursor_value, ref_, _) = gather_refs ( cursor_by_char, & mut reader, & self . module_index . interner ) ?;
198219
199220 let Some ( cursor_value) = cursor_value else {
200221 return Ok ( None ) ;
201222 } ;
202223 match ref_ {
203- Some ( RefKind :: InheritId ) => self . jump_def_inherit_id ( & cursor_value, uri) ,
224+ Some ( RefKind :: Ref ( _ ) ) => self . jump_def_inherit_id ( & cursor_value, uri) ,
204225 Some ( RefKind :: Model ) => self . jump_def_model ( & cursor_value) ,
205226 Some ( RefKind :: Id ) | Some ( RefKind :: FieldName ) | None => Ok ( None ) ,
206227 }
@@ -210,7 +231,7 @@ impl Backend {
210231 let uri = & params. text_document_position . text_document . uri ;
211232 let ( slice, cursor_by_char, _) = self . record_slice ( & rope, uri, position) ?;
212233 let mut reader = Tokenizer :: from ( & slice[ ..] ) ;
213- let ( _, cursor_value, ref_, _) = gather_refs ( cursor_by_char, & mut reader) ?;
234+ let ( _, cursor_value, ref_, _) = gather_refs ( cursor_by_char, & mut reader, & self . module_index . interner ) ?;
214235
215236 let Some ( cursor_value) = cursor_value else {
216237 return Ok ( None ) ;
@@ -221,7 +242,7 @@ impl Backend {
221242 . map ( |ref_| ref_. to_string ( ) ) ;
222243 match ref_ {
223244 Some ( RefKind :: Model ) => self . model_references ( & cursor_value) ,
224- Some ( RefKind :: InheritId ) | Some ( RefKind :: Id ) => {
245+ Some ( RefKind :: Ref ( _ ) ) | Some ( RefKind :: Id ) => {
225246 self . record_references ( & cursor_value, current_module. as_deref ( ) )
226247 }
227248 Some ( RefKind :: FieldName ) | None => Ok ( None ) ,
@@ -232,6 +253,7 @@ impl Backend {
232253fn gather_refs < ' read > (
233254 cursor_by_char : usize ,
234255 reader : & mut Tokenizer < ' read > ,
256+ interner : & ThreadedRodeo ,
235257) -> miette:: Result < ( Option < Tag > , Option < StrSpan < ' read > > , Option < RefKind > , Option < String > ) > {
236258 let mut tag = None ;
237259 let mut cursor_value = None ;
@@ -255,17 +277,19 @@ fn gather_refs<'read>(
255277 } else if local. as_str ( ) == "name" && value_in_range {
256278 cursor_value = Some ( value) ;
257279 ref_kind = Some ( RefKind :: FieldName ) ;
258- } else if local. as_str ( ) == "name" && value. as_str ( ) == "inherit_id" {
259- ref_kind = Some ( RefKind :: InheritId ) ;
280+ } else if local. as_str ( ) == "name" {
281+ let relation = interner. get_or_intern ( value. as_str ( ) ) ;
282+ ref_kind = Some ( RefKind :: Ref ( relation) ) ;
260283 }
261284 }
262285 Ok ( Token :: Attribute { local, value, .. } )
263286 if matches ! ( tag, Some ( Tag :: Template ) )
264287 && local. as_str ( ) == "inherit_id"
265288 && value. range ( ) . contains ( & cursor_by_char) =>
266289 {
290+ let inherit_id = interner. get_or_intern ( "ir.ui.view" ) ;
267291 cursor_value = Some ( value) ;
268- ref_kind = Some ( RefKind :: InheritId ) ;
292+ ref_kind = Some ( RefKind :: Ref ( inherit_id ) ) ;
269293 }
270294 Ok ( Token :: Attribute { local, value, .. } )
271295 if matches ! ( tag, Some ( Tag :: Record ) ) && local. as_str ( ) == "model" =>
0 commit comments