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
use crate::semantics::*; use crate::syntax::*; use crate::*; pub struct DuplicateDeclaration; impl DuplicateDeclaration { fn check_kind( kind: DeclarationKind, analysis: &mut Analysis, diagnostics: &mut Vec<Diagnostic>, reported_symbols: &mut Vec<Id>, ) { for scope_root in analysis.navigator.all_scope_roots() { let mut declarations_by_name = HashMap::new(); for declaration in analysis .navigator .all_declarations_in_scope(&scope_root, kind) { if let Some((name, symbol)) = analysis.navigator.symbol_of(&declaration) { if !declarations_by_name.contains_key(&name) { declarations_by_name.insert(name.clone(), vec![]); } declarations_by_name.get_mut(&name).unwrap().push(symbol); } } for (name, declarations) in declarations_by_name { let count = declarations.len(); if count < 2 { continue; } for symbol in declarations { if reported_symbols.contains(&symbol.id) { continue; } diagnostics.push(Diagnostic::DuplicatedDeclaration( symbol.span, name.clone(), count, )); reported_symbols.push(symbol.id); } } } } } impl Checker for DuplicateDeclaration { fn check(&self, analysis: &mut Analysis, diagnostics: &mut Vec<Diagnostic>) { let mut reported_symbols = vec![]; Self::check_kind( DeclarationKind::Type, analysis, diagnostics, &mut reported_symbols, ); Self::check_kind( DeclarationKind::Value, analysis, diagnostics, &mut reported_symbols, ); } }