@@ -406,90 +406,98 @@ impl PythonValidator {
406406 if !symbol. borrow ( ) . is_field_class ( session) {
407407 continue ;
408408 }
409- if let Some ( related_field_name) = eval_weak. as_weak ( ) . context . get ( & S ! ( "related" ) ) . filter ( |val| matches ! ( val, ContextValue :: STRING ( _) ) ) . map ( |ctx_val| ctx_val. as_string ( ) ) {
410- let Some ( special_arg_range) = eval_weak. as_weak ( ) . context . get ( & S ! ( "related_arg_range" ) ) . map ( |ctx_val| ctx_val. as_text_range ( ) ) else {
411- continue ;
412- } ;
413- let syms = PythonArchEval :: get_nested_sub_field ( session, & related_field_name, class. clone ( ) , maybe_from_module. clone ( ) ) ;
414- if syms. is_empty ( ) {
415- if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03014 , & [ & related_field_name, & model_data. name ] ) {
416- self . diagnostics . push ( Diagnostic {
417- range : Range :: new ( Position :: new ( special_arg_range. start ( ) . to_u32 ( ) , 0 ) , Position :: new ( special_arg_range. end ( ) . to_u32 ( ) , 0 ) ) ,
418- ..diagnostic_base. clone ( )
419- } ) ;
420- }
421- continue ;
422- }
423- let Some ( field_type) = symbol
424- . borrow ( )
425- . get_member_symbol ( session, & S ! ( "type" ) , None , false , false , false , false )
426- . 0 . first ( )
427- . and_then ( |field_type_var| field_type_var. borrow ( ) . evaluations ( ) . cloned ( ) )
428- . and_then ( |evals| evals. first ( ) . cloned ( ) )
429- . and_then ( |eval| eval. value . clone ( ) )
430- . and_then ( |value| match value {
431- EvaluationValue :: CONSTANT ( Expr :: StringLiteral ( s) ) => Some ( s. value . to_string ( ) ) ,
432- _ => None ,
433- } ) else {
434- continue ;
435- } ;
436- let found_same_type_match = syms. iter ( ) . any ( |sym|{
437- let related_eval_weaks = Symbol :: follow_ref ( & & EvaluationSymbolPtr :: WEAK ( EvaluationSymbolWeak :: new (
438- Rc :: downgrade ( & sym) ,
439- None ,
440- false ,
441- ) ) , session, & mut None , true , true , None ) ;
442- related_eval_weaks. iter ( ) . any ( |related_eval_weak|{
443- let Some ( related_field_class_sym) = related_eval_weak. upgrade_weak ( ) else {
444- return false
445- } ;
446- let found = related_field_class_sym
447- . borrow ( )
448- . get_member_symbol ( session, & S ! ( "type" ) , None , false , false , false , false )
449- . 0 . first ( )
450- . and_then ( |field_type_var| field_type_var. borrow ( ) . evaluations ( ) . cloned ( ) )
451- . and_then ( |evals| evals. first ( ) . cloned ( ) )
452- . and_then ( |eval| eval. value . clone ( ) )
453- . map ( |value| matches ! ( value, EvaluationValue :: CONSTANT ( Expr :: StringLiteral ( s) ) if s. value. to_string( ) == field_type) )
454- . unwrap_or ( false ) ;
455- found
456- } )
457- } ) ;
458- if !found_same_type_match{
459- if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03017 , & [ ] ) {
460- self . diagnostics . push ( Diagnostic {
461- range : Range :: new ( Position :: new ( special_arg_range. start ( ) . to_u32 ( ) , 0 ) , Position :: new ( special_arg_range. end ( ) . to_u32 ( ) , 0 ) ) ,
462- ..diagnostic_base. clone ( )
463- } ) ;
464- }
465-
466- }
467- } else if let Some ( comodel_field_name) = eval_weak. as_weak ( ) . context . get ( & S ! ( "comodel_name" ) ) . map ( |ctx_val| ctx_val. as_string ( ) ) {
468- let Some ( special_arg_range) = eval_weak. as_weak ( ) . context . get ( & S ! ( "comodel_name_arg_range" ) ) . map ( |ctx_val| ctx_val. as_text_range ( ) ) else {
469- continue ;
470- } ;
471- let maybe_model = session. sync_odoo . models . get ( & Sy ! ( comodel_field_name. clone( ) ) ) ;
472- if maybe_model. map ( |m| m. borrow_mut ( ) . has_symbols ( ) ) . unwrap_or ( false ) {
473- let model = maybe_model. unwrap ( ) . clone ( ) ;
474- let Some ( ref from_module) = maybe_from_module else { continue } ;
475- if !model. clone ( ) . borrow ( ) . model_in_deps ( session, from_module) {
476- if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03015 , & [ & comodel_field_name] ) {
409+ ' related_check: {
410+ if let Some ( related_field_name) = eval_weak. as_weak ( ) . context . get ( & S ! ( "related" ) ) . filter ( |val| matches ! ( val, ContextValue :: STRING ( _) ) ) . map ( |ctx_val| ctx_val. as_string ( ) ) {
411+ let Some ( special_arg_range) = eval_weak. as_weak ( ) . context . get ( & S ! ( "related_arg_range" ) ) . map ( |ctx_val| ctx_val. as_text_range ( ) ) else {
412+ break ' related_check;
413+ } ;
414+ let syms = PythonArchEval :: get_nested_sub_field ( session, & related_field_name, class. clone ( ) , maybe_from_module. clone ( ) ) ;
415+ if syms. is_empty ( ) {
416+ if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03014 , & [ & related_field_name, & model_data. name ] ) {
477417 self . diagnostics . push ( Diagnostic {
478418 range : Range :: new ( Position :: new ( special_arg_range. start ( ) . to_u32 ( ) , 0 ) , Position :: new ( special_arg_range. end ( ) . to_u32 ( ) , 0 ) ) ,
479419 ..diagnostic_base. clone ( )
480420 } ) ;
481421 }
422+ break ' related_check;
482423 }
483- } else {
484- if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03016 , & [ & comodel_field_name] ) {
485- self . diagnostics . push ( Diagnostic {
486- range : Range :: new ( Position :: new ( special_arg_range. start ( ) . to_u32 ( ) , 0 ) , Position :: new ( special_arg_range. end ( ) . to_u32 ( ) , 0 ) ) ,
487- ..diagnostic_base. clone ( )
488- } ) ;
424+ let Some ( field_type) = symbol
425+ . borrow ( )
426+ . get_member_symbol ( session, & S ! ( "type" ) , None , false , false , false , false )
427+ . 0 . first ( )
428+ . and_then ( |field_type_var| field_type_var. borrow ( ) . evaluations ( ) . cloned ( ) )
429+ . and_then ( |evals| evals. first ( ) . cloned ( ) )
430+ . and_then ( |eval| eval. value . clone ( ) )
431+ . and_then ( |value| match value {
432+ EvaluationValue :: CONSTANT ( Expr :: StringLiteral ( s) ) => Some ( s. value . to_string ( ) ) ,
433+ _ => None ,
434+ } ) else {
435+ break ' related_check;
436+ } ;
437+ let found_same_type_match = syms. iter ( ) . any ( |sym|{
438+ let related_eval_weaks = Symbol :: follow_ref ( & & EvaluationSymbolPtr :: WEAK ( EvaluationSymbolWeak :: new (
439+ Rc :: downgrade ( & sym) ,
440+ None ,
441+ false ,
442+ ) ) , session, & mut None , true , true , None ) ;
443+ related_eval_weaks. iter ( ) . any ( |related_eval_weak|{
444+ let Some ( related_field_class_sym) = related_eval_weak. upgrade_weak ( ) else {
445+ return false
446+ } ;
447+ let found = related_field_class_sym
448+ . borrow ( )
449+ . get_member_symbol ( session, & S ! ( "type" ) , None , false , false , false , false )
450+ . 0 . first ( )
451+ . and_then ( |field_type_var| field_type_var. borrow ( ) . evaluations ( ) . cloned ( ) )
452+ . and_then ( |evals| evals. first ( ) . cloned ( ) )
453+ . and_then ( |eval| eval. value . clone ( ) )
454+ . map ( |value| matches ! ( value, EvaluationValue :: CONSTANT ( Expr :: StringLiteral ( s) ) if s. value. to_string( ) == field_type) )
455+ . unwrap_or ( false ) ;
456+ found
457+ } )
458+ } ) ;
459+ if !found_same_type_match{
460+ if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03017 , & [ ] ) {
461+ self . diagnostics . push ( Diagnostic {
462+ range : Range :: new ( Position :: new ( special_arg_range. start ( ) . to_u32 ( ) , 0 ) , Position :: new ( special_arg_range. end ( ) . to_u32 ( ) , 0 ) ) ,
463+ ..diagnostic_base. clone ( )
464+ } ) ;
465+ }
466+
489467 }
468+ }
469+ }
470+ ' comodel_check: {
471+ if let Some ( comodel_field_name) = eval_weak. as_weak ( ) . context . get ( & S ! ( "comodel_name" ) ) . map ( |ctx_val| ctx_val. as_string ( ) ) {
472+ let Some ( special_arg_range) = eval_weak. as_weak ( ) . context . get ( & S ! ( "comodel_name_arg_range" ) ) . map ( |ctx_val| ctx_val. as_text_range ( ) ) else {
473+ break ' comodel_check;
474+ } ;
490475 let Some ( file_symbol) = class_ref. get_file ( ) . and_then ( |file| file. upgrade ( ) ) else {
491- return ;
476+ break ' comodel_check ;
492477 } ;
478+ let maybe_model = session. sync_odoo . models . get ( & Sy ! ( comodel_field_name. clone( ) ) ) ;
479+ if maybe_model. map ( |m| m. borrow_mut ( ) . has_symbols ( ) ) . unwrap_or ( false ) {
480+ let model = maybe_model. unwrap ( ) . clone ( ) ;
481+ file_symbol. borrow_mut ( ) . add_model_dependencies ( & model) ;
482+ let Some ( ref from_module) = maybe_from_module else { break ' comodel_check; } ;
483+ if !model. clone ( ) . borrow ( ) . model_in_deps ( session, from_module) {
484+ if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03015 , & [ & comodel_field_name] ) {
485+ self . diagnostics . push ( Diagnostic {
486+ range : Range :: new ( Position :: new ( special_arg_range. start ( ) . to_u32 ( ) , 0 ) , Position :: new ( special_arg_range. end ( ) . to_u32 ( ) , 0 ) ) ,
487+ ..diagnostic_base. clone ( )
488+ } ) ;
489+ }
490+ } else {
491+ break ' comodel_check;
492+ }
493+ } else {
494+ if let Some ( diagnostic_base) = create_diagnostic ( & session, DiagnosticCode :: OLS03016 , & [ & comodel_field_name] ) {
495+ self . diagnostics . push ( Diagnostic {
496+ range : Range :: new ( Position :: new ( special_arg_range. start ( ) . to_u32 ( ) , 0 ) , Position :: new ( special_arg_range. end ( ) . to_u32 ( ) , 0 ) ) ,
497+ ..diagnostic_base. clone ( )
498+ } ) ;
499+ }
500+ }
493501 file_symbol. borrow_mut ( ) . as_file_mut ( ) . not_found_models . insert ( Sy ! ( comodel_field_name. clone( ) ) , BuildSteps :: ARCH_EVAL ) ;
494502 session. sync_odoo . get_main_entry ( ) . borrow_mut ( ) . not_found_symbols_for_models . insert ( file_symbol. clone ( ) ) ;
495503 }
0 commit comments