mod body;
mod checks;
mod collect;
mod names;
mod targets;
use std::collections::BTreeMap;
use wolf_ast::{File, NodeId};
use wolf_diag::Diagnostic;
use wolf_project::{ConfigOverride, Kind};
use wolf_span::{FileId, Span};
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Role {
Prelude,
Std,
Entry,
Src,
Test,
Example,
Native,
}
pub type NativeNames =
std::collections::BTreeMap<String, std::collections::BTreeMap<String, String>>;
pub const UNREADABLE: &str = "*";
pub struct ModuleInput<'a> {
pub path: Vec<String>,
pub role: Role,
pub file: FileId,
pub ast: &'a File,
}
pub struct ProjectInfo<'a> {
pub kind: Kind,
pub config: &'a [ConfigOverride],
pub native: &'a NativeNames,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ModuleId(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct DefId(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct LocalId(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DefKind {
Struct,
Enum,
Alias,
IntrinsicType,
Interface,
Fn,
Config,
ExternFn,
ExternType,
Variant {
parent: DefId,
payload: Payload,
},
Member {
owner: DefId,
method: bool,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Payload {
None,
Tuple,
Struct,
}
impl DefKind {
pub fn is_type(self) -> bool {
matches!(
self,
DefKind::Struct
| DefKind::Enum
| DefKind::Alias
| DefKind::IntrinsicType
| DefKind::Interface
| DefKind::ExternType
)
}
fn describe(self) -> &'static str {
match self {
DefKind::Struct => "struct",
DefKind::Enum => "enum",
DefKind::Alias => "type alias",
DefKind::IntrinsicType => "built-in type",
DefKind::Interface => "interface",
DefKind::Fn => "function",
DefKind::Config => "constant",
DefKind::ExternFn => "extern function",
DefKind::ExternType => "extern type",
DefKind::Variant { .. } => "variant",
DefKind::Member { method: true, .. } => "method",
DefKind::Member { method: false, .. } => "associated function",
}
}
}
#[derive(Clone, Debug)]
pub struct Def {
pub kind: DefKind,
pub name: String,
pub module: ModuleId,
pub public: bool,
pub span: Span,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Res {
Def(DefId),
Module(ModuleId),
Local(LocalId),
TypeParam(Span),
SelfType,
}
#[derive(Clone, Debug)]
pub struct Local {
pub name: String,
pub span: Span,
}
#[derive(Clone, Debug)]
pub struct ModuleInfo {
pub path: Vec<String>,
pub role: Role,
pub file: FileId,
pub items: BTreeMap<String, DefId>,
}
#[derive(Debug, Default)]
pub struct Resolved {
pub modules: Vec<ModuleInfo>,
pub defs: Vec<Def>,
pub locals: Vec<Local>,
pub res: BTreeMap<(FileId, NodeId), Res>,
pub local_decls: BTreeMap<Span, LocalId>,
pub members: BTreeMap<DefId, BTreeMap<String, DefId>>,
pub impls: BTreeMap<(ModuleId, usize, usize), DefId>,
pub diagnostics: Vec<Diagnostic>,
}
impl Resolved {
pub fn def(&self, id: DefId) -> Option<&Def> {
self.defs.get(id.0 as usize)
}
}
pub fn resolve(modules: &[ModuleInput<'_>], project: &ProjectInfo<'_>) -> Resolved {
let mut resolver = collect::Resolver::new(modules, project);
resolver.collect();
resolver.resolve_bodies();
resolver.finish()
}
pub use names::{is_pascal_case, is_snake_case, suggest};
pub use targets::{check_target, check_vm};