1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
use crate::semantics::*; use crate::syntax::*; use crate::*; pub struct InvalidInherit; impl InvalidInherit { fn check_is_directive( &self, directive: &Node, analysis: &mut Analysis, diagnostics: &mut Vec<Diagnostic>, ) -> Option<()> { let class = analysis.navigator.closest_class_upwards(directive)?; if let IsDirective { type_expression, .. } = directive.kind { let type_expression = analysis.navigator.find_child(directive, type_expression)?; let super_type = analysis.types.get_type_of_type_expression(&type_expression); let sub_type = analysis.types.get_type_of_declaration(&class); self.check_inherit( type_expression.span, super_type, sub_type, analysis, diagnostics, )?; } None } fn check_inherit( &self, span: Span, super_type: Type, sub_type: Type, analysis: &mut Analysis, diagnostics: &mut Vec<Diagnostic>, ) -> Option<()> { let mut violations = vec![]; 'super_behaviours: for super_behaviour in analysis.types.get_behaviours(&super_type) { let super_selector = super_behaviour.selector(); for sub_behaviour in analysis.types.get_behaviours(&sub_type) { let sub_selector = sub_behaviour.selector(); if super_selector == sub_selector { let super_behaviour_type = analysis.types.get_type_of_behaviour(&super_behaviour); let sub_behaviour_type = analysis.types.get_type_of_behaviour(&sub_behaviour); let assignment = check_assignment( super_behaviour_type.clone(), sub_behaviour_type.clone(), &analysis.navigator, &analysis.types, false, ); if assignment.is_invalid() { violations.push(InheritanceViolation::OverrideNotSound( super_behaviour.clone(), assignment, )); } continue 'super_behaviours; } } violations.push(InheritanceViolation::BehaviourNotImplemented( super_behaviour, )); } if violations.len() > 0 { diagnostics.push(Diagnostic::InvalidInherit { span, super_type, sub_type, violations, }); } None } } impl Checker for InvalidInherit { fn check(&self, analysis: &mut Analysis, diagnostics: &mut Vec<Diagnostic>) { for is_directive in analysis.navigator.all_is_directives() { self.check_is_directive(&is_directive, analysis, diagnostics) .unwrap_or(()); } } }