Skip to content

Commit

Permalink
fix: module issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Chronostasys committed Aug 1, 2023
1 parent dcfa317 commit 81c26fd
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 74 deletions.
103 changes: 55 additions & 48 deletions src/ast/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ use lsp_types::SemanticTokenType;
use lsp_types::Url;
use rustc_hash::FxHashMap;
use rustc_hash::FxHashSet;

use std::cell::RefCell;

use std::path::PathBuf;

use std::sync::Arc;
mod builtins;
mod references;
Expand Down Expand Up @@ -105,6 +106,7 @@ pub struct Ctx<'a> {
pub ctx_flag: CtxFlag,
pub generator_data: Option<Arc<RefCell<GeneratorCtxData>>>,
pub generic_cache: GenericCache,
pub origin_mod: *const Mod,
}

#[derive(Clone, Default)]
Expand Down Expand Up @@ -298,6 +300,7 @@ impl<'a, 'ctx> Ctx<'a> {
ctx_flag: CtxFlag::Normal,
generator_data: None,
generic_cache: generic_infer,
origin_mod: std::ptr::null(),
}
}
pub fn new_child(&'a self, start: Pos, builder: &'a BuilderEnum<'a, 'ctx>) -> Ctx<'a> {
Expand Down Expand Up @@ -336,6 +339,7 @@ impl<'a, 'ctx> Ctx<'a> {
ctx_flag: self.ctx_flag,
generator_data: self.generator_data.clone(),
generic_cache: self.generic_cache.clone(),
origin_mod: self.origin_mod,
};
add_primitive_types(&mut ctx);
if start != Default::default() {
Expand Down Expand Up @@ -854,6 +858,30 @@ impl<'a, 'ctx> Ctx<'a> {
}
Err(range.new_err(ErrorCode::UNDEFINED_TYPE))
}

pub fn get_type_in_mod(&self, m: &Mod, name: &str, range: Range) -> Result<GlobType, PLDiag> {
if let Some(pv) = self.generic_types.get(name) {
self.set_if_refs_tp(pv.clone(), range);
self.send_if_go_to_def(
range,
pv.borrow().get_range().unwrap_or(range),
self.plmod.path.clone(),
);
return Ok(pv.clone().into());
}
if m.path == self.plmod.path {
if let Ok(pv) = self.plmod.get_type(name, range, self) {
return Ok(pv);
}
} else if let Ok(pv) = m.get_type(name, range, self) {
return Ok(pv);
}
if let Some(father) = self.father {
let re = father.get_type_in_mod(m, name, range);
return re;
}
Err(range.new_err(ErrorCode::UNDEFINED_TYPE))
}
/// 用来获取外部模块的全局变量
/// 如果没在当前module的全局变量表中找到,将会生成一个
/// 该全局变量的声明
Expand Down Expand Up @@ -911,6 +939,8 @@ impl<'a, 'ctx> Ctx<'a> {
}
self.set_if_refs_tp(pltype.clone(), range);
self.send_if_go_to_def(range, range, self.plmod.path.clone());
self.db
.add_tp_to_mod(&self.plmod.path, &name, pltype.clone());
self.plmod.types.insert(name, pltype.into());
Ok(())
}
Expand All @@ -919,6 +949,8 @@ impl<'a, 'ctx> Ctx<'a> {
unreachable!()
}
let name = pltype.borrow().get_name();
self.db
.add_tp_to_mod(&self.plmod.path, &name, pltype.clone());
self.plmod.types.insert(name, pltype.into());
}
#[inline]
Expand Down Expand Up @@ -1016,33 +1048,14 @@ impl<'a, 'ctx> Ctx<'a> {
u: &TP,
mut f: F,
) -> R {
let p = PathBuf::from(&u.get_path());
let mut oldm = None;
if u.get_path() != self.plmod.path {
let s = p.file_name().unwrap().to_str().unwrap();
let m = s.split('.').next().unwrap();
let m = self.plmod.submods.get(m).unwrap();
oldm = Some(self.set_mod(m.clone()));
}
let res = f(self, u);
if let Some(m) = oldm {
self.set_mod(m);
}
res
}

// FIXME: performance
pub fn run_in_type_mod_deep<'b, TP: CustomType, R, F: FnMut(&mut Ctx<'a>, &TP) -> R>(
&'b mut self,
u: &TP,
mut f: F,
) -> R {
let p = PathBuf::from(&u.get_path());
let mut oldm = None;
if u.get_path() != self.plmod.path {
let s = p.file_name().unwrap().to_str().unwrap();
let m = s.split('.').next().unwrap();
let m = self.plmod.search_mod(u, m).unwrap();
let ori_mod = unsafe { &*self.origin_mod as &Mod };
let m = if u.get_path() == ori_mod.path {
ori_mod.clone()
} else {
self.db.get_module(&u.get_path()).unwrap()
};
oldm = Some(self.set_mod(m));
}
let res = f(self, u);
Expand All @@ -1065,13 +1078,15 @@ impl<'a, 'ctx> Ctx<'a> {
u: &mut TP,
mut f: F,
) -> R {
let p = PathBuf::from(&u.get_path());
let mut oldm = None;
if u.get_path() != self.plmod.path {
let s = p.file_name().unwrap().to_str().unwrap();
let m = s.split('.').next().unwrap();
let m = self.plmod.submods.get(m).unwrap();
oldm = Some(self.set_mod(m.clone()));
let ori_mod = unsafe { &*self.origin_mod as &Mod };
let m = if u.get_path() == ori_mod.path {
ori_mod.clone()
} else {
self.db.get_module(&u.get_path()).unwrap()
};
oldm = Some(self.set_mod(m));
}
let res = f(self, u);
if let Some(m) = oldm {
Expand All @@ -1080,24 +1095,16 @@ impl<'a, 'ctx> Ctx<'a> {
res
}

pub fn run_in_type_mod_mut_deep<'b, TP: CustomType, R, F: FnMut(&mut Ctx<'a>, &mut TP) -> R>(
&'b mut self,
u: &mut TP,
mut f: F,
) -> R {
let p = PathBuf::from(&u.get_path());
let mut oldm = None;
if u.get_path() != self.plmod.path {
let s = p.file_name().unwrap().to_str().unwrap();
let m = s.split('.').next().unwrap();
let m = self.plmod.search_mod(u, m).unwrap();
oldm = Some(self.set_mod(m));
}
let res = f(self, u);
if let Some(m) = oldm {
self.set_mod(m);
pub fn get_mod(&self, path: &str) -> Mod {
let ori_mod = unsafe { &*self.origin_mod as &Mod };

if path == self.plmod.path {
self.plmod.clone()
} else if path == ori_mod.path {
ori_mod.clone()
} else {
self.db.get_module(path).unwrap()
}
res
}

pub fn get_file_url(&self) -> Url {
Expand Down
2 changes: 1 addition & 1 deletion src/ast/node/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl Node for FuncCallNode {
)?;
// value check and generic infer
let res = ctx.protect_generic_context(&fnvalue.fntype.generic_map.clone(), |ctx| {
let rettp = ctx.run_in_type_mod_mut_deep(&mut fnvalue, |ctx, fnvalue| {
let rettp = ctx.run_in_type_mod_mut(&mut fnvalue, |ctx, fnvalue| {
if let Some(receiver_pltype) = &receiver_type {
if !fnvalue.fntype.param_pltypes[0]
.eq_or_infer(ctx, receiver_pltype.clone(), builder)?
Expand Down
6 changes: 3 additions & 3 deletions src/ast/node/implement.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::{
ast::{ctx::Ctx, tokens::TokenType},
ast::{ctx::Ctx, tokens::TokenType, traits::CustomType},
format_label,
};
use internal_macro::node;
Expand Down Expand Up @@ -123,7 +123,7 @@ fn check_fn<'a, 'b>(
)
.add_label(
st.range,
ctx.get_file(),
st.get_path(),
format_label!("trait {} def here", &st.name),
)
.add_help(
Expand Down Expand Up @@ -235,7 +235,7 @@ impl Node for ImplNode {
)
.add_label(
tp.borrow().get_range().unwrap(),
ctx.get_file(),
tp.borrow().get_path().unwrap_or(ctx.get_file()),
format_label!("trait {} def here", tp.borrow().get_name()),
)
.add_help("add the method to current impl block")
Expand Down
1 change: 1 addition & 0 deletions src/ast/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub enum TypeNodeEnum {
Func(FuncDefNode),
Tuple(TupleTypeNode),
Closure(ClosureTypeNode),
Custom(CustomTypeNode),
}
#[enum_dispatch]
pub trait TypeNode: RangeTrait + FmtTrait + PrintTrait {
Expand Down
2 changes: 1 addition & 1 deletion src/ast/node/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ impl Node for TakeOpNode {
headptr = builder.alloc("temp", &head_pltype.borrow(), ctx, None);
}
match &*head_pltype.clone().borrow() {
PLType::Trait(s) => ctx.run_in_type_mod_deep(s, |ctx, s| {
PLType::Trait(s) => ctx.run_in_type_mod(s, |ctx, s| {
ctx.protect_generic_context(&s.generic_map, |ctx| {
let head_pltype = head_pltype.clone();
let field = s.get_trait_field(&id.name);
Expand Down
2 changes: 2 additions & 0 deletions src/ast/node/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ pub fn emit_file(db: &dyn Db, params: ProgramEmitParam) -> ModWrapper {
if let Some(builtin_mod) = ctx.plmod.submods.get("stdbuiltin").cloned() {
ctx.plmod.import_all_symbols_from(&builtin_mod);
}
ctx.origin_mod = &ctx.plmod as _;
ctx.import_all_infer_maps_from_sub_mods();
let m = &mut ctx;
#[cfg(feature = "llvm")]
Expand Down Expand Up @@ -625,6 +626,7 @@ pub fn emit_file(db: &dyn Db, params: ProgramEmitParam) -> ModWrapper {
},
);
}
db.add_module(ctx.get_file(), ctx.plmod.clone());
ModWrapper::new(db, ctx.plmod)
}

Expand Down
51 changes: 51 additions & 0 deletions src/ast/node/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -994,3 +994,54 @@ impl PrintTrait for ClosureTypeNode {
self.ret_type.print(tabs + 1, true, line.clone());
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CustomTypeNode {
pub name: String,
pub range: Range,
pub path: String,
}

impl TypeNode for CustomTypeNode {
fn get_type<'a, 'b>(
&self,
ctx: &'b mut Ctx<'a>,
_builder: &'b BuilderEnum<'a, '_>,
_gen_code: bool,
) -> TypeNodeResult {
let m = ctx.get_mod(&self.path);
let tp = ctx.get_type_in_mod(&m, &self.name, self.range)?;
Ok(tp.tp)
}

fn emit_highlight(&self, _ctx: &mut Ctx) {
todo!()
}

fn eq_or_infer<'a, 'b>(
&self,
_ctx: &'b mut Ctx<'a>,
_pltype: Arc<RefCell<PLType>>,
_builder: &'b BuilderEnum<'a, '_>,
) -> Result<EqRes, PLDiag> {
todo!()
}
}

impl RangeTrait for CustomTypeNode {
fn range(&self) -> Range {
self.range
}
}

impl PrintTrait for CustomTypeNode {
fn print(&self, _tabs: usize, _end: bool, _line: Vec<bool>) {
todo!()
}
}

impl FmtTrait for CustomTypeNode {
fn format(&self, _builder: &mut FmtBuilder) {
todo!()
}
}
38 changes: 20 additions & 18 deletions src/ast/pltype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::builder::ValueHandle;
use super::ctx::Ctx;
use super::diag::ErrorCode;
use super::node::types::ClosureTypeNode;
use super::node::types::CustomTypeNode;
use super::plmod::Mod;
use super::plmod::MutVec;
use super::tokens::TokenType;
Expand Down Expand Up @@ -46,7 +47,7 @@ use lsp_types::SymbolKind;
use rustc_hash::FxHashMap;
use std::cell::RefCell;

use std::path::PathBuf;

use std::sync::atomic::AtomicI64;
use std::sync::atomic::Ordering;
use std::sync::Arc;
Expand Down Expand Up @@ -395,25 +396,17 @@ impl PLType {
}
}

fn get_ns<T: CustomType>(tp: &T, path: &str) -> Vec<String> {
let p = tp.get_path();
if p != path && !p.ends_with("builtin.pi") {
let p: PathBuf = p.into();
vec![p
.with_extension("")
.file_name()
.unwrap()
.to_str()
.unwrap()
.to_string()]
} else {
vec![]
}
fn new_custom_tp_node<T: CustomType>(tp: &T, _path: &str) -> Box<TypeNodeEnum> {
Box::new(TypeNodeEnum::Custom(CustomTypeNode {
name: tp.get_name(),
range: tp.get_range(),
path: tp.get_path(),
}))
}

pub fn get_typenode(&self, path: &str) -> Box<TypeNodeEnum> {
match self {
PLType::Struct(st) => new_typename_node(&st.name, st.range, &Self::get_ns(st, path)),
PLType::Struct(st) => Self::new_custom_tp_node(st, path),
PLType::Arr(arr) => new_arrtype_node(arr.get_elem_type().borrow().get_typenode(path)),
PLType::Primitive(p) => new_typename_node(&p.get_name(), Default::default(), &[]),
PLType::Void => new_typename_node("void", Default::default(), &[]),
Expand All @@ -428,9 +421,9 @@ impl PLType {
PLType::PlaceHolder(p) => {
new_typename_node(&p.get_place_holder_name(), Default::default(), &[])
}
PLType::Trait(t) => new_typename_node(&t.name, t.range, &Self::get_ns(t, path)),
PLType::Trait(t) => Self::new_custom_tp_node(t, path),
PLType::Fn(_) => unreachable!(),
PLType::Union(u) => new_typename_node(&u.name, u.range, &Self::get_ns(u, path)),
PLType::Union(u) => Self::new_custom_tp_node(u, path),
PLType::Closure(c) => Box::new(c.to_type_node(path)),
}
}
Expand All @@ -456,6 +449,15 @@ impl PLType {
}
}

pub fn get_path(&self) -> Option<String> {
match self {
PLType::Fn(f) => Some(f.get_path()),
PLType::Struct(f) | PLType::Trait(f) => Some(f.get_path()),
PLType::Union(f) => Some(f.get_path()),
_ => None,
}
}

pub fn get_name(&self) -> String {
match self {
PLType::Fn(fu) => fu.name.clone(),
Expand Down
Loading

0 comments on commit 81c26fd

Please sign in to comment.