Skip to content

Commit

Permalink
Start work on lookup meta by hash
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Apr 4, 2023
1 parent d96abed commit fc6a0b5
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 59 deletions.
5 changes: 5 additions & 0 deletions crates/rune/src/compile/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ impl Context {
self.meta.get(name)
}

/// Lookup meta by its hash.
pub(crate) fn lookup_meta_by_hash(&self, hash: Hash) -> Option<&PrivMeta> {
todo!()
}

/// Look up signature of function.
#[cfg(feature = "doc")]
pub(crate) fn lookup_signature(&self, hash: Hash) -> Option<&meta::Signature> {
Expand Down
10 changes: 4 additions & 6 deletions crates/rune/src/compile/function_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use crate::compile::module::{
};
use crate::compile::{IntoComponent, ItemBuf, Named};
use crate::hash::Hash;
#[cfg(feature = "doc")]
use crate::runtime::TypeInfo;
use crate::runtime::{FunctionHandler, Protocol};

mod sealed {
Expand Down Expand Up @@ -138,7 +136,7 @@ impl ToInstance for &str {
kind: AssociatedFunctionKind::Instance(self.into()),
parameters: Hash::EMPTY,
#[cfg(feature = "doc")]
parameter_type_infos: vec![],
parameter_types: vec![],
}
}
}
Expand All @@ -150,7 +148,7 @@ impl ToFieldFunction for &str {
kind: AssociatedFunctionKind::FieldFn(protocol, self.into()),
parameters: Hash::EMPTY,
#[cfg(feature = "doc")]
parameter_type_infos: vec![],
parameter_types: vec![],
}
}
}
Expand All @@ -165,7 +163,7 @@ pub struct AssociatedFunctionName {
/// Parameters hash.
pub parameters: Hash,
#[cfg(feature = "doc")]
pub parameter_type_infos: Vec<TypeInfo>,
pub parameter_types: Vec<Hash>,
}

impl AssociatedFunctionName {
Expand All @@ -174,7 +172,7 @@ impl AssociatedFunctionName {
kind: AssociatedFunctionKind::IndexFn(protocol, index),
parameters: Hash::EMPTY,
#[cfg(feature = "doc")]
parameter_type_infos: vec![],
parameter_types: vec![],
}
}
}
Expand Down
72 changes: 45 additions & 27 deletions crates/rune/src/doc/context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::compile::context::PrivMeta;
use crate::compile::meta;
use crate::compile::{AssociatedFunction, ComponentRef, IntoComponent, Item};
use crate::doc::Visitor;
Expand Down Expand Up @@ -72,39 +73,31 @@ impl<'a> Context<'a> {
.chain(tail)
}

/// Get a meta item by its hash.
pub(crate) fn meta_by_hash(&self, hash: Hash) -> Option<Meta<'_>> {
for visitor in self.visitors {
if let Some(m) = visitor.get_by_hash(hash) {
return Some(visitor_meta_to_meta(m, visitor, hash));
}
}

let meta = self.context.lookup_meta_by_hash(hash)?;
Some(self.context_meta_to_meta(meta)?)
}

/// Lookup Meta.
pub(crate) fn meta(&self, item: &Item) -> Option<Meta<'_>> {
for visitor in self.visitors {
if let Some(m) = visitor.meta.get(item) {
let kind = match m {
meta::Kind::Unknown { .. } => Kind::Unknown,
meta::Kind::Struct { .. } => Kind::Struct,
meta::Kind::Variant { .. } => Kind::Variant,
meta::Kind::Enum => Kind::Enum,
meta::Kind::Function { is_async, args, .. } => Kind::Function(Function {
is_async: *is_async,
args: None,
signature: Signature::Function { args: *args },
}),
_ => Kind::Unsupported,
};

let docs = visitor
.docs
.get(item)
.map(Vec::as_slice)
.unwrap_or_default();

return Some(Meta {
hash: Hash::type_hash(item),
docs,
kind,
});
if let Some((hash, m)) = visitor.get(item) {
return Some(visitor_meta_to_meta(m, visitor, hash));
}
}

let meta = self.context.lookup_meta(item)?;
Some(self.context_meta_to_meta(meta)?)
}

