1use alloc::{boxed::Box, format};
2
3use super::*;
4use crate::{AttributeValue, any::AsAny, traits::TraitInfo};
5
6pub trait OpRegistration: Op {
7 fn dialect_name() -> ::midenc_hir_symbol::Symbol;
9 fn name() -> ::midenc_hir_symbol::Symbol;
11 fn full_name() -> ::midenc_hir_symbol::Symbol {
13 ::midenc_hir_symbol::Symbol::intern(format!(
14 "{}.{}",
15 Self::dialect_name(),
16 <Self as OpRegistration>::name()
17 ))
18 }
19 fn traits() -> Box<[TraitInfo]>;
21}
22
23pub trait BuildableOp<Args: core::marker::Tuple>: Op {
24 type Builder<'a, T>: FnOnce<Args, Output = Result<UnsafeIntrusiveEntityRef<Self>, crate::Report>>
25 + 'a
26 where
27 T: ?Sized + Builder + 'a;
28 fn builder<'b, B>(builder: &'b mut B, span: SourceSpan) -> Self::Builder<'b, B>
29 where
30 B: ?Sized + Builder + 'b;
31}
32
33pub trait Op: AsAny + OpVerifier {
34 fn name(&self) -> OperationName;
38 fn as_operation(&self) -> &Operation;
39 fn as_operation_mut(&mut self) -> &mut Operation;
40
41 fn print(&self, flags: &OpPrintingFlags) -> crate::formatter::Document {
42 let operation = self.as_operation();
43 operation.print(flags, operation.context())
44 }
45
46 #[inline]
47 fn as_operation_ref(&self) -> OperationRef {
48 self.as_operation().as_operation_ref()
49 }
50 fn set_span(&mut self, span: SourceSpan) {
51 self.as_operation_mut().set_span(span);
52 }
53 fn parent(&self) -> Option<BlockRef> {
54 self.as_operation().parent()
55 }
56 fn parent_region(&self) -> Option<RegionRef> {
57 self.as_operation().parent_region()
58 }
59 fn parent_op(&self) -> Option<OperationRef> {
60 self.as_operation().parent_op()
61 }
62 fn num_regions(&self) -> usize {
63 self.as_operation().num_regions()
64 }
65 fn regions(&self) -> &RegionList {
66 self.as_operation().regions()
67 }
68 fn regions_mut(&mut self) -> &mut RegionList {
69 self.as_operation_mut().regions_mut()
70 }
71 fn region(&self, index: usize) -> EntityRef<'_, Region> {
72 self.as_operation().region(index)
73 }
74 fn region_mut(&mut self, index: usize) -> EntityMut<'_, Region> {
75 self.as_operation_mut().region_mut(index)
76 }
77 fn has_successors(&self) -> bool {
78 self.as_operation().has_successors()
79 }
80 fn num_successors(&self) -> usize {
81 self.as_operation().num_successors()
82 }
83 fn has_operands(&self) -> bool {
84 self.as_operation().has_operands()
85 }
86 fn num_operands(&self) -> usize {
87 self.as_operation().num_operands()
88 }
89 fn operands(&self) -> &OpOperandStorage {
90 self.as_operation().operands()
91 }
92 fn operands_mut(&mut self) -> &mut OpOperandStorage {
93 self.as_operation_mut().operands_mut()
94 }
95 fn has_results(&self) -> bool {
96 self.as_operation().has_results()
97 }
98 fn num_results(&self) -> usize {
99 self.as_operation().num_results()
100 }
101 fn results(&self) -> &OpResultStorage {
102 self.as_operation().results()
103 }
104 fn results_mut(&mut self) -> &mut OpResultStorage {
105 self.as_operation_mut().results_mut()
106 }
107 fn successors(&self) -> &OpSuccessorStorage {
108 self.as_operation().successors()
109 }
110 fn successors_mut(&mut self) -> &mut OpSuccessorStorage {
111 self.as_operation_mut().successors_mut()
112 }
113}
114
115impl Spanned for dyn Op {
116 fn span(&self) -> SourceSpan {
117 self.as_operation().span
118 }
119}
120
121pub trait OpExt {
122 fn get_attribute(&self, name: impl Into<interner::Symbol>) -> Option<&dyn AttributeValue>;
124
125 fn has_attribute(&self, name: impl Into<interner::Symbol>) -> bool;
127
128 fn set_attribute(
130 &mut self,
131 name: impl Into<interner::Symbol>,
132 value: Option<impl AttributeValue>,
133 );
134
135 fn remove_attribute(&mut self, name: impl Into<interner::Symbol>);
137
138 fn nearest_parent_op<T: Op>(&self) -> Option<UnsafeIntrusiveEntityRef<T>>;
141}
142
143impl<T: ?Sized + Op> OpExt for T {
144 #[inline]
145 fn get_attribute(&self, name: impl Into<interner::Symbol>) -> Option<&dyn AttributeValue> {
146 self.as_operation().get_attribute(name)
147 }
148
149 #[inline]
150 fn has_attribute(&self, name: impl Into<interner::Symbol>) -> bool {
151 self.as_operation().has_attribute(name)
152 }
153
154 #[inline]
155 fn set_attribute(
156 &mut self,
157 name: impl Into<interner::Symbol>,
158 value: Option<impl AttributeValue>,
159 ) {
160 self.as_operation_mut().set_attribute(name, value);
161 }
162
163 #[inline]
164 fn remove_attribute(&mut self, name: impl Into<interner::Symbol>) {
165 self.as_operation_mut().remove_attribute(name);
166 }
167
168 #[inline]
169 fn nearest_parent_op<U: Op>(&self) -> Option<UnsafeIntrusiveEntityRef<U>> {
170 self.as_operation().nearest_parent_op()
171 }
172}