dada_ir_ast/ast/
function.rs1use dada_util::{FromImpls, SalsaSerialize};
2use salsa::Update;
3use serde::Serialize;
4
5use super::{AstGenericDecl, AstPerm, AstStatement, AstTy, SpanVec, SpannedIdentifier};
6use crate::{
7 ast::{AstVisibility, AstWhereClauses, DeferredParse},
8 span::{Span, Spanned},
9};
10
11#[derive(SalsaSerialize)]
13#[salsa::tracked(debug)]
14pub struct AstFunction<'db> {
15 pub span: Span<'db>,
17
18 pub effects: AstFunctionEffects<'db>,
20
21 pub fn_span: Span<'db>,
23
24 pub visibility: Option<AstVisibility<'db>>,
26
27 pub name: SpannedIdentifier<'db>,
29
30 #[return_ref]
32 pub generics: Option<SpanVec<'db, AstGenericDecl<'db>>>,
33
34 #[return_ref]
36 pub inputs: SpanVec<'db, AstFunctionInput<'db>>,
37
38 pub output_ty: Option<AstTy<'db>>,
40
41 #[return_ref]
43 pub where_clauses: Option<AstWhereClauses<'db>>,
44
45 #[return_ref]
47 pub body: Option<DeferredParse<'db>>,
48}
49
50#[derive(SalsaSerialize)]
53#[salsa::tracked(debug)]
54pub struct AstMainFunction<'db> {
55 #[return_ref]
56 pub statements: SpanVec<'db, AstStatement<'db>>,
57}
58
59impl<'db> Spanned<'db> for AstMainFunction<'db> {
60 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
61 self.statements(db).span
62 }
63}
64
65#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
66pub struct AstFunctionEffects<'db> {
67 pub async_effect: Option<Span<'db>>,
68 pub unsafe_effect: Option<Span<'db>>,
69}
70
71impl<'db> Spanned<'db> for AstFunction<'db> {
72 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
73 AstFunction::span(*self, db)
74 }
75}
76
77#[derive(
78 Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, FromImpls, Serialize,
79)]
80pub enum AstFunctionInput<'db> {
81 SelfArg(AstSelfArg<'db>),
82 Variable(VariableDecl<'db>),
83}
84
85impl<'db> Spanned<'db> for AstFunctionInput<'db> {
86 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
87 match self {
88 AstFunctionInput::SelfArg(arg) => arg.span(db),
89 AstFunctionInput::Variable(var) => var.span(db),
90 }
91 }
92}
93
94#[derive(SalsaSerialize)]
95#[salsa::tracked(debug)]
96pub struct AstSelfArg<'db> {
97 pub perm: Option<AstPerm<'db>>,
100 pub self_span: Span<'db>,
101}
102
103impl<'db> Spanned<'db> for AstSelfArg<'db> {
104 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
105 if let Some(perm) = self.perm(db) {
106 self.self_span(db).start_from(perm.span(db))
107 } else {
108 self.self_span(db)
109 }
110 }
111}
112
113#[derive(SalsaSerialize)]
115#[salsa::tracked(debug)]
116pub struct VariableDecl<'db> {
117 pub mutable: Option<Span<'db>>,
119
120 pub name: SpannedIdentifier<'db>,
122
123 pub perm: Option<AstPerm<'db>>,
126
127 pub base_ty: AstTy<'db>,
130}
131
132impl<'db> Spanned<'db> for VariableDecl<'db> {
133 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
134 self.name(db).span.to(db, self.base_ty(db).span(db))
135 }
136}