mun_hir 0.4.0

Provides high-level intermediate representation of Mun code
Documentation
use super::Struct;
use crate::diagnostics::ExportedPrivate;
use crate::resolve::HasResolver;
use crate::DiagnosticSink;
use crate::{HasVisibility, Ty, Visibility};

use crate::FileId;
use crate::HirDatabase;

use crate::visibility::RawVisibility;

#[cfg(test)]
mod tests;

pub struct StructValidator<'a> {
    strukt: Struct,
    db: &'a dyn HirDatabase,
    file_id: FileId,
}

impl<'a> StructValidator<'a> {
    pub fn new(strukt: Struct, db: &'a dyn HirDatabase, file_id: FileId) -> Self {
        StructValidator {
            strukt,
            db,
            file_id,
        }
    }

    pub fn validate_privacy(&self, sink: &mut DiagnosticSink) {
        let resolver = self.strukt.id.resolver(self.db.upcast());
        let struct_data = self.strukt.data(self.db.upcast());

        let public_fields = struct_data
            .fields
            .iter()
            .filter(|(_, field_data)| field_data.visibility == RawVisibility::Public);

        let field_types = public_fields.map(|(_, field_data)| {
            let type_ref = field_data.type_ref;
            let (ty, _) = Ty::from_hir(self.db, &resolver, struct_data.type_ref_map(), type_ref);
            (ty, type_ref)
        });

        let struct_visibility = self.strukt.visibility(self.db);
        let type_is_allowed = |ty: &Ty| match struct_visibility {
            Visibility::Module(module_id) => {
                ty.visibility(self.db).is_visible_from(self.db, module_id)
            }
            Visibility::Public => ty.visibility(self.db).is_externally_visible(),
        };

        field_types
            .filter(|(ty, _)| !type_is_allowed(ty))
            .for_each(|(_, type_ref)| {
                sink.push(ExportedPrivate {
                    file: self.file_id,
                    type_ref: struct_data
                        .type_ref_source_map()
                        .type_ref_syntax(type_ref)
                        .unwrap(),
                })
            });
    }
}