fn context_meta_to_meta(&self, meta: &'a PrivMeta) -> Option<Meta<'a>> {
let kind = match &meta.kind {
meta::Kind::Unknown { .. } => Kind::Unknown,
meta::Kind::Struct { .. } => Kind::Struct,
Expand Down Expand Up @@ -138,11 +131,13 @@ impl<'a> Context<'a> {
_ => Kind::Unsupported,
};

Some(Meta {
let m = Meta {
hash: meta.hash,
docs: meta.docs.lines(),
kind,
})
};

Some(m)
}

/// Iterate over known modules.
Expand All @@ -153,3 +148,26 @@ impl<'a> Context<'a> {
.chain(self.context.iter_meta().map(|(_, m)| m.module.as_ref()))
}
}

fn visitor_meta_to_meta<'a>(m: &'a meta::Kind, visitor: &'a Visitor, hash: Hash) -> Meta<'a> {
let kind = match m {
meta::Kind::Unknown { .. } => Kind::Unknown,
meta::Kind::Struct { .. } => Kind::Struct,
meta::Kind::Variant { .. } => Kind::Variant,
meta::Kind::Enum => Kind::Enum,
meta::Kind::Function { is_async, args, .. } => Kind::Function(Function {
is_async: *is_async,
args: None,
signature: Signature::Function { args: *args },
}),
_ => Kind::Unsupported,
};

let docs = visitor
.docs
.get(&hash)
.map(Vec::as_slice)
.unwrap_or_default();

Meta { hash, docs, kind }
}
8 changes: 6 additions & 2 deletions crates/rune/src/doc/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,12 @@ fn type_(cx: &Ctxt<'_>, what: &str, hash: Hash) -> Result<()> {

let mut list = Vec::new();

for p in &f.name.parameter_type_infos {
list.push(p.to_string());
for hash in &f.name.parameter_types {
if let Some(meta) = cx.context.meta_by_hash(*hash) {
list.push(String::from("META"));
} else {
list.push(String::from("?"));
}
}

let parameters = (!list.is_empty()).then(|| list.join(", "));
Expand Down
39 changes: 30 additions & 9 deletions crates/rune/src/doc/visitor.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use crate::collections::{BTreeMap, HashMap};
use crate::collections::HashMap;
use crate::compile::{
meta, CompileVisitor, IntoComponent, Item, ItemBuf, Location, MetaRef, Names,
};
use crate::hash::Hash;

/// Visitor used to collect documentation from rune sources.
pub struct Visitor {
pub(crate) base: ItemBuf,
pub(crate) names: Names,
pub(crate) meta: BTreeMap<ItemBuf, meta::Kind>,
pub(crate) docs: HashMap<ItemBuf, Vec<String>>,
pub(crate) field_docs: HashMap<ItemBuf, HashMap<Box<str>, Vec<String>>>,
pub(crate) meta: HashMap<Hash, meta::Kind>,
pub(crate) docs: HashMap<Hash, Vec<String>>,
pub(crate) field_docs: HashMap<Hash, HashMap<Box<str>, Vec<String>>>,
pub(crate) item_to_hash: HashMap<ItemBuf, Hash>,
}

impl Visitor {
Expand All @@ -22,23 +24,39 @@ impl Visitor {
Self {
base: base.into_iter().collect(),
names: Names::default(),
meta: BTreeMap::default(),
meta: HashMap::default(),
item_to_hash: HashMap::new(),
docs: HashMap::default(),
field_docs: HashMap::default(),
}
}

/// Get meta by item.
pub(crate) fn get(&self, item: &Item) -> Option<(Hash, &meta::Kind)> {
let hash = self.item_to_hash.get(item)?;
Some((*hash, self.meta.get(hash)?))
}

/// Get meta by hash.
pub(crate) fn get_by_hash(&self, hash: Hash) -> Option<&meta::Kind> {
self.meta.get(&hash)
}
}

impl CompileVisitor for Visitor {
fn register_meta(&mut self, meta: MetaRef<'_>) {
let item = self.base.join(meta.item);
self.meta.insert(item.to_owned(), meta.kind.clone());
self.item_to_hash.insert(item.to_owned(), meta.hash);
self.meta.insert(meta.hash, meta.kind.clone());
self.names.insert(item);
}

fn visit_doc_comment(&mut self, _location: Location, item: &Item, string: &str) {
let item = self.base.join(item);
self.docs.entry(item).or_default().push(string.to_owned());

if let Some(hash) = self.item_to_hash.get(&item) {
self.docs.entry(*hash).or_default().push(string.to_owned());
}
}

fn visit_field_doc_comment(
Expand All @@ -49,7 +67,10 @@ impl CompileVisitor for Visitor {
string: &str,
) {
let item = self.base.join(item);
let map = self.field_docs.entry(item).or_default();
map.entry(field.into()).or_default().push(string.to_owned());

if let Some(hash) = self.item_to_hash.get(&item) {
let map = self.field_docs.entry(*hash).or_default();
map.entry(field.into()).or_default().push(string.to_owned());
}
}
}
12 changes: 2 additions & 10 deletions crates/rune/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ where
kind: info.kind,
parameters: Hash::parameters(self.parameters.iter().map(|t| t.hash)),
#[cfg(feature = "doc")]
parameter_type_infos: self
.parameters
.iter()
.map(|t| t.type_info.clone())
.collect(),
parameter_types: self.parameters.iter().map(|t| t.hash).collect(),
}
}
}
Expand All @@ -62,11 +58,7 @@ where
kind: info.kind,
parameters: Hash::parameters(self.parameters.iter().map(|p| p.hash)),
#[cfg(feature = "doc")]
parameter_type_infos: self
.parameters
.iter()
.map(|p| p.type_info.clone())
.collect(),
parameter_types: self.parameters.iter().map(|p| p.hash).collect(),
}
}
}
2 changes: 1 addition & 1 deletion crates/rune/src/runtime/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl ToInstance for Protocol {
kind: AssociatedFunctionKind::Protocol(self),
parameters: Hash::EMPTY,
#[cfg(feature = "doc")]
parameter_type_infos: vec![],
parameter_types: vec![],
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions crates/rune/src/runtime/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use crate::Hash;
#[derive(Clone)]
pub struct FullTypeOf {
pub(crate) hash: Hash,
#[cfg(feature = "doc")]
pub(crate) type_info: TypeInfo,
}

/// Trait used for Rust types for which we can determine the runtime type of.
Expand All @@ -16,8 +14,6 @@ pub trait TypeOf {
fn type_of() -> FullTypeOf {
FullTypeOf {
hash: Self::type_hash(),
#[cfg(feature = "doc")]
type_info: Self::type_info(),
}
}

Expand Down

0 comments on commit fc6a0b5

Please sign in to comment.