use crate::collections::HashSet;
use crate::{ConstValue, Hash, Id, Item, Location, SourceId, Span, Visibility};
use std::fmt;
use std::path::PathBuf;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct CompileMetaCapture {
pub ident: Box<str>,
}
#[derive(Debug, Clone)]
pub struct CompileMeta {
pub item: Arc<CompileItem>,
pub kind: CompileMetaKind,
pub source: Option<CompileSource>,
}
#[derive(Debug, Clone)]
pub struct CompileSource {
pub source_id: SourceId,
pub span: Span,
pub path: Option<PathBuf>,
}
impl CompileMeta {
pub fn type_hash_of(&self) -> Option<Hash> {
match &self.kind {
CompileMetaKind::UnitStruct { type_hash, .. } => Some(*type_hash),
CompileMetaKind::TupleStruct { type_hash, .. } => Some(*type_hash),
CompileMetaKind::Struct { type_hash, .. } => Some(*type_hash),
CompileMetaKind::Enum { type_hash, .. } => Some(*type_hash),
CompileMetaKind::Function { type_hash, .. } => Some(*type_hash),
CompileMetaKind::Closure { type_hash, .. } => Some(*type_hash),
CompileMetaKind::AsyncBlock { type_hash, .. } => Some(*type_hash),
CompileMetaKind::UnitVariant { .. } => None,
CompileMetaKind::TupleVariant { .. } => None,
CompileMetaKind::StructVariant { .. } => None,
CompileMetaKind::Const { .. } => None,
CompileMetaKind::ConstFn { .. } => None,
CompileMetaKind::Import { .. } => None,
}
}
}
impl fmt::Display for CompileMeta {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.kind {
CompileMetaKind::UnitStruct { .. } => {
write!(fmt, "struct {}", self.item.item)?;
}
CompileMetaKind::TupleStruct { .. } => {
write!(fmt, "struct {}", self.item.item)?;
}
CompileMetaKind::Struct { .. } => {
write!(fmt, "struct {}", self.item.item)?;
}
CompileMetaKind::UnitVariant { .. } => {
write!(fmt, "unit variant {}", self.item.item)?;
}
CompileMetaKind::TupleVariant { .. } => {
write!(fmt, "variant {}", self.item.item)?;
}
CompileMetaKind::StructVariant { .. } => {
write!(fmt, "variant {}", self.item.item)?;
}
CompileMetaKind::Enum { .. } => {
write!(fmt, "enum {}", self.item.item)?;
}
CompileMetaKind::Function { .. } => {
write!(fmt, "fn {}", self.item.item)?;
}
CompileMetaKind::Closure { .. } => {
write!(fmt, "closure {}", self.item.item)?;
}
CompileMetaKind::AsyncBlock { .. } => {
write!(fmt, "async block {}", self.item.item)?;
}
CompileMetaKind::Const { .. } => {
write!(fmt, "const {}", self.item.item)?;
}
CompileMetaKind::ConstFn { .. } => {
write!(fmt, "const fn {}", self.item.item)?;
}
CompileMetaKind::Import { .. } => {
write!(fmt, "import {}", self.item.item)?;
}
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub enum CompileMetaKind {
UnitStruct {
type_hash: Hash,
empty: CompileMetaEmpty,
},
TupleStruct {
type_hash: Hash,
tuple: CompileMetaTuple,
},
Struct {
type_hash: Hash,
object: CompileMetaStruct,
},
UnitVariant {
type_hash: Hash,
enum_item: Item,
empty: CompileMetaEmpty,
},
TupleVariant {
type_hash: Hash,
enum_item: Item,
tuple: CompileMetaTuple,
},
StructVariant {
type_hash: Hash,
enum_item: Item,
object: CompileMetaStruct,
},
Enum {
type_hash: Hash,
},
Function {
type_hash: Hash,
is_test: bool,
},
Closure {
type_hash: Hash,
captures: Arc<[CompileMetaCapture]>,
do_move: bool,
},
AsyncBlock {
type_hash: Hash,
captures: Arc<[CompileMetaCapture]>,
do_move: bool,
},
Const {
const_value: ConstValue,
},
ConstFn {
id: Id,
is_test: bool,
},
Import {
module: Arc<CompileMod>,
location: Location,
target: Item,
},
}
#[derive(Debug, Clone)]
pub struct CompileMetaEmpty {
pub hash: Hash,
}
#[derive(Debug, Clone)]
pub struct CompileMetaStruct {
pub fields: HashSet<Box<str>>,
}
#[derive(Debug, Clone)]
pub struct CompileMetaTuple {
pub args: usize,
pub hash: Hash,
}
#[derive(Default, Debug, Clone)]
pub struct CompileItem {
pub id: Id,
pub location: Location,
pub item: Item,
pub visibility: Visibility,
pub module: Arc<CompileMod>,
}
impl CompileItem {
pub fn is_public(&self) -> bool {
self.visibility.is_public() && self.module.is_public()
}
}
impl From<Item> for CompileItem {
fn from(item: Item) -> Self {
Self {
id: Default::default(),
location: Default::default(),
item,
visibility: Default::default(),
module: Default::default(),
}
}
}
#[derive(Default, Debug)]
pub struct CompileMod {
pub location: Location,
pub item: Item,
pub visibility: Visibility,
pub parent: Option<Arc<CompileMod>>,
}
impl CompileMod {
pub fn is_public(&self) -> bool {
let mut current = Some(self);
while let Some(m) = current.take() {
if !m.visibility.is_public() {
return false;
}
current = m.parent.as_deref();
}
true
}
}