Skip to main content

melior_macro/dialect/operation/
result.rs

1use super::{OperationElement, OperationField, VariadicKind};
2use crate::dialect::{
3    error::Error,
4    r#type::Type as ElementType,
5    utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier},
6};
7use proc_macro2::{Span, TokenStream};
8use quote::quote;
9use syn::{parse_quote, Ident, Type};
10
11#[derive(Debug)]
12pub struct OperationResult<'a> {
13    name: &'a str,
14    singular_identifier: Ident,
15    r#type: ElementType,
16    variadic_kind: VariadicKind,
17}
18
19impl<'a> OperationResult<'a> {
20    pub fn new(
21        name: &'a str,
22        r#type: ElementType,
23        variadic_kind: VariadicKind,
24    ) -> Result<Self, Error> {
25        Ok(Self {
26            name,
27            singular_identifier: sanitize_snake_case_identifier(name)?,
28            r#type,
29            variadic_kind,
30        })
31    }
32}
33
34impl OperationField for OperationResult<'_> {
35    fn name(&self) -> &str {
36        self.name
37    }
38
39    fn singular_identifier(&self) -> &Ident {
40        &self.singular_identifier
41    }
42
43    fn plural_kind_identifier(&self) -> Ident {
44        Ident::new("results", Span::call_site())
45    }
46
47    // TODO Share this logic with `Operand`.
48    fn parameter_type(&self) -> Type {
49        let r#type: Type = parse_quote!(::melior::ir::Type<'c>);
50
51        if self.r#type.is_variadic() {
52            parse_quote! { &[#r#type] }
53        } else {
54            r#type
55        }
56    }
57
58    // TODO Share this logic with `Operand`.
59    fn return_type(&self) -> Type {
60        let r#type: Type = parse_quote!(::melior::ir::operation::OperationResult<'c, '_>);
61
62        if !self.r#type.is_variadic() {
63            generate_result_type(r#type)
64        } else if self.variadic_kind == VariadicKind::AttributeSized {
65            generate_result_type(generate_iterator_type(r#type))
66        } else {
67            generate_iterator_type(r#type)
68        }
69    }
70
71    fn is_optional(&self) -> bool {
72        self.r#type.is_optional()
73    }
74
75    fn add_arguments(&self, name: &Ident) -> TokenStream {
76        if self.r#type.is_unfixed() && !self.r#type.is_optional() {
77            quote! { #name }
78        } else {
79            quote! { &[#name] }
80        }
81    }
82}
83
84impl OperationElement for OperationResult<'_> {
85    fn is_variadic(&self) -> bool {
86        self.r#type.is_variadic()
87    }
88
89    fn variadic_kind(&self) -> &VariadicKind {
90        &self.variadic_kind
91    }
92}