mod query;
use core::fmt;
use core::mem::take;
use core::num::NonZeroUsize;
use rust_alloc::rc::Rc;
pub(crate) use self::query::{Query, QueryInner, QuerySource};
use crate as rune;
use crate::alloc::path::PathBuf;
use crate::alloc::prelude::*;
use crate::ast::{self, OptionSpanned, Span, Spanned};
use crate::compile::{ir, Doc, Error, ItemId, ItemMeta, Location, ModId, Result};
use crate::grammar::{Ignore, Node, NodeAt, NodeId, Tree};
use crate::hash::Hash;
use crate::hir;
use crate::indexing;
use crate::parse::NonZeroId;
use crate::runtime::format;
use crate::runtime::Call;
#[derive(Default, Debug, TryClone, Clone, Copy)]
#[try_clone(copy)]
pub(crate) enum Used {
Unused,
#[default]
Used,
}
impl Used {
pub(crate) fn is_unused(self) -> bool {
matches!(self, Self::Unused)
}
}
pub(crate) struct Named<'ast> {
pub(crate) module: ModId,
pub(crate) item: ItemId,
pub(crate) trailing: usize,
pub(crate) parameters: [Option<(
&'ast dyn Spanned,
&'ast ast::AngleBracketed<ast::PathSegmentExpr, T![,]>,
)>; 2],
}
impl fmt::Display for Named<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.item, f)
}
}
pub(crate) enum Named2Kind {
Full,
Ident(ast::Ident),
SelfValue(#[allow(unused)] ast::SelfValue),
}
pub(crate) struct Named2<'a> {
pub(crate) module: ModId,
pub(crate) kind: Named2Kind,
pub(crate) item: ItemId,
pub(crate) trailing: usize,
pub(crate) parameters: [Option<Node<'a>>; 2],
}
impl fmt::Display for Named2<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.item, f)
}
}
#[allow(clippy::large_enum_variant)]
pub(crate) enum BuiltInMacro {
Template(BuiltInTemplate),
Format(BuiltInFormat),
File(BuiltInFile),
Line(BuiltInLine),
}
pub(crate) enum BuiltInMacro2 {
File(ast::LitStr),
Line(usize),
Template(Rc<Tree>, BuiltInLiteral),
Format(Rc<Tree>),
}
#[derive(Spanned)]
pub(crate) struct BuiltInTemplate {
#[rune(span)]
pub(crate) span: Span,
pub(crate) from_literal: bool,
pub(crate) exprs: Vec<ast::Expr>,
}
#[derive(Spanned)]
pub(crate) struct BuiltInFormat {
#[rune(span)]
pub(crate) span: Span,
pub(crate) fill: Option<char>,
pub(crate) align: Option<format::Alignment>,
pub(crate) width: Option<NonZeroUsize>,
pub(crate) precision: Option<NonZeroUsize>,
pub(crate) flags: Option<format::Flags>,
pub(crate) format_type: Option<format::Type>,
pub(crate) value: ast::Expr,
}
#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq, Spanned)]
#[try_clone(copy)]
pub(crate) struct BuiltInFile {
pub(crate) value: ast::Lit,
}
#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq, Spanned)]
#[try_clone(copy)]
pub(crate) struct BuiltInLine {
pub(crate) value: ast::Lit,
}
#[derive(Debug, TryClone)]
pub(crate) struct Closure<'hir> {
pub(crate) hir: &'hir hir::ExprClosure<'hir>,
pub(crate) call: Call,
}
#[derive(Debug, TryClone)]
pub(crate) struct AsyncBlock<'hir> {
pub(crate) hir: &'hir hir::AsyncBlock<'hir>,
pub(crate) call: Call,
}
#[derive(Debug, TryClone)]
pub(crate) enum SecondaryBuild<'hir> {
Closure(Closure<'hir>),
AsyncBlock(AsyncBlock<'hir>),
}
#[derive(Debug, TryClone)]
pub(crate) struct SecondaryBuildEntry<'hir> {
pub(crate) item_meta: ItemMeta,
pub(crate) build: SecondaryBuild<'hir>,
}
#[derive(Debug, TryClone)]
pub(crate) enum Build {
Function(indexing::Function),
Unused,
Import(indexing::Import),
ReExport,
Query,
}
#[derive(Debug, TryClone)]
pub(crate) struct BuildEntry {
pub(crate) item_meta: ItemMeta,
pub(crate) build: Build,
}
pub(crate) enum ImplItemKind {
Ast {
path: Box<ast::Path>,
functions: Vec<ast::ItemFn>,
},
Node {
path: NodeAt,
functions: Vec<(NodeId, Attrs)>,
},
}
#[must_use = "must be consumed"]
#[derive(Default, Debug)]
pub(crate) struct Attrs {
pub(crate) test: Option<Span>,
pub(crate) bench: Option<Span>,
pub(crate) docs: Vec<Doc>,
pub(crate) builtin: Option<(Span, BuiltInLiteral)>,
}
impl Attrs {
pub(crate) fn deny_non_docs(self, cx: &mut dyn Ignore<'_>) -> Result<()> {
if let Some(span) = self.test {
cx.error(Error::msg(span, "unsupported #[test] attribute"))?;
}
if let Some(span) = self.bench {
cx.error(Error::msg(span, "unsupported #[bench] attribute"))?;
}
if let Some((span, _)) = self.builtin {
cx.error(Error::msg(span, "unsupported #[builtin] attribute"))?;
}
Ok(())
}
pub(crate) fn deny_any(self, cx: &mut dyn Ignore<'_>) -> Result<()> {
if let Some(span) = self.docs.option_span() {
cx.error(Error::msg(span, "unsupported documentation"))?;
}
self.deny_non_docs(cx)?;
Ok(())
}
}
pub(crate) struct ImplItem {
pub(crate) kind: ImplItemKind,
pub(crate) location: Location,
pub(crate) root: Option<PathBuf>,
pub(crate) nested_item: Option<Span>,
pub(crate) macro_depth: usize,
}
#[must_use = "Must be used to report errors"]
pub(crate) struct ExpandMacroBuiltin {
pub(crate) id: NonZeroId,
pub(crate) node: NodeAt,
pub(crate) location: Location,
pub(crate) root: Option<PathBuf>,
pub(crate) macro_depth: usize,
pub(crate) item: indexing::IndexItem,
pub(crate) literal: BuiltInLiteral,
}
impl ExpandMacroBuiltin {
pub(crate) fn finish(self) -> Result<NonZeroId> {
if let BuiltInLiteral::Yes(span) = self.literal {
return Err(Error::msg(
span,
"#[builtin(literal)] option is not allowed",
));
}
Ok(self.id)
}
}
#[derive(Default, Debug)]
pub(crate) enum BuiltInLiteral {
Yes(Span),
#[default]
No,
}
impl BuiltInLiteral {
pub(crate) fn take(&mut self) -> Self {
take(self)
}
pub(crate) fn is_yes(&self) -> bool {
matches!(self, Self::Yes(_))
}
}
pub(crate) enum DeferEntry {
ImplItem(ImplItem),
ExpandMacroBuiltin(ExpandMacroBuiltin),
ExpandMacroCall(ExpandMacroBuiltin),
}
pub(crate) struct ConstFn<'hir> {
pub(crate) item_meta: ItemMeta,
pub(crate) ir_fn: ir::IrFn,
#[allow(unused)]
pub(crate) hir: hir::ItemFn<'hir>,
}
pub(crate) enum ExpandedMacro {
Builtin(BuiltInMacro2),
Tree(Rc<Tree>),
}
#[derive(Default)]
pub(crate) struct GenericsParameters {
pub(crate) trailing: usize,
pub(crate) parameters: [Option<Hash>; 2],
}
impl GenericsParameters {
pub(crate) fn is_empty(&self) -> bool {
self.parameters.iter().all(|p| p.is_none())
}
}
impl fmt::Debug for GenericsParameters {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut f = f.debug_list();
for p in &self.parameters[2 - self.trailing..] {
f.entry(p);
}
f.finish()
}
}
impl AsRef<GenericsParameters> for GenericsParameters {
#[inline]
fn as_ref(&self) -> &GenericsParameters {
self
}
}