Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render more documentation #476

Merged
merged 3 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions benches/benches/primes.rn
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const MAX_NUMBER_TO_CHECK = 1000;

/// Find prime numbers.
#[bench]
fn find_primes(b) {
let prime_mask = [];
Expand Down
5 changes: 4 additions & 1 deletion crates/rune-macros/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ where
raw_str,
shared,
type_info,
any_type_info,
type_of,
unsafe_from_value,
unsafe_to_value,
Expand Down Expand Up @@ -436,12 +437,14 @@ where
#impl_named

impl #impl_generics #type_of for #ident #ty_generics #where_clause {
#[inline]
fn type_hash() -> #hash {
<Self as #any>::type_hash()
}

#[inline]
fn type_info() -> #type_info {
#type_info::Any(#raw_str::from_str(std::any::type_name::<Self>()))
#type_info::Any(#any_type_info::new(#raw_str::from_str(std::any::type_name::<Self>())))
}
}

Expand Down
2 changes: 2 additions & 0 deletions crates/rune-macros/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ impl Context {
token_stream: quote!(#module::macros::TokenStream),
tuple: quote!(#module::runtime::Tuple),
type_info: quote!(#module::runtime::TypeInfo),
any_type_info: quote!(#module::runtime::AnyTypeInfo),
type_of: quote!(#module::runtime::TypeOf),
unit_struct: quote!(#module::runtime::UnitStruct),
unsafe_from_value: quote!(#module::runtime::UnsafeFromValue),
Expand Down Expand Up @@ -686,6 +687,7 @@ pub(crate) struct Tokens {
pub(crate) token_stream: TokenStream,
pub(crate) tuple: TokenStream,
pub(crate) type_info: TokenStream,
pub(crate) any_type_info: TokenStream,
pub(crate) type_of: TokenStream,
pub(crate) unit_struct: TokenStream,
pub(crate) unsafe_from_value: TokenStream,
Expand Down
3 changes: 2 additions & 1 deletion crates/rune/src/any.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::compile::Named;
use crate::Hash;
use crate::hash::Hash;

pub use rune_macros::Any;

/// A trait which can be stored inside of an [AnyObj](crate::runtime::AnyObj).
Expand Down
5 changes: 4 additions & 1 deletion crates/rune/src/compile/compile_visitor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::ast::Span;
use crate::compile::{Item, Location, MetaRef};
use crate::hash::Hash;
use crate::SourceId;

/// A visitor that will be called for every language item compiled.
Expand All @@ -24,7 +25,8 @@ pub trait CompileVisitor {
///
/// This can be called in any order, before or after
/// [CompileVisitor::visit_meta] for any given item.
fn visit_doc_comment(&mut self, _location: Location, _item: &Item, _docstr: &str) {}
fn visit_doc_comment(&mut self, _location: Location, _item: &Item, _hash: Hash, _docstr: &str) {
}

/// Visit anterior `///`-style comments, and interior `//!`-style doc
/// comments for a field contained in a struct / enum variant struct.
Expand All @@ -35,6 +37,7 @@ pub trait CompileVisitor {
&mut self,
_location: Location,
_item: &Item,
_hash: Hash,
_field: &str,
_docstr: &str,
) {
Expand Down
31 changes: 21 additions & 10 deletions crates/rune/src/compile/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub struct PrivMeta {

impl PrivMeta {
pub(crate) fn new(
module: &Module,
#[cfg_attr(not(feature = "doc"), allow(unused))] module: &Module,
hash: Hash,
item: ItemBuf,
kind: meta::Kind,
Expand Down Expand Up @@ -95,7 +95,9 @@ pub struct Context {
/// Whether or not to include the prelude when constructing a new unit.
has_default_modules: bool,
/// Item metadata in the context.
meta: HashMap<ItemBuf, PrivMeta>,
meta: HashMap<Hash, PrivMeta>,
/// Store item to hash mapping.
item_to_hash: HashMap<ItemBuf, Hash>,
/// Information on functions.
functions_info: HashMap<Hash, meta::Signature>,
/// Registered native function handlers.
Expand Down Expand Up @@ -283,18 +285,25 @@ impl Context {
}

/// Access the context meta for the given item.
pub(crate) fn lookup_meta(&self, name: &Item) -> Option<&PrivMeta> {
self.meta.get(name)
pub(crate) fn lookup_meta(&self, item: &Item) -> Option<&PrivMeta> {
let hash = self.item_to_hash.get(item)?;
self.meta.get(hash)
}

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

/// Look up signature of function.
#[cfg(feature = "doc")]
pub(crate) fn lookup_signature(&self, hash: Hash) -> Option<&meta::Signature> {
self.functions_info.get(&hash)
}

/// Iterate over all metadata in the context.
pub fn iter_meta(&self) -> impl Iterator<Item = (&Item, &PrivMeta)> + '_ {
self.meta.iter().map(|(item, meta)| (item.as_ref(), meta))
pub fn iter_meta(&self) -> impl Iterator<Item = &PrivMeta> + '_ {
self.meta.values()
}

/// Check if unit contains the given name by prefix.
Expand Down Expand Up @@ -342,14 +351,15 @@ impl Context {

/// Install the given meta.
fn install_meta(&mut self, meta: PrivMeta) -> Result<(), ContextError> {
match self.meta.entry(meta.item.clone()) {
match self.meta.entry(meta.hash) {
hash_map::Entry::Occupied(e) => {
return Err(ContextError::ConflictingMeta {
existing: Box::new(e.get().info()),
current: Box::new(meta.info()),
});
}
hash_map::Entry::Vacant(e) => {
self.item_to_hash.insert(meta.item.clone(), meta.hash);
e.insert(meta);
}
}
Expand Down Expand Up @@ -604,6 +614,7 @@ impl Context {
};

let hash = assoc
.name
.kind
.hash(key.type_hash)
.with_parameters(key.parameters);
Expand All @@ -613,7 +624,7 @@ impl Context {
is_async: assoc.is_async,
args: assoc.args,
kind: meta::SignatureKind::Instance {
name: assoc.kind.clone(),
name: assoc.name.kind.clone(),
self_type_info: info.type_info.clone(),
},
};
Expand All @@ -639,7 +650,7 @@ impl Context {
//
// The other alternatives are protocol functions (which are not free)
// and plain hashes.
if let AssociatedFunctionKind::Instance(name) = &assoc.kind {
if let AssociatedFunctionKind::Instance(name) = &assoc.name.kind {
let item = info.item.extended(name);
self.names.insert(&item);

Expand Down Expand Up @@ -667,7 +678,7 @@ impl Context {

self.functions.insert(hash, assoc.handler.clone());

if !self.meta.contains_key(&item) {
if !self.item_to_hash.contains_key(&item) {
self.install_meta(PrivMeta::new(
module,
type_hash,
Expand Down
48 changes: 11 additions & 37 deletions crates/rune/src/compile/function_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ use crate::compile::module::{
AssocType, AssociatedFunctionKey, AsyncFunction, AsyncInstFn, Function, InstFn,
};
use crate::compile::{IntoComponent, ItemBuf, Named};
use crate::hash::{Hash, Params};
use crate::hash::Hash;
use crate::runtime::{FunctionHandler, Protocol};

mod sealed {
use crate::hash::Params;
use crate::params::Params;
use crate::runtime::Protocol;

pub trait Sealed {}

impl Sealed for &str {}
impl Sealed for Protocol {}
impl<T, P> Sealed for Params<T, P> {}
impl<T, const N: usize> Sealed for Params<T, N> {}
}

/// Type used to collect and store function metadata through the
Expand Down Expand Up @@ -135,6 +135,8 @@ impl ToInstance for &str {
AssociatedFunctionName {
kind: AssociatedFunctionKind::Instance(self.into()),
parameters: Hash::EMPTY,
#[cfg(feature = "doc")]
parameter_types: vec![],
}
}
}
Expand All @@ -145,40 +147,8 @@ impl ToFieldFunction for &str {
AssociatedFunctionName {
kind: AssociatedFunctionKind::FieldFn(protocol, self.into()),
parameters: Hash::EMPTY,
}
}
}

impl<T, P> ToInstance for Params<T, P>
where
T: ToInstance,
P: IntoIterator,
P::Item: std::hash::Hash,
{
#[inline]
fn to_instance(self) -> AssociatedFunctionName {
let info = self.name.to_instance();

AssociatedFunctionName {
kind: info.kind,
parameters: Hash::parameters(self.parameters),
}
}
}

impl<T, P> ToFieldFunction for Params<T, P>
where
T: ToFieldFunction,
P: IntoIterator,
P::Item: std::hash::Hash,
{
#[inline]
fn to_field_function(self, protocol: Protocol) -> AssociatedFunctionName {
let info = self.name.to_field_function(protocol);

AssociatedFunctionName {
kind: info.kind,
parameters: Hash::parameters(self.parameters),
#[cfg(feature = "doc")]
parameter_types: vec![],
}
}
}
Expand All @@ -192,13 +162,17 @@ pub struct AssociatedFunctionName {
pub kind: AssociatedFunctionKind,
/// Parameters hash.
pub parameters: Hash,
#[cfg(feature = "doc")]
pub parameter_types: Vec<Hash>,
}

impl AssociatedFunctionName {
pub(crate) fn index(protocol: Protocol, index: usize) -> Self {
Self {
kind: AssociatedFunctionKind::IndexFn(protocol, index),
parameters: Hash::EMPTY,
#[cfg(feature = "doc")]
parameter_types: vec![],
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions crates/rune/src/compile/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ use crate::hash::Hash;
use crate::parse::{Id, ParseError, ResolveContext};
use crate::runtime::{ConstValue, TypeInfo};

/// Provides a human-readable description of a meta item. This is cheaper to use
/// than [Meta] because it avoids having to clone some data.
/// A meta reference to an item being compiled.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct MetaRef<'a> {
Expand Down
14 changes: 8 additions & 6 deletions crates/rune/src/compile/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,16 +202,18 @@ pub(crate) enum TypeSpecification {
#[derive(Clone)]
#[non_exhaustive]
pub struct AssociatedFunction {
/// Handle of the associated function.
pub(crate) handler: Arc<FunctionHandler>,
/// Type information of the associated function.
pub(crate) type_info: TypeInfo,
/// If the function is asynchronous.
pub is_async: bool,
pub(crate) is_async: bool,
/// Arguments the function receives.
pub args: Option<usize>,
/// The kind of the associated function.
pub kind: AssociatedFunctionKind,
pub(crate) args: Option<usize>,
/// The full name of the associated function.
pub(crate) name: AssociatedFunctionName,
/// The documentation of the associated function.
pub docs: Docs,
pub(crate) docs: Docs,
}

/// A key that identifies an associated function.
Expand Down Expand Up @@ -1071,7 +1073,7 @@ impl Module {
type_info: data.ty.type_info,
is_async: data.is_async,
args: data.args,
kind: data.name.kind,
name: data.name,
docs,
};

Expand Down
6 changes: 6 additions & 0 deletions crates/rune/src/compile/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ impl Pool {
self.item(id)
}

/// Get the hash associated with a module item.
pub(crate) fn module_item_hash(&self, id: ModId) -> Hash {
let id = self.module(id).item;
self.item_type_hash(id)
}

/// Get by item id.
pub(crate) fn module_by_item(&self, id: ItemId) -> Option<&ModMeta> {
Some(self.module(*self.item_to_mod.get(&id)?))
Expand Down
1 change: 1 addition & 0 deletions crates/rune/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ pub use self::html::write_html;

mod visitor;
pub use self::visitor::Visitor;
pub(crate) use self::visitor::VisitorData;
Loading