use std::sync::RwLock;
use hashbrown::HashMap;
use crate::{decl_engine::*, language::ty, monomorphize::priv_prelude::*, Engines, TypeEngine};
pub(crate) struct InstructContext<'a> {
pub(crate) type_engine: &'a TypeEngine,
pub(crate) decl_engine: &'a DeclEngine,
instructions: &'a RwLock<InstructionItems>,
}
impl<'a> InstructContext<'a> {
pub(crate) fn from_root(
engines: Engines<'a>,
instructions: &'a RwLock<InstructionItems>,
) -> Self {
Self::from_module_namespace(engines, instructions)
}
fn from_module_namespace(
engines: Engines<'a>,
instructions: &'a RwLock<InstructionItems>,
) -> Self {
let (type_engine, decl_engine) = engines.unwrap();
Self {
type_engine,
decl_engine,
instructions,
}
}
pub(crate) fn by_ref(&mut self) -> InstructContext<'_> {
InstructContext {
type_engine: self.type_engine,
decl_engine: self.decl_engine,
instructions: self.instructions,
}
}
pub(crate) fn scoped(self) -> InstructContext<'a> {
InstructContext {
type_engine: self.type_engine,
decl_engine: self.decl_engine,
instructions: self.instructions,
}
}
}
type FnMap = HashMap<DeclId<ty::TyFunctionDecl>, Vec<Instruction>>;
type TraitMap = HashMap<DeclId<ty::TyTraitDecl>, Vec<Instruction>>;
type ImplTraitMap = HashMap<DeclId<ty::TyImplTrait>, Vec<Instruction>>;
type StructMap = HashMap<DeclId<ty::TyStructDecl>, Vec<Instruction>>;
type EnumMap = HashMap<DeclId<ty::TyEnumDecl>, Vec<Instruction>>;
pub(crate) struct InstructionItems {
fn_map: FnMap,
trait_map: TraitMap,
impl_trait_map: ImplTraitMap,
struct_map: StructMap,
enum_map: EnumMap,
instructions: Vec<Instruction>,
}
impl InstructionItems {
pub(crate) fn new(instructions: Vec<Instruction>) -> InstructionItems {
let mut fn_map: FnMap = HashMap::new();
let mut trait_map: TraitMap = HashMap::new();
let mut impl_trait_map: ImplTraitMap = HashMap::new();
let mut struct_map: StructMap = HashMap::new();
let mut enum_map: EnumMap = HashMap::new();
let mut leftovers = vec![];
for instruction in instructions.into_iter() {
match &instruction {
Instruction::FnDecl(decl_id, _) => {
let v = fn_map.entry(*decl_id).or_default();
v.push(instruction);
}
Instruction::TraitDecl(decl_id, _) => {
let v = trait_map.entry(*decl_id).or_default();
v.push(instruction);
}
Instruction::ImplTrait(decl_id, _) => {
let v = impl_trait_map.entry(*decl_id).or_default();
v.push(instruction);
}
Instruction::StructDecl(decl_id, _) => {
let v = struct_map.entry(*decl_id).or_default();
v.push(instruction);
}
Instruction::EnumDecl(decl_id, _) => {
let v = enum_map.entry(*decl_id).or_default();
v.push(instruction);
}
_ => {
leftovers.push(instruction);
}
}
}
InstructionItems {
fn_map,
trait_map,
impl_trait_map,
struct_map,
enum_map,
instructions: leftovers,
}
}
}