1use super::{
2 instructions::ClrInstruction,
3 pool::ClrConstantPool,
4 types::{
5 ClrAccessFlags, ClrAttribute, ClrExceptionHandler, ClrExternalAssembly, ClrField, ClrLocalVariable, ClrMethodImplFlags,
6 ClrModule, ClrParameter, ClrTypeReference, ClrVersion,
7 },
8};
9use gaia_types::{GaiaError, Result, SourceLocation};
10
11#[derive(Debug, Clone)]
13pub struct ClrProgram {
14 pub name: String,
16 pub version: ClrVersion,
18 pub access_flags: ClrAccessFlags,
20 pub external_assemblies: Vec<ClrExternalAssembly>,
22 pub module: Option<ClrModule>,
24 pub types: Vec<ClrType>,
26 pub global_methods: Vec<ClrMethod>,
28 pub global_fields: Vec<ClrField>,
30 pub attributes: Vec<ClrAttribute>,
32 pub constant_pool: ClrConstantPool,
34 pub source_file: Option<String>,
36}
37
38impl ClrProgram {
39 pub fn new(name: impl Into<String>) -> Self {
41 Self {
42 name: name.into(),
43 version: ClrVersion::default(),
44 access_flags: ClrAccessFlags::default(),
45 external_assemblies: Vec::new(),
46 module: None,
47 types: Vec::new(),
48 global_methods: Vec::new(),
49 global_fields: Vec::new(),
50 attributes: Vec::new(),
51 constant_pool: ClrConstantPool::new(),
52 source_file: None,
53 }
54 }
55
56 pub fn add_type(&mut self, clr_type: ClrType) {
58 self.types.push(clr_type);
59 }
60
61 pub fn add_global_method(&mut self, method: ClrMethod) {
63 self.global_methods.push(method);
64 }
65
66 pub fn add_global_field(&mut self, field: ClrField) {
68 self.global_fields.push(field);
69 }
70
71 pub fn add_external_assembly(&mut self, assembly: ClrExternalAssembly) {
73 self.external_assemblies.push(assembly);
74 }
75
76 pub fn validate(&self) -> Result<()> {
78 if self.name.is_empty() {
80 return Err(GaiaError::syntax_error("程序集名称不能为空".to_string(), SourceLocation::default()));
81 }
82
83 for clr_type in &self.types {
85 clr_type.validate()?;
86 }
87
88 for method in &self.global_methods {
90 method.validate()?;
91 }
92
93 Ok(())
94 }
95}
96
97#[derive(Debug, Clone)]
99pub struct ClrType {
100 pub name: String,
102 pub namespace: Option<String>,
104 pub access_flags: ClrAccessFlags,
106 pub base_type: Option<ClrTypeReference>,
108 pub interfaces: Vec<ClrTypeReference>,
110 pub fields: Vec<ClrField>,
112 pub methods: Vec<ClrMethod>,
114 pub properties: Vec<String>, pub events: Vec<String>, pub nested_types: Vec<ClrType>,
120 pub attributes: Vec<ClrAttribute>,
122}
123
124impl ClrType {
125 pub fn new(name: String, namespace: Option<String>) -> Self {
127 Self {
128 name,
129 namespace,
130 access_flags: ClrAccessFlags::default(),
131 base_type: None,
132 interfaces: Vec::new(),
133 fields: Vec::new(),
134 methods: Vec::new(),
135 properties: Vec::new(),
136 events: Vec::new(),
137 nested_types: Vec::new(),
138 attributes: Vec::new(),
139 }
140 }
141
142 pub fn add_method(&mut self, method: ClrMethod) {
144 self.methods.push(method);
145 }
146
147 pub fn add_field(&mut self, field: ClrField) {
149 self.fields.push(field);
150 }
151
152 pub fn validate(&self) -> Result<()> {
154 if self.name.is_empty() {
156 return Err(GaiaError::syntax_error("类型名称不能为空".to_string(), SourceLocation::default()));
157 }
158
159 for method in &self.methods {
161 method.validate()?;
162 }
163
164 Ok(())
165 }
166}
167
168#[derive(Debug, Clone)]
170pub struct ClrMethod {
171 pub name: String,
173 pub return_type: ClrTypeReference,
175 pub parameters: Vec<ClrParameter>,
177 pub access_flags: ClrAccessFlags,
179 pub impl_flags: ClrMethodImplFlags,
181 pub instructions: Vec<ClrInstruction>,
183 pub max_stack: u32,
185 pub locals: Vec<ClrLocalVariable>,
187 pub exception_handlers: Vec<ClrExceptionHandler>,
189 pub attributes: Vec<ClrAttribute>,
191 pub is_entry_point: bool,
193}
194
195impl ClrMethod {
196 pub fn new(name: String, return_type: ClrTypeReference) -> Self {
198 Self {
199 name,
200 return_type,
201 parameters: Vec::new(),
202 access_flags: ClrAccessFlags::default(),
203 impl_flags: ClrMethodImplFlags::default(),
204 instructions: Vec::new(),
205 max_stack: 8,
206 locals: Vec::new(),
207 exception_handlers: Vec::new(),
208 attributes: Vec::new(),
209 is_entry_point: false,
210 }
211 }
212
213 pub fn add_instruction(&mut self, instruction: ClrInstruction) {
215 self.instructions.push(instruction);
216 }
217
218 pub fn add_parameter(&mut self, parameter: ClrParameter) {
220 self.parameters.push(parameter);
221 }
222
223 pub fn validate(&self) -> Result<()> {
225 if self.name.is_empty() {
227 return Err(GaiaError::syntax_error("方法名称不能为空".to_string(), SourceLocation::default()));
228 }
229
230 Ok(())
231 }
232}