Skip to content

Commit

Permalink
Store many defs for everything, pass test
Browse files Browse the repository at this point in the history
  • Loading branch information
azdavis committed Dec 7, 2023
1 parent 16629c5 commit 0c49cee
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 140 deletions.
31 changes: 18 additions & 13 deletions crates/analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub use mlb_statics::StdBasis;
/// The url to go to for information about diagnostics.
pub const URL: &str = "https://github.com/azdavis/millet/blob/main/docs/diagnostics";

const DOC_SEPARATOR: &str = "\n\n---\n\n";

/// Performs analysis.
#[derive(Debug)]
pub struct Analysis {
Expand Down Expand Up @@ -140,7 +142,7 @@ impl Analysis {
let this = def::Def::Path(def::Path::Regular(pos.path), idx);
parts.extend(self.get_doc(this));
let defs = ft.file.info.get_defs(idx);
parts.extend(defs.into_iter().filter_map(|def| self.get_doc(def)));
parts.extend(defs.into_iter().flatten().filter_map(|&def| self.get_doc(def)));
ptr.text_range()
}
None => ft.token.text_range(),
Expand All @@ -152,7 +154,7 @@ impl Analysis {
return None;
}
let range = ft.file.syntax.pos_db.range_utf16(range)?;
Some((parts.join("\n\n---\n\n"), range))
Some((parts.join(DOC_SEPARATOR), range))
}

fn get_doc(&self, def: def::Def) -> Option<&str> {
Expand All @@ -178,6 +180,7 @@ impl Analysis {
.info
.get_defs(idx)
.into_iter()
.flatten()
.filter_map(|def| source_files::path_and_range(&self.source_files, def.to_regular_idx()?));
Some(iter.collect())
}
Expand Down Expand Up @@ -342,28 +345,30 @@ impl Analysis {
label: name.as_str().to_owned(),
kind: sml_namespace::SymbolKind::Structure,
detail: None,
documentation: env.def.and_then(|d| self.get_doc(d)).map(ToOwned::to_owned),
documentation: self.get_defs_doc(&env.defs),
}));
ac.extend(env.val_env.iter().map(|(name, val_info)| {
let ty_scheme = val_info.ty_scheme.display(&self.syms_tys, config::DiagnosticLines::Many);
CompletionItem {
label: name.as_str().to_owned(),
kind: sml_symbol_kind::get(&self.syms_tys.tys, val_info),
detail: Some(ty_scheme.to_string()),
documentation: val_info.defs.iter().filter_map(|&x| self.get_doc(x)).fold(None, |ac, x| {
match ac {
None => Some(x.to_owned()),
Some(mut ac) => {
ac.push_str("\n\n---\n\n");
ac.push_str(x);
Some(ac)
}
}
}),
documentation: self.get_defs_doc(&val_info.defs),
}
}));
}

fn get_defs_doc(&self, defs: &FxHashSet<def::Def>) -> Option<String> {
defs.iter().filter_map(|&x| self.get_doc(x)).fold(None, |ac, x| match ac {
None => Some(x.to_owned()),
Some(mut ac) => {
ac.push_str("\n\n---\n\n");
ac.push_str(x);
Some(ac)
}
})
}

/// Returns all inlay hints for the range.
#[must_use]
pub fn inlay_hints(&self, range: WithPath<RangeUtf16>) -> Option<Vec<InlayHint>> {
Expand Down
12 changes: 7 additions & 5 deletions crates/sml-statics-types/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ pub struct Env {
pub ty_env: TyEnv,
/// The value env.
pub val_env: ValEnv,
/// The def site for this env.
pub def: Option<def::Def>,
/// The definitions.
///
/// It's a set, because we can have structures ascribing to signatures.
pub defs: FxHashSet<def::Def>,
/// Whether everything in this env is disallowed.
pub disallow: Option<Disallow>,
}

impl Env {
/// Returns an empty `Env` with the given def.
/// Returns an empty `Env` with the given defs.
#[must_use]
pub fn new(def: Option<def::Def>) -> Env {
Env { def, ..Env::default() }
pub fn new(defs: FxHashSet<def::Def>) -> Env {
Env { defs, ..Env::default() }
}

/// Appends other onto self, emptying other.
Expand Down
8 changes: 5 additions & 3 deletions crates/sml-statics-types/src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ pub struct TyInfo<VE = ValEnv> {
pub ty_scheme: TyScheme,
/// The val environment.
pub val_env: VE,
/// The def.
pub def: Option<def::Def>,
/// The definitions.
///
/// It's a set, because we can have structures ascribing to signatures.
pub defs: FxHashSet<def::Def>,
/// Whether this is disallowed.
pub disallow: Option<Disallow>,
}
Expand All @@ -32,7 +34,7 @@ where
TyInfo {
ty_scheme: self.ty_scheme,
val_env: self.val_env.into(),
def: self.def,
defs: self.defs,
disallow: self.disallow,
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/sml-statics-types/src/sym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::info::{TyInfo, ValEnv, ValInfo};
use crate::ty::{Ty, TyKind, TyScheme};
use crate::{def, overload};
use drop_bomb::DropBomb;
use fast_hash::FxHashMap;
use fast_hash::{FxHashMap, FxHashSet};
use std::fmt;

/// A symbol, aka a type name. Definition: `TyName`
Expand Down Expand Up @@ -245,7 +245,7 @@ impl Syms {
let ty_info = TyInfo {
ty_scheme: TyScheme::zero(Ty::NONE),
val_env: SymValEnv::default(),
def: None,
defs: FxHashSet::default(),
disallow: None,
};
// must start with sometimes equality, as an assumption for constructing datatypes. we may
Expand Down
21 changes: 14 additions & 7 deletions crates/sml-statics/src/basis.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Bases. (The plural of "basis".)
use crate::get_env::get_mut_env;
use fast_hash::FxHashMap;
use fast_hash::{FxHashMap, FxHashSet};
use sml_statics_types::disallow::{self, Disallow};
use sml_statics_types::env::{Cx, Env, FunEnv, SigEnv, StrEnv};
use sml_statics_types::info::{IdStatus, TyEnv, TyInfo, ValEnv, ValInfo};
Expand Down Expand Up @@ -153,7 +153,7 @@ pub fn minimal() -> (sml_statics_types::St, Bs) {
TyInfo {
ty_scheme: alpha_list.clone(),
val_env: datatype_ve([(Primitive::Nil, alpha_list), (Primitive::Cons, cons)]),
def: Some(Primitive::List.into()),
defs: FxHashSet::from_iter([Primitive::List.into()]),
disallow: None,
}
};
Expand All @@ -167,15 +167,15 @@ pub fn minimal() -> (sml_statics_types::St, Bs) {
TyInfo {
ty_scheme: ty_scheme_one(&mut tys, TyVarKind::Regular, ref_),
val_env: datatype_ve([(Primitive::RefVal, con)]),
def: Some(Primitive::RefTy.into()),
defs: FxHashSet::from_iter([Primitive::RefTy.into()]),
disallow: None,
}
};
insert_special(&mut syms, Sym::REF, ref_info);
let vector_info = TyInfo {
ty_scheme: ty_scheme_one(&mut tys, TyVarKind::Regular, |tys, a| tys.con(vec![a], Sym::VECTOR)),
val_env: SymValEnv::default(),
def: Some(Primitive::Vector.into()),
defs: FxHashSet::from_iter([Primitive::Vector.into()]),
disallow: None,
};
insert_special(&mut syms, Sym::VECTOR, vector_info);
Expand All @@ -190,7 +190,7 @@ pub fn minimal() -> (sml_statics_types::St, Bs) {
let ti = TyInfo {
ty_scheme: TyScheme::zero(ty),
val_env: ValEnv::default(),
def: Some(name.into()),
defs: FxHashSet::from_iter([name.into()]),
disallow: None,
};
(str_util::Name::new(name.as_str()), ti)
Expand Down Expand Up @@ -244,7 +244,13 @@ pub fn minimal() -> (sml_statics_types::St, Bs) {
let bs = Bs {
fun_env: FunEnv::default(),
sig_env: SigEnv::default(),
env: Env { str_env: StrEnv::default(), ty_env, val_env, def: None, disallow: None },
env: Env {
str_env: StrEnv::default(),
ty_env,
val_env,
defs: FxHashSet::default(),
disallow: None,
},
};
(sml_statics_types::St { syms, tys }, bs)
}
Expand All @@ -267,7 +273,8 @@ fn insert_special(syms: &mut Syms, sym: Sym, ty_info: SymTyInfo) {
fn basic_datatype(tys: &mut Tys, sym: Sym, ctors: &'static [Primitive]) -> SymTyInfo {
let ty_scheme = TyScheme::zero(tys.con(Vec::new(), sym));
let val_env = datatype_ve(ctors.iter().map(|&x| (x, ty_scheme.clone())));
TyInfo { ty_scheme, val_env, def: Some(sym.primitive().unwrap().into()), disallow: None }
let defs = FxHashSet::from_iter([sym.primitive().unwrap().into()]);
TyInfo { ty_scheme, val_env, defs, disallow: None }
}

fn datatype_ve<I>(xs: I) -> SymValEnv
Expand Down
11 changes: 5 additions & 6 deletions crates/sml-statics/src/dec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,8 @@ fn get_one(
IdStatus::Exn(_) => {
match ins_no_dupe(&mut val_env, name.clone(), val_info.clone(), Item::Val) {
None => {
if let Some(&def) = val_info.defs.iter().next() {
st.info.entries.defs.dec.insert(dec, def);
}
let dec_defs = st.info.entries.defs.dec.entry(dec).or_default();
dec_defs.extend(val_info.defs.iter());
}
Some(e) => st.err(dec, e),
}
Expand Down Expand Up @@ -299,7 +298,7 @@ fn get_ty_binds(
let ty = ty::get(st, cx, ars, ty::Mode::TyRhs, ty_bind.ty);
let ty_scheme = generalize::get_fixed(&mut st.syms_tys.tys, fixed, ty);
let ty_info =
TyInfo { ty_scheme, val_env: ValEnv::default(), def: st.def(idx), disallow: None };
TyInfo { ty_scheme, val_env: ValEnv::default(), defs: st.def(idx), disallow: None };
if let Some(e) = ins_no_dupe(ty_env, ty_bind.name.clone(), ty_info, Item::Ty) {
st.err(idx, e);
}
Expand Down Expand Up @@ -345,7 +344,7 @@ pub(crate) fn get_dat_binds(
let ty_info = TyInfo {
ty_scheme: ty_scheme.clone(),
val_env: ValEnv::default(),
def: st.def(idx),
defs: st.def(idx),
disallow: None,
};
if let Some(e) = ins_no_dupe(&mut fake_ty_env, dat_bind.name.clone(), ty_info, Item::Ty) {
Expand Down Expand Up @@ -414,7 +413,7 @@ pub(crate) fn get_dat_binds(
// NOTE: no checking for duplicates here
big_val_env.append(&mut val_env.clone().into());
let ty_info =
TyInfo { ty_scheme: datatype.ty_scheme, val_env, def: st.def(idx), disallow: None };
TyInfo { ty_scheme: datatype.ty_scheme, val_env, defs: st.def(idx), disallow: None };
let ty_info_dve = ty_info.clone().with_default_val_env_type();
let equality = equality::get_ty_info(
st.info.mode,
Expand Down
Loading

0 comments on commit 0c49cee

Please sign in to comment.