cl-typeck: Store def metadata in a Node
I'm not overly proud of this code, but it currently works. Will refactor later.
This commit is contained in:
parent
d7ce33e457
commit
7c73fd335c
@ -5,7 +5,11 @@ use cl_ast::{
|
|||||||
use cl_lexer::Lexer;
|
use cl_lexer::Lexer;
|
||||||
use cl_parser::{inliner::ModuleInliner, Parser};
|
use cl_parser::{inliner::ModuleInliner, Parser};
|
||||||
use cl_typeck::{
|
use cl_typeck::{
|
||||||
definition::Def, name_collector::NameCollector, project::Project, type_resolver::resolve,
|
definition::Def,
|
||||||
|
name_collector::NameCollector,
|
||||||
|
node::{Node, NodeSource},
|
||||||
|
project::Project,
|
||||||
|
type_resolver::resolve,
|
||||||
};
|
};
|
||||||
use repline::{error::Error as RlError, prebaked::*};
|
use repline::{error::Error as RlError, prebaked::*};
|
||||||
use std::{error::Error, path};
|
use std::{error::Error, path};
|
||||||
@ -128,19 +132,26 @@ fn resolve_all(prj: &mut Project) -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
fn list_types(prj: &mut Project) {
|
fn list_types(prj: &mut Project) {
|
||||||
println!(" name\x1b[30G type");
|
println!(" name\x1b[30G type");
|
||||||
for (idx, Def { name, vis, kind, .. }) in prj.pool.iter().enumerate() {
|
for (idx, Def { kind, node: Node { vis, kind: source, .. }, .. }) in prj.pool.iter().enumerate()
|
||||||
|
{
|
||||||
print!("{idx:3}: {vis}");
|
print!("{idx:3}: {vis}");
|
||||||
println!("{name}\x1b[30G| {kind}");
|
if let Some(Some(name)) = source.as_ref().map(NodeSource::name) {
|
||||||
|
print!("{name}");
|
||||||
|
}
|
||||||
|
println!("\x1b[30G| {kind}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pretty_def(def: &Def, id: impl Into<usize>) {
|
fn pretty_def(def: &Def, id: impl Into<usize>) {
|
||||||
let id = id.into();
|
let id = id.into();
|
||||||
let Def { vis, name, kind, module, meta, source } = def;
|
let Def { module, kind, node: Node { meta, vis, kind: source, .. } } = def;
|
||||||
for meta in *meta {
|
for meta in *meta {
|
||||||
println!("#[{meta}]")
|
println!("#[{meta}]")
|
||||||
}
|
}
|
||||||
println!("{vis}{name} [id: {id}] = {kind}");
|
if let Some(Some(name)) = source.as_ref().map(NodeSource::name) {
|
||||||
|
print!("{vis}{name} ");
|
||||||
|
}
|
||||||
|
println!("[id: {id}] = {kind}");
|
||||||
if let Some(source) = source {
|
if let Some(source) = source {
|
||||||
println!("Source:\n{C_LISTING}{source}\x1b[0m");
|
println!("Source:\n{C_LISTING}{source}\x1b[0m");
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,53 @@
|
|||||||
use crate::{key::DefID, module::Module};
|
use crate::{
|
||||||
use cl_ast::{Item, Meta, Sym, Visibility};
|
key::DefID,
|
||||||
|
module::Module,
|
||||||
|
node::{Node, NodeSource},
|
||||||
|
};
|
||||||
|
use cl_ast::{Meta, Sym, Visibility};
|
||||||
use std::{fmt::Debug, str::FromStr};
|
use std::{fmt::Debug, str::FromStr};
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Def<'a> {
|
pub struct Def<'a> {
|
||||||
pub name: Sym,
|
pub node: Node<'a>,
|
||||||
pub vis: Visibility,
|
|
||||||
pub meta: &'a [Meta],
|
|
||||||
pub kind: DefKind,
|
pub kind: DefKind,
|
||||||
pub source: Option<&'a Item>,
|
|
||||||
pub module: Module,
|
pub module: Module,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Def<'a> {
|
||||||
|
pub fn with_node(node: Node<'a>) -> Self {
|
||||||
|
Self { node, kind: DefKind::Undecided, module: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Def<'_> {
|
||||||
|
pub fn name(&self) -> Option<Sym> {
|
||||||
|
match self.node.kind {
|
||||||
|
Some(source) => source.name(),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod builder_functions {
|
mod builder_functions {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<'a> Def<'a> {
|
impl<'a> Def<'a> {
|
||||||
pub fn set_name(&mut self, name: Sym) -> &mut Self {
|
|
||||||
self.name = name;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
pub fn set_vis(&mut self, vis: Visibility) -> &mut Self {
|
pub fn set_vis(&mut self, vis: Visibility) -> &mut Self {
|
||||||
self.vis = vis;
|
self.node.vis = vis;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn set_meta(&mut self, meta: &'a [Meta]) -> &mut Self {
|
pub fn set_meta(&mut self, meta: &'a [Meta]) -> &mut Self {
|
||||||
self.meta = meta;
|
self.node.meta = meta;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn set_kind(&mut self, kind: DefKind) -> &mut Self {
|
pub fn set_kind(&mut self, kind: DefKind) -> &mut Self {
|
||||||
self.kind = kind;
|
self.kind = kind;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn set_source(&mut self, source: &'a Item) -> &mut Self {
|
pub fn set_source(&mut self, source: NodeSource<'a>) -> &mut Self {
|
||||||
self.source = Some(source);
|
self.node.kind = Some(source);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn set_module(&mut self, module: Module) -> &mut Self {
|
pub fn set_module(&mut self, module: Module) -> &mut Self {
|
||||||
@ -45,19 +57,6 @@ mod builder_functions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Def<'_> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
name: "".into(),
|
|
||||||
vis: Visibility::Public,
|
|
||||||
meta: Default::default(),
|
|
||||||
kind: Default::default(),
|
|
||||||
source: Default::default(),
|
|
||||||
module: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, PartialEq, Eq)]
|
#[derive(Clone, Default, Debug, PartialEq, Eq)]
|
||||||
pub enum DefKind {
|
pub enum DefKind {
|
||||||
/// An unevaluated definition
|
/// An unevaluated definition
|
||||||
@ -79,6 +78,7 @@ pub enum DefKind {
|
|||||||
pub enum ValueKind {
|
pub enum ValueKind {
|
||||||
Const(DefID),
|
Const(DefID),
|
||||||
Static(DefID),
|
Static(DefID),
|
||||||
|
Local(DefID),
|
||||||
Fn(DefID),
|
Fn(DefID),
|
||||||
}
|
}
|
||||||
/// A [TypeKind] represents an item in the Type Namespace
|
/// A [TypeKind] represents an item in the Type Namespace
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//! [Display] implementations for [TypeKind], [Adt], and [Intrinsic]
|
//! [Display] implementations for [TypeKind], [Adt], and [Intrinsic]
|
||||||
|
|
||||||
|
use crate::node::Node;
|
||||||
|
|
||||||
use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind};
|
use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind};
|
||||||
use cl_ast::format::FmtAdapter;
|
use cl_ast::format::FmtAdapter;
|
||||||
use std::{
|
use std::{
|
||||||
@ -30,16 +32,20 @@ where
|
|||||||
|
|
||||||
impl Display for Def<'_> {
|
impl Display for Def<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { name, vis, meta, kind, source, module } = self;
|
let Self { module, node: Node { in_path: _, span: _, meta, vis, kind: source }, kind } =
|
||||||
|
self;
|
||||||
if !meta.is_empty() {
|
if !meta.is_empty() {
|
||||||
writeln!(f, "#{meta:?}")?;
|
writeln!(f, "#{meta:?}")?;
|
||||||
}
|
}
|
||||||
writeln!(f, "{vis}{name}: ")?;
|
|
||||||
writeln!(f, "kind: {kind}")?;
|
|
||||||
if let Some(source) = source {
|
if let Some(source) = source {
|
||||||
writeln!(f, "source:")?;
|
if let Some(name) = source.name() {
|
||||||
writeln!(f.indent(), "\n{source}")?;
|
writeln!(f, "{vis}{name}:")?;
|
||||||
|
}
|
||||||
|
writeln!(f.indent(), "source:\n{source}")?;
|
||||||
|
} else {
|
||||||
|
writeln!(f, "{vis}: ")?;
|
||||||
}
|
}
|
||||||
|
writeln!(f, "kind: {kind}")?;
|
||||||
write!(f, "module: {module}")
|
write!(f, "module: {module}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,6 +67,7 @@ impl std::fmt::Display for ValueKind {
|
|||||||
match self {
|
match self {
|
||||||
ValueKind::Const(id) => write!(f, "const ({id})"),
|
ValueKind::Const(id) => write!(f, "const ({id})"),
|
||||||
ValueKind::Static(id) => write!(f, "static ({id})"),
|
ValueKind::Static(id) => write!(f, "static ({id})"),
|
||||||
|
ValueKind::Local(id) => write!(f, "let ({id})"),
|
||||||
ValueKind::Fn(id) => write!(f, "fn def ({id})"),
|
ValueKind::Fn(id) => write!(f, "fn def ({id})"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use crate::{
|
|||||||
definition::{Def, DefKind},
|
definition::{Def, DefKind},
|
||||||
key::DefID,
|
key::DefID,
|
||||||
module::Module as Mod,
|
module::Module as Mod,
|
||||||
|
node::{Node, NodeSource},
|
||||||
project::Project as Prj,
|
project::Project as Prj,
|
||||||
};
|
};
|
||||||
use cl_ast::{ast_visitor::Visit, *};
|
use cl_ast::{ast_visitor::Visit, *};
|
||||||
@ -10,6 +11,7 @@ use std::mem;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NameCollector<'prj, 'a> {
|
pub struct NameCollector<'prj, 'a> {
|
||||||
|
path: cl_ast::Path,
|
||||||
prj: &'prj mut Prj<'a>,
|
prj: &'prj mut Prj<'a>,
|
||||||
parent: DefID,
|
parent: DefID,
|
||||||
retval: Option<DefID>,
|
retval: Option<DefID>,
|
||||||
@ -18,11 +20,11 @@ pub struct NameCollector<'prj, 'a> {
|
|||||||
impl<'prj, 'a> NameCollector<'prj, 'a> {
|
impl<'prj, 'a> NameCollector<'prj, 'a> {
|
||||||
/// Constructs a new [NameCollector] out of a [Project](Prj)
|
/// Constructs a new [NameCollector] out of a [Project](Prj)
|
||||||
pub fn new(prj: &'prj mut Prj<'a>) -> Self {
|
pub fn new(prj: &'prj mut Prj<'a>) -> Self {
|
||||||
Self { parent: prj.root, prj, retval: None }
|
Self { parent: prj.root, prj, path: Default::default(), retval: None }
|
||||||
}
|
}
|
||||||
/// Constructs a new [NameCollector] out of a [Project](Prj) and a parent [DefID]
|
/// Constructs a new [NameCollector] out of a [Project](Prj) and a parent [DefID]
|
||||||
pub fn with_root(prj: &'prj mut Prj<'a>, parent: DefID) -> Self {
|
pub fn with_root(prj: &'prj mut Prj<'a>, parent: DefID) -> Self {
|
||||||
Self { prj, parent, retval: None }
|
Self { prj, parent, path: Default::default(), retval: None }
|
||||||
}
|
}
|
||||||
/// Runs the provided function with the given parent
|
/// Runs the provided function with the given parent
|
||||||
pub fn with_parent<F, N>(&mut self, parent: DefID, node: N, f: F)
|
pub fn with_parent<F, N>(&mut self, parent: DefID, node: N, f: F)
|
||||||
@ -44,49 +46,78 @@ impl<'prj, 'a> Visit<'a> for NameCollector<'prj, 'a> {
|
|||||||
fn visit_item(&mut self, i: &'a Item) {
|
fn visit_item(&mut self, i: &'a Item) {
|
||||||
let Item { extents: _, attrs, vis, kind } = i;
|
let Item { extents: _, attrs, vis, kind } = i;
|
||||||
if let Some(def) = self.returns(kind, Self::visit_item_kind) {
|
if let Some(def) = self.returns(kind, Self::visit_item_kind) {
|
||||||
self.prj[def]
|
self.prj[def].set_meta(&attrs.meta).set_vis(*vis);
|
||||||
.set_meta(&attrs.meta)
|
|
||||||
.set_vis(*vis)
|
|
||||||
.set_source(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_module(&mut self, m: &'a Module) {
|
fn visit_module(&mut self, m: &'a Module) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Module { name: Identifier(name), kind } = m;
|
let Module { name: Identifier(name), kind } = m;
|
||||||
|
|
||||||
let def = Def { name: *name, module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Module(m))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.insert_type(*name, id);
|
prj[*parent].module.insert_type(*name, id);
|
||||||
|
self.path.push(PathPart::Ident(Identifier(*name)));
|
||||||
self.with_parent(id, kind, Self::visit_module_kind);
|
self.with_parent(id, kind, Self::visit_module_kind);
|
||||||
|
self.path.pop();
|
||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
fn visit_alias(&mut self, a: &'a Alias) {
|
fn visit_alias(&mut self, a: &'a Alias) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Alias { to: Identifier(name), from: _ } = a;
|
let Alias { to: Identifier(name), from: _ } = a;
|
||||||
|
|
||||||
let def = Def { name: *name, module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Alias(a))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.insert_type(*name, id);
|
prj[*parent].module.insert_type(*name, id);
|
||||||
|
|
||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
fn visit_enum(&mut self, e: &'a Enum) {
|
fn visit_enum(&mut self, e: &'a Enum) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Enum { name: Identifier(name), kind } = e;
|
let Enum { name: Identifier(name), kind } = e;
|
||||||
|
|
||||||
let def = Def { name: *name, module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Enum(e))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.insert_type(*name, id);
|
prj[*parent].module.insert_type(*name, id);
|
||||||
|
|
||||||
self.with_parent(id, kind, Self::visit_enum_kind);
|
self.with_parent(id, kind, Self::visit_enum_kind);
|
||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
|
fn visit_variant(&mut self, v: &'a Variant) {
|
||||||
|
let Self { path, prj, parent, retval: _ } = self;
|
||||||
|
let Variant { name: Identifier(name), kind } = v;
|
||||||
|
|
||||||
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Variant(v))),
|
||||||
|
};
|
||||||
|
let id = prj.pool.insert(def);
|
||||||
|
prj[*parent].module.insert_type(*name, id);
|
||||||
|
|
||||||
|
self.with_parent(id, kind, Self::visit_variant_kind);
|
||||||
|
self.retval = Some(id);
|
||||||
|
}
|
||||||
fn visit_struct(&mut self, s: &'a Struct) {
|
fn visit_struct(&mut self, s: &'a Struct) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Struct { name: Identifier(name), kind } = s;
|
let Struct { name: Identifier(name), kind } = s;
|
||||||
|
|
||||||
let def = Def { name: *name, module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Struct(s))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.insert_type(*name, id);
|
prj[*parent].module.insert_type(*name, id);
|
||||||
|
|
||||||
@ -94,10 +125,14 @@ impl<'prj, 'a> Visit<'a> for NameCollector<'prj, 'a> {
|
|||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
fn visit_const(&mut self, c: &'a Const) {
|
fn visit_const(&mut self, c: &'a Const) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Const { name: Identifier(name), ty: _, init } = c;
|
let Const { name: Identifier(name), ty: _, init } = c;
|
||||||
|
|
||||||
let def = Def { name: *name, module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Const(c))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.insert_value(*name, id);
|
prj[*parent].module.insert_value(*name, id);
|
||||||
|
|
||||||
@ -105,10 +140,14 @@ impl<'prj, 'a> Visit<'a> for NameCollector<'prj, 'a> {
|
|||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
fn visit_static(&mut self, s: &'a Static) {
|
fn visit_static(&mut self, s: &'a Static) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Static { name: Identifier(name), mutable: _, ty: _, init } = s;
|
let Static { name: Identifier(name), mutable: _, ty: _, init } = s;
|
||||||
|
|
||||||
let def = Def { name: *name, module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Static(s))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.insert_value(*name, id);
|
prj[*parent].module.insert_value(*name, id);
|
||||||
|
|
||||||
@ -116,10 +155,14 @@ impl<'prj, 'a> Visit<'a> for NameCollector<'prj, 'a> {
|
|||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
fn visit_function(&mut self, f: &'a Function) {
|
fn visit_function(&mut self, f: &'a Function) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Function { name: Identifier(name), body, .. } = f;
|
let Function { name: Identifier(name), body, .. } = f;
|
||||||
|
|
||||||
let def = Def { name: *name, module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Function(f))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.insert_value(*name, id);
|
prj[*parent].module.insert_value(*name, id);
|
||||||
|
|
||||||
@ -129,9 +172,13 @@ impl<'prj, 'a> Visit<'a> for NameCollector<'prj, 'a> {
|
|||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
fn visit_impl(&mut self, i: &'a Impl) {
|
fn visit_impl(&mut self, i: &'a Impl) {
|
||||||
let Self { prj, parent, retval: _ } = self;
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
let Impl { target: _, body } = i;
|
let Impl { target: _, body } = i;
|
||||||
let def = Def { module: Mod::new(*parent), ..Default::default() };
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Impl(i))),
|
||||||
|
};
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
|
|
||||||
// items will get reparented after name collection, when target is available
|
// items will get reparented after name collection, when target is available
|
||||||
@ -139,14 +186,33 @@ impl<'prj, 'a> Visit<'a> for NameCollector<'prj, 'a> {
|
|||||||
|
|
||||||
self.retval = Some(id);
|
self.retval = Some(id);
|
||||||
}
|
}
|
||||||
fn visit_use(&mut self, _u: &'a Use) {
|
fn visit_use(&mut self, u: &'a Use) {
|
||||||
let Self { prj, parent, retval } = self;
|
let Self { prj, parent, path, retval } = self;
|
||||||
let def =
|
let def = Def {
|
||||||
Def { module: Mod::new(*parent), kind: DefKind::Use(*parent), ..Default::default() };
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Use(*parent),
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Use(u))),
|
||||||
|
};
|
||||||
|
|
||||||
let id = prj.pool.insert(def);
|
let id = prj.pool.insert(def);
|
||||||
prj[*parent].module.imports.push(id);
|
prj[*parent].module.imports.push(id);
|
||||||
|
|
||||||
*retval = Some(id);
|
*retval = Some(id);
|
||||||
}
|
}
|
||||||
|
fn visit_let(&mut self, l: &'a Let) {
|
||||||
|
let Self { prj, parent, path, retval: _ } = self;
|
||||||
|
let Let { name: Identifier(name), init, .. } = l;
|
||||||
|
let def = Def {
|
||||||
|
module: Mod::new(*parent),
|
||||||
|
kind: DefKind::Undecided,
|
||||||
|
node: Node::new(path.clone(), Some(NodeSource::Local(l))),
|
||||||
|
};
|
||||||
|
|
||||||
|
let id = prj.pool.insert(def);
|
||||||
|
prj[*parent].module.insert_value(*name, id);
|
||||||
|
if let Some(expr) = init {
|
||||||
|
self.visit_expr(expr)
|
||||||
|
}
|
||||||
|
self.retval = Some(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,23 @@ pub struct Node<'a> {
|
|||||||
pub span: &'a Span,
|
pub span: &'a Span,
|
||||||
pub meta: &'a [Meta],
|
pub meta: &'a [Meta],
|
||||||
pub vis: Visibility,
|
pub vis: Visibility,
|
||||||
pub kind: NodeSource<'a>,
|
pub kind: Option<NodeSource<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Node<'a> {
|
||||||
|
pub fn new(path: Path, kind: Option<NodeSource<'a>>) -> Self {
|
||||||
|
const DUMMY_SPAN: Span = Span::dummy();
|
||||||
|
Self { in_path: path, span: &DUMMY_SPAN, meta: &[], vis: Visibility::Public, kind }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum NodeSource<'a> {
|
pub enum NodeSource<'a> {
|
||||||
|
Root,
|
||||||
Module(&'a Module),
|
Module(&'a Module),
|
||||||
Alias(&'a Alias),
|
Alias(&'a Alias),
|
||||||
Enum(&'a Enum),
|
Enum(&'a Enum),
|
||||||
|
Variant(&'a Variant),
|
||||||
Struct(&'a Struct),
|
Struct(&'a Struct),
|
||||||
Const(&'a Const),
|
Const(&'a Const),
|
||||||
Static(&'a Static),
|
Static(&'a Static),
|
||||||
@ -37,9 +46,11 @@ pub enum NodeSource<'a> {
|
|||||||
impl<'a> NodeSource<'a> {
|
impl<'a> NodeSource<'a> {
|
||||||
pub fn name(&self) -> Option<Sym> {
|
pub fn name(&self) -> Option<Sym> {
|
||||||
match self {
|
match self {
|
||||||
|
NodeSource::Root => None,
|
||||||
NodeSource::Module(v) => Some(v.name.0),
|
NodeSource::Module(v) => Some(v.name.0),
|
||||||
NodeSource::Alias(v) => Some(v.to.0),
|
NodeSource::Alias(v) => Some(v.to.0),
|
||||||
NodeSource::Enum(v) => Some(v.name.0),
|
NodeSource::Enum(v) => Some(v.name.0),
|
||||||
|
NodeSource::Variant(v) => Some(v.name.0),
|
||||||
NodeSource::Struct(v) => Some(v.name.0),
|
NodeSource::Struct(v) => Some(v.name.0),
|
||||||
NodeSource::Const(v) => Some(v.name.0),
|
NodeSource::Const(v) => Some(v.name.0),
|
||||||
NodeSource::Static(v) => Some(v.name.0),
|
NodeSource::Static(v) => Some(v.name.0),
|
||||||
@ -81,9 +92,11 @@ impl<'a> NodeSource<'a> {
|
|||||||
impl fmt::Display for NodeSource<'_> {
|
impl fmt::Display for NodeSource<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
Self::Root => "🌳 root 🌳".fmt(f),
|
||||||
Self::Module(arg0) => arg0.fmt(f),
|
Self::Module(arg0) => arg0.fmt(f),
|
||||||
Self::Alias(arg0) => arg0.fmt(f),
|
Self::Alias(arg0) => arg0.fmt(f),
|
||||||
Self::Enum(arg0) => arg0.fmt(f),
|
Self::Enum(arg0) => arg0.fmt(f),
|
||||||
|
Self::Variant(arg0) => arg0.fmt(f),
|
||||||
Self::Struct(arg0) => arg0.fmt(f),
|
Self::Struct(arg0) => arg0.fmt(f),
|
||||||
Self::Const(arg0) => arg0.fmt(f),
|
Self::Const(arg0) => arg0.fmt(f),
|
||||||
Self::Static(arg0) => arg0.fmt(f),
|
Self::Static(arg0) => arg0.fmt(f),
|
||||||
@ -135,7 +148,7 @@ pub mod sorcerer {
|
|||||||
let Self { path, parts, defs } = self;
|
let Self { path, parts, defs } = self;
|
||||||
let (span, meta, vis) = *parts;
|
let (span, meta, vis) = *parts;
|
||||||
|
|
||||||
defs.push(Node { in_path: path.clone(), span, meta, vis, kind })
|
defs.push(Node { in_path: path.clone(), span, meta, vis, kind: Some(kind) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,10 @@ use crate::{
|
|||||||
definition::{Def, DefKind, TypeKind},
|
definition::{Def, DefKind, TypeKind},
|
||||||
key::DefID,
|
key::DefID,
|
||||||
module,
|
module,
|
||||||
|
node::{Node, NodeSource},
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
use cl_ast::{Identifier, PathPart, TyFn, TyKind, TyRef, TyTuple, Visibility};
|
use cl_ast::{Identifier, PathPart};
|
||||||
use cl_structures::deprecated_intern_pool::Pool;
|
use cl_structures::deprecated_intern_pool::Pool;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
@ -30,35 +31,28 @@ impl Project<'_> {
|
|||||||
|
|
||||||
impl Default for Project<'_> {
|
impl Default for Project<'_> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
const ROOT_PATH: cl_ast::Path = cl_ast::Path { absolute: true, parts: Vec::new() };
|
||||||
|
|
||||||
let mut pool = Pool::default();
|
let mut pool = Pool::default();
|
||||||
let root = pool.insert(Def {
|
let root = pool.insert(Def {
|
||||||
name: "🌳 root 🌳".into(),
|
module: Default::default(),
|
||||||
kind: DefKind::Type(TypeKind::Module),
|
kind: DefKind::Type(TypeKind::Module),
|
||||||
..Default::default()
|
node: Node::new(ROOT_PATH, Some(NodeSource::Root)),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Insert the Never(!) type
|
|
||||||
let never = pool.insert(Def {
|
let never = pool.insert(Def {
|
||||||
name: "!".into(),
|
|
||||||
vis: Visibility::Public,
|
|
||||||
kind: DefKind::Type(TypeKind::Never),
|
|
||||||
module: module::Module::new(root),
|
module: module::Module::new(root),
|
||||||
..Default::default()
|
kind: DefKind::Type(TypeKind::Never),
|
||||||
|
node: Node::new(ROOT_PATH, None),
|
||||||
});
|
});
|
||||||
let empty = pool.insert(Def {
|
let empty = pool.insert(Def {
|
||||||
name: "()".into(),
|
module: module::Module::new(root),
|
||||||
vis: Visibility::Public,
|
|
||||||
kind: DefKind::Type(TypeKind::Empty),
|
kind: DefKind::Type(TypeKind::Empty),
|
||||||
module: module::Module::new(root),
|
node: Node::new(ROOT_PATH, None),
|
||||||
..Default::default()
|
|
||||||
});
|
});
|
||||||
// TODO: Self is not a real type!
|
|
||||||
let selfty = pool.insert(Def {
|
let selfty = pool.insert(Def {
|
||||||
name: "Self".into(),
|
|
||||||
vis: Visibility::Public,
|
|
||||||
kind: DefKind::Type(TypeKind::SelfTy),
|
|
||||||
module: module::Module::new(root),
|
module: module::Module::new(root),
|
||||||
..Default::default()
|
kind: DefKind::Type(TypeKind::SelfTy),
|
||||||
|
node: Node::new(ROOT_PATH, None),
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut anon_types = HashMap::new();
|
let mut anon_types = HashMap::new();
|
||||||
@ -171,7 +165,8 @@ pub mod evaluate {
|
|||||||
//! or an intermediate result of expression evaluation.
|
//! or an intermediate result of expression evaluation.
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use cl_ast::{Sym, Ty};
|
use crate::module;
|
||||||
|
use cl_ast::{Sym, Ty, TyFn, TyKind, TyRef, TyTuple};
|
||||||
|
|
||||||
/// Things that can be evaluated as a type expression
|
/// Things that can be evaluated as a type expression
|
||||||
pub trait EvaluableTypeExpression {
|
pub trait EvaluableTypeExpression {
|
||||||
@ -196,19 +191,7 @@ pub mod evaluate {
|
|||||||
TyKind::Empty => prj.anon_types[&TypeKind::Empty],
|
TyKind::Empty => prj.anon_types[&TypeKind::Empty],
|
||||||
TyKind::SelfTy => prj.anon_types[&TypeKind::SelfTy],
|
TyKind::SelfTy => prj.anon_types[&TypeKind::SelfTy],
|
||||||
// TyKind::Path must be looked up explicitly
|
// TyKind::Path must be looked up explicitly
|
||||||
TyKind::Path(path) => {
|
TyKind::Path(path) => path.evaluate(prj, parent)?,
|
||||||
let (id, path) = prj
|
|
||||||
.get_type(path.into(), parent)
|
|
||||||
.ok_or("Failed to get type")?;
|
|
||||||
if path.is_empty() {
|
|
||||||
id
|
|
||||||
} else {
|
|
||||||
let (id, path) = prj.get_value(path, id).ok_or("Failed to get value")?;
|
|
||||||
path.is_empty()
|
|
||||||
.then_some(id)
|
|
||||||
.ok_or("Path not fully resolved")?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TyKind::Tuple(tup) => tup.evaluate(prj, parent)?,
|
TyKind::Tuple(tup) => tup.evaluate(prj, parent)?,
|
||||||
TyKind::Ref(tyref) => tyref.evaluate(prj, parent)?,
|
TyKind::Ref(tyref) => tyref.evaluate(prj, parent)?,
|
||||||
TyKind::Fn(tyfn) => tyfn.evaluate(prj, parent)?,
|
TyKind::Fn(tyfn) => tyfn.evaluate(prj, parent)?,
|
||||||
@ -228,7 +211,7 @@ pub mod evaluate {
|
|||||||
.types
|
.types
|
||||||
.get(self)
|
.get(self)
|
||||||
.copied()
|
.copied()
|
||||||
.ok_or_else(|| format!("{self} is not a member of {}", prj[parent].name))
|
.ok_or_else(|| format!("{self} is not a member of {:?}", prj[parent].name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,9 +221,9 @@ pub mod evaluate {
|
|||||||
let types = self.types.evaluate(prj, parent)?;
|
let types = self.types.evaluate(prj, parent)?;
|
||||||
let root = prj.root;
|
let root = prj.root;
|
||||||
let id = prj.insert_anonymous_type(TypeKind::Tuple(types.clone()), move || Def {
|
let id = prj.insert_anonymous_type(TypeKind::Tuple(types.clone()), move || Def {
|
||||||
kind: DefKind::Type(TypeKind::Tuple(types)),
|
|
||||||
module: module::Module::new(root),
|
module: module::Module::new(root),
|
||||||
..Default::default()
|
node: Node::new(Default::default(), None),
|
||||||
|
kind: DefKind::Type(TypeKind::Tuple(types)),
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
@ -254,9 +237,9 @@ pub mod evaluate {
|
|||||||
|
|
||||||
let root = prj.root;
|
let root = prj.root;
|
||||||
let id = prj.insert_anonymous_type(TypeKind::Ref(*count, to), move || Def {
|
let id = prj.insert_anonymous_type(TypeKind::Ref(*count, to), move || Def {
|
||||||
kind: DefKind::Type(TypeKind::Ref(*count, to)),
|
|
||||||
module: module::Module::new(root),
|
module: module::Module::new(root),
|
||||||
..Default::default()
|
node: Node::new(Default::default(), None),
|
||||||
|
kind: DefKind::Type(TypeKind::Ref(*count, to)),
|
||||||
});
|
});
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
@ -274,9 +257,9 @@ pub mod evaluate {
|
|||||||
|
|
||||||
let root = prj.root;
|
let root = prj.root;
|
||||||
let id = prj.insert_anonymous_type(TypeKind::FnSig { args, rety }, || Def {
|
let id = prj.insert_anonymous_type(TypeKind::FnSig { args, rety }, || Def {
|
||||||
kind: DefKind::Type(TypeKind::FnSig { args, rety }),
|
|
||||||
module: module::Module::new(root),
|
module: module::Module::new(root),
|
||||||
..Default::default()
|
node: Node::new(Default::default(), None),
|
||||||
|
kind: DefKind::Type(TypeKind::FnSig { args, rety }),
|
||||||
});
|
});
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
@ -304,15 +287,14 @@ pub mod evaluate {
|
|||||||
impl<'a> EvaluableTypeExpression for Path<'a> {
|
impl<'a> EvaluableTypeExpression for Path<'a> {
|
||||||
type Out = DefID;
|
type Out = DefID;
|
||||||
fn evaluate(&self, prj: &mut Project, parent: DefID) -> Result<Self::Out, String> {
|
fn evaluate(&self, prj: &mut Project, parent: DefID) -> Result<Self::Out, String> {
|
||||||
let (id, path) = prj.get_type(*self, parent).ok_or("Failed to get type")?;
|
let (tid, vid, path) = prj.get(*self, parent).ok_or("Failed to traverse path")?;
|
||||||
|
if !path.is_empty() {
|
||||||
if path.is_empty() {
|
Err(format!("Could not traverse past boundary: {path}"))?;
|
||||||
Ok(id)
|
}
|
||||||
} else {
|
match (tid, vid) {
|
||||||
let (id, path) = prj.get_value(path, id).ok_or("Failed to get value")?;
|
(Some(ty), _) => Ok(ty),
|
||||||
path.is_empty()
|
(None, Some(val)) => Ok(val),
|
||||||
.then_some(id)
|
(None, None) => Err(format!("No type or value found at path {self}")),
|
||||||
.ok_or(String::from("Path not fully resolved"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,33 +3,47 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
definition::{Adt, Def, DefKind, TypeKind, ValueKind},
|
definition::{Adt, Def, DefKind, TypeKind, ValueKind},
|
||||||
key::DefID,
|
key::DefID,
|
||||||
module,
|
node::{Node, NodeSource},
|
||||||
project::{evaluate::EvaluableTypeExpression, Project as Prj},
|
project::{evaluate::EvaluableTypeExpression, Project as Prj},
|
||||||
};
|
};
|
||||||
use cl_ast::*;
|
use cl_ast::*;
|
||||||
|
|
||||||
/// Evaluate a single ID
|
/// Evaluate a single ID
|
||||||
pub fn resolve(prj: &mut Prj, id: DefID) -> Result<(), &'static str> {
|
pub fn resolve(prj: &mut Prj, id: DefID) -> Result<(), &'static str> {
|
||||||
let (DefKind::Undecided, Some(source)) = (&prj[id].kind, prj[id].source) else {
|
let Def { node: Node { kind: Some(source), meta, .. }, kind: DefKind::Undecided, .. } = prj[id]
|
||||||
|
else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
let kind = match &source.kind {
|
|
||||||
ItemKind::Alias(_) => "type",
|
|
||||||
ItemKind::Module(_) => "mod",
|
|
||||||
ItemKind::Enum(_) => "enum",
|
|
||||||
ItemKind::Struct(_) => "struct",
|
|
||||||
ItemKind::Const(_) => "const",
|
|
||||||
ItemKind::Static(_) => "static",
|
|
||||||
ItemKind::Function(_) => "fn",
|
|
||||||
ItemKind::Impl(_) => "impl",
|
|
||||||
ItemKind::Use(_) => "use",
|
|
||||||
};
|
|
||||||
eprintln!(
|
|
||||||
"Resolver: \x1b[32mEvaluating\x1b[0m \"\x1b[36m{kind} {}\x1b[0m\" (`{id:?}`)",
|
|
||||||
prj[id].name
|
|
||||||
);
|
|
||||||
|
|
||||||
prj[id].kind = source.resolve_type(prj, id)?;
|
let kind = match &source {
|
||||||
|
NodeSource::Root => "root",
|
||||||
|
NodeSource::Alias(_) => "type",
|
||||||
|
NodeSource::Module(_) => "mod",
|
||||||
|
NodeSource::Enum(_) => "enum",
|
||||||
|
NodeSource::Variant(_) => "variant",
|
||||||
|
NodeSource::Struct(_) => "struct",
|
||||||
|
NodeSource::Const(_) => "const",
|
||||||
|
NodeSource::Static(_) => "static",
|
||||||
|
NodeSource::Function(_) => "fn",
|
||||||
|
NodeSource::Impl(_) => "impl",
|
||||||
|
NodeSource::Use(_) => "use",
|
||||||
|
NodeSource::Local(_) => "let",
|
||||||
|
NodeSource::Ty(_) => "ty",
|
||||||
|
};
|
||||||
|
let name = prj[id].name().unwrap_or("".into());
|
||||||
|
|
||||||
|
eprintln!("Resolver: \x1b[32mEvaluating\x1b[0m \"\x1b[36m{kind} {name}\x1b[0m\" (`{id:?}`)");
|
||||||
|
|
||||||
|
for Meta { name: Identifier(name), kind } in meta {
|
||||||
|
if let ("intrinsic", MetaKind::Equals(Literal::String(s))) = (&**name, kind) {
|
||||||
|
prj[id].kind = DefKind::Type(TypeKind::Intrinsic(
|
||||||
|
s.parse().map_err(|_| "Failed to parse intrinsic")?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if DefKind::Undecided == prj[id].kind {
|
||||||
|
prj[id].kind = source.resolve_type(prj, id)?;
|
||||||
|
}
|
||||||
|
|
||||||
eprintln!("\x1b[33m=> {}\x1b[0m", prj[id].kind);
|
eprintln!("\x1b[33m=> {}\x1b[0m", prj[id].kind);
|
||||||
|
|
||||||
@ -41,28 +55,37 @@ pub trait TypeResolvable<'a> {
|
|||||||
/// The return type upon success
|
/// The return type upon success
|
||||||
type Out;
|
type Out;
|
||||||
/// Resolves type expressions within this node
|
/// Resolves type expressions within this node
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str>;
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Item {
|
impl<'a> TypeResolvable<'a> for NodeSource<'a> {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
|
||||||
let Self { attrs: Attrs { meta }, kind, .. } = self;
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
for meta in meta {
|
match self {
|
||||||
if let Ok(def) = meta.resolve_type(prj, id) {
|
NodeSource::Root => Ok(DefKind::Type(TypeKind::Module)),
|
||||||
return Ok(def);
|
NodeSource::Module(v) => v.resolve_type(prj, id),
|
||||||
}
|
NodeSource::Alias(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Enum(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Variant(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Struct(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Const(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Static(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Function(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Local(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Impl(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Use(v) => v.resolve_type(prj, id),
|
||||||
|
NodeSource::Ty(v) => v.resolve_type(prj, id),
|
||||||
}
|
}
|
||||||
kind.resolve_type(prj, id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Meta {
|
impl<'a> TypeResolvable<'a> for &'a Meta {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let Self { name: Identifier(name), kind } = self;
|
let Meta { name: Identifier(name), kind } = self;
|
||||||
match (name.as_ref(), kind) {
|
match (name.as_ref(), kind) {
|
||||||
("intrinsic", MetaKind::Equals(Literal::String(intrinsic))) => Ok(DefKind::Type(
|
("intrinsic", MetaKind::Equals(Literal::String(intrinsic))) => Ok(DefKind::Type(
|
||||||
TypeKind::Intrinsic(intrinsic.parse().map_err(|_| "unknown intrinsic type")?),
|
TypeKind::Intrinsic(intrinsic.parse().map_err(|_| "unknown intrinsic type")?),
|
||||||
@ -75,64 +98,18 @@ impl<'a> TypeResolvable<'a> for Meta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for ItemKind {
|
impl<'a> TypeResolvable<'a> for &'a Module {
|
||||||
type Out = DefKind;
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
|
||||||
if prj[id].source.map(|s| &s.kind as *const _) != Some(self as *const _) {
|
|
||||||
return Err("id is not self!");
|
|
||||||
}
|
|
||||||
match self {
|
|
||||||
ItemKind::Module(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Impl(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Alias(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Enum(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Struct(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Const(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Static(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Function(i) => i.resolve_type(prj, id),
|
|
||||||
ItemKind::Use(i) => i.resolve_type(prj, id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Module {
|
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
Ok(DefKind::Type(TypeKind::Module))
|
Ok(DefKind::Type(TypeKind::Module))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Impl {
|
impl<'a> TypeResolvable<'a> for &'a Alias {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let parent = prj.parent_of(id).unwrap_or(id);
|
|
||||||
|
|
||||||
let target = match &self.target {
|
|
||||||
ImplKind::Type(t) => t.evaluate(prj, parent),
|
|
||||||
ImplKind::Trait { for_type, .. } => for_type.evaluate(prj, parent),
|
|
||||||
}
|
|
||||||
.map_err(|_| "Unresolved type in impl target")?;
|
|
||||||
|
|
||||||
prj[id].module.parent = Some(target);
|
|
||||||
|
|
||||||
Ok(DefKind::Impl(target))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Use {
|
|
||||||
type Out = DefKind;
|
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
|
||||||
todo!("Resolve types for {self} with ID {id} in {prj:?}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Alias {
|
|
||||||
type Out = DefKind;
|
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
|
||||||
let parent = prj.parent_of(id).unwrap_or(id);
|
let parent = prj.parent_of(id).unwrap_or(id);
|
||||||
let alias = if let Some(ty) = &self.from {
|
let alias = if let Some(ty) = &self.from {
|
||||||
Some(
|
Some(
|
||||||
@ -148,62 +125,57 @@ impl<'a> TypeResolvable<'a> for Alias {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Enum {
|
impl<'a> TypeResolvable<'a> for &'a Enum {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let Self { name: _, kind } = self;
|
let Enum { name: _, kind } = self;
|
||||||
let EnumKind::Variants(v) = kind else {
|
let EnumKind::Variants(v) = kind else {
|
||||||
return Ok(DefKind::Type(TypeKind::Adt(Adt::FieldlessEnum)));
|
return Ok(DefKind::Type(TypeKind::Adt(Adt::FieldlessEnum)));
|
||||||
};
|
};
|
||||||
let mut fields = vec![];
|
let mut fields = vec![];
|
||||||
for v @ Variant { name: Identifier(name), kind: _ } in v {
|
for Variant { name: Identifier(name), kind: _ } in v {
|
||||||
let id = v.resolve_type(prj, id)?;
|
let id = prj[id].module.get_type(*name);
|
||||||
fields.push((*name, id))
|
fields.push((*name, id))
|
||||||
}
|
}
|
||||||
Ok(DefKind::Type(TypeKind::Adt(Adt::Enum(fields))))
|
Ok(DefKind::Type(TypeKind::Adt(Adt::Enum(fields))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Variant {
|
impl<'a> TypeResolvable<'a> for &'a Variant {
|
||||||
type Out = Option<DefID>;
|
type Out = DefKind;
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
|
// Get the grandparent of this node, for name resolution
|
||||||
let parent = prj.parent_of(id).unwrap_or(id);
|
let parent = prj.parent_of(id).unwrap_or(id);
|
||||||
let Self { name: Identifier(name), kind } = self;
|
let grandparent = prj.parent_of(parent).unwrap_or(parent);
|
||||||
|
let Variant { name: _, kind } = self;
|
||||||
|
|
||||||
let adt = match kind {
|
Ok(DefKind::Type(match kind {
|
||||||
VariantKind::Plain => return Ok(None),
|
VariantKind::Plain => return Ok(DefKind::Type(TypeKind::Empty)),
|
||||||
VariantKind::CLike(_) => todo!("Resolve variant info for C-like enums"),
|
VariantKind::CLike(_) => return Ok(DefKind::Undecided),
|
||||||
VariantKind::Tuple(ty) => {
|
VariantKind::Tuple(ty) => match &ty.kind {
|
||||||
return ty
|
TyKind::Empty => TypeKind::Tuple(vec![]),
|
||||||
.evaluate(prj, parent)
|
TyKind::Tuple(TyTuple { types }) => {
|
||||||
.map_err(|_| "Unresolved type in enum tuple variant")
|
TypeKind::Tuple(types.evaluate(prj, grandparent).map_err(|e| {
|
||||||
.map(Some)
|
eprintln!("{e}");
|
||||||
|
""
|
||||||
|
})?)
|
||||||
|
}
|
||||||
|
_ => Err("Unexpected TyKind in tuple variant")?,
|
||||||
|
},
|
||||||
|
VariantKind::Struct(members) => {
|
||||||
|
TypeKind::Adt(Adt::Struct(members.resolve_type(prj, parent)?))
|
||||||
}
|
}
|
||||||
VariantKind::Struct(members) => Adt::Struct(members.resolve_type(prj, id)?),
|
}))
|
||||||
};
|
|
||||||
|
|
||||||
let def = Def {
|
|
||||||
name: *name,
|
|
||||||
kind: DefKind::Type(TypeKind::Adt(adt)),
|
|
||||||
module: module::Module::new(id),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_id = prj.pool.insert(def);
|
|
||||||
// Insert the struct variant type into the enum's namespace
|
|
||||||
prj[id].module.insert_type(*name, new_id);
|
|
||||||
|
|
||||||
Ok(Some(new_id))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Struct {
|
impl<'a> TypeResolvable<'a> for &'a Struct {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let parent = prj.parent_of(id).unwrap_or(id);
|
let parent = prj.parent_of(id).unwrap_or(id);
|
||||||
let Self { name: _, kind } = self;
|
let Struct { name: _, kind } = self;
|
||||||
Ok(match kind {
|
Ok(match kind {
|
||||||
StructKind::Empty => DefKind::Type(TypeKind::Empty),
|
StructKind::Empty => DefKind::Type(TypeKind::Empty),
|
||||||
StructKind::Tuple(types) => DefKind::Type(TypeKind::Adt(Adt::TupleStruct({
|
StructKind::Tuple(types) => DefKind::Type(TypeKind::Adt(Adt::TupleStruct({
|
||||||
@ -224,12 +196,12 @@ impl<'a> TypeResolvable<'a> for Struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for StructMember {
|
impl<'a> TypeResolvable<'a> for &'a StructMember {
|
||||||
type Out = (Sym, Visibility, DefID);
|
type Out = (Sym, Visibility, DefID);
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let parent = prj.parent_of(id).unwrap_or(id);
|
let parent = prj.parent_of(id).unwrap_or(id);
|
||||||
let Self { name: Identifier(name), vis, ty } = self;
|
let StructMember { name: Identifier(name), vis, ty } = self;
|
||||||
|
|
||||||
let ty = ty
|
let ty = ty
|
||||||
.evaluate(prj, parent)
|
.evaluate(prj, parent)
|
||||||
@ -239,23 +211,24 @@ impl<'a> TypeResolvable<'a> for StructMember {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Const {
|
impl<'a> TypeResolvable<'a> for &'a Const {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let Self { ty, .. } = self;
|
let Const { ty, .. } = self;
|
||||||
let ty = ty
|
let ty = ty
|
||||||
.evaluate(prj, id)
|
.evaluate(prj, id)
|
||||||
.map_err(|_| "Invalid type while resolving const")?;
|
.map_err(|_| "Invalid type while resolving const")?;
|
||||||
Ok(DefKind::Value(ValueKind::Const(ty)))
|
Ok(DefKind::Value(ValueKind::Const(ty)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> TypeResolvable<'a> for Static {
|
|
||||||
|
impl<'a> TypeResolvable<'a> for &'a Static {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let parent = prj.parent_of(id).unwrap_or(id);
|
let parent = prj.parent_of(id).unwrap_or(id);
|
||||||
let Self { ty, .. } = self;
|
let Static { ty, .. } = self;
|
||||||
let ty = ty
|
let ty = ty
|
||||||
.evaluate(prj, parent)
|
.evaluate(prj, parent)
|
||||||
.map_err(|_| "Invalid type while resolving static")?;
|
.map_err(|_| "Invalid type while resolving static")?;
|
||||||
@ -263,12 +236,12 @@ impl<'a> TypeResolvable<'a> for Static {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeResolvable<'a> for Function {
|
impl<'a> TypeResolvable<'a> for &'a Function {
|
||||||
type Out = DefKind;
|
type Out = DefKind;
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let parent = prj.parent_of(id).unwrap_or(id);
|
let parent = prj.parent_of(id).unwrap_or(id);
|
||||||
let Self { sign, .. } = self;
|
let Function { sign, .. } = self;
|
||||||
let sign = sign
|
let sign = sign
|
||||||
.evaluate(prj, parent)
|
.evaluate(prj, parent)
|
||||||
.map_err(|_| "Invalid type in function signature")?;
|
.map_err(|_| "Invalid type in function signature")?;
|
||||||
@ -276,10 +249,57 @@ impl<'a> TypeResolvable<'a> for Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: TypeResolvable<'a>> TypeResolvable<'a> for [T] {
|
impl<'a> TypeResolvable<'a> for &'a Let {
|
||||||
type Out = Vec<T::Out>;
|
type Out = DefKind;
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
#[allow(unused)]
|
||||||
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
|
let Let { mutable, name, ty, init } = self;
|
||||||
|
Ok(DefKind::Undecided)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TypeResolvable<'a> for &'a Impl {
|
||||||
|
type Out = DefKind;
|
||||||
|
|
||||||
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
|
let parent = prj.parent_of(id).unwrap_or(id);
|
||||||
|
|
||||||
|
let target = match &self.target {
|
||||||
|
ImplKind::Type(t) => t.evaluate(prj, parent),
|
||||||
|
ImplKind::Trait { for_type, .. } => for_type.evaluate(prj, parent),
|
||||||
|
}
|
||||||
|
.map_err(|_| "Unresolved type in impl target")?;
|
||||||
|
|
||||||
|
prj[id].module.parent = Some(target);
|
||||||
|
|
||||||
|
Ok(DefKind::Impl(target))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TypeResolvable<'a> for &'a Use {
|
||||||
|
type Out = DefKind;
|
||||||
|
|
||||||
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
|
todo!("Resolve types for {self} with ID {id} in {prj:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TypeResolvable<'a> for &'a TyKind {
|
||||||
|
type Out = DefKind;
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> TypeResolvable<'a> for &'a [T]
|
||||||
|
where &'a T: TypeResolvable<'a>
|
||||||
|
{
|
||||||
|
type Out = Vec<<&'a T as TypeResolvable<'a>>::Out>;
|
||||||
|
|
||||||
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
let mut members = vec![];
|
let mut members = vec![];
|
||||||
for member in self {
|
for member in self {
|
||||||
members.push(member.resolve_type(prj, id)?);
|
members.push(member.resolve_type(prj, id)?);
|
||||||
@ -287,10 +307,12 @@ impl<'a, T: TypeResolvable<'a>> TypeResolvable<'a> for [T] {
|
|||||||
Ok(members)
|
Ok(members)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, T: TypeResolvable<'a>> TypeResolvable<'a> for Option<T> {
|
|
||||||
type Out = Option<T::Out>;
|
|
||||||
|
|
||||||
fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
impl<'a, T> TypeResolvable<'a> for Option<&'a T>
|
||||||
|
where &'a T: TypeResolvable<'a>
|
||||||
|
{
|
||||||
|
type Out = Option<<&'a T as TypeResolvable<'a>>::Out>;
|
||||||
|
fn resolve_type(self, prj: &mut Prj<'a>, id: DefID) -> Result<Self::Out, &'static str> {
|
||||||
match self {
|
match self {
|
||||||
Some(t) => Some(t.resolve_type(prj, id)).transpose(),
|
Some(t) => Some(t.resolve_type(prj, id)).transpose(),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
|
@ -16,6 +16,7 @@ use cl_ast::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
definition::{Def, DefKind},
|
definition::{Def, DefKind},
|
||||||
key::DefID,
|
key::DefID,
|
||||||
|
node::NodeSource,
|
||||||
project::Project,
|
project::Project,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,13 +31,9 @@ impl<'a> Project<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_def(&mut self, id: DefID) -> UseResult {
|
pub fn visit_def(&mut self, id: DefID) -> UseResult {
|
||||||
let Def { name, vis, meta, kind, source, module } = &self.pool[id];
|
let Def { kind, node, module } = &self.pool[id];
|
||||||
if let (DefKind::Use(parent), Some(source)) = (kind, source) {
|
if let (DefKind::Use(parent), Some(NodeSource::Use(u))) = (kind, node.kind) {
|
||||||
let Item { kind: ItemKind::Use(u), .. } = source else {
|
|
||||||
Err(format!("Not a use item: {source}"))?
|
|
||||||
};
|
|
||||||
println!("Importing use item {u}");
|
println!("Importing use item {u}");
|
||||||
|
|
||||||
self.visit_use(u, *parent);
|
self.visit_use(u, *parent);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user