@@ -11,13 +11,14 @@ use std::{
11
11
sync:: { Arc , Mutex , RwLock } ,
12
12
} ;
13
13
14
- use ast:: provider:: IdProvider ;
14
+ use ast:: ast:: { DataType , DataTypeDeclaration , UserTypeDeclaration } ;
15
+ use ast:: { ast:: Variable , provider:: IdProvider } ;
15
16
use plc:: {
16
17
codegen:: GeneratedModule ,
17
- index:: { ArgumentType , PouIndexEntry , VariableIndexEntry } ,
18
+ index:: PouIndexEntry ,
18
19
lowering:: calls:: AggregateTypeLowerer ,
19
20
output:: FormatOption ,
20
- typesystem:: { DataType , DataTypeInformation , VOID_INTERNAL_NAME , VOID_TYPE } ,
21
+ typesystem:: { VOID_INTERNAL_NAME , VOID_POINTER_TYPE } ,
21
22
ConfigFormat , OnlineChange , Target ,
22
23
} ;
23
24
use plc_diagnostics:: diagnostics:: Diagnostic ;
@@ -286,66 +287,62 @@ impl PipelineParticipantMut for AggregateTypeLowerer {
286
287
}
287
288
}
288
289
289
- pub struct VTableIndexer ;
290
+ pub struct VTableIndexer {
291
+ id_provider : IdProvider ,
292
+ }
290
293
291
294
impl VTableIndexer {
295
+ pub fn new ( id_provider : IdProvider ) -> Self {
296
+ Self { id_provider }
297
+ }
298
+
292
299
fn get_vtable_name ( name : & str ) -> String {
293
300
format ! ( "__vtable_{name}" )
294
301
}
295
302
296
- fn create_vtable ( name : & str , methods : Vec < & PouIndexEntry > ) -> DataType {
297
- let mut members = Vec :: new ( ) ;
298
- for ( index, method) in methods. iter ( ) . enumerate ( ) {
299
- let entry = VariableIndexEntry :: new (
300
- method. get_name ( ) ,
301
- method. get_name ( ) ,
302
- VOID_INTERNAL_NAME ,
303
- ArgumentType :: ByRef ( plc:: index:: VariableType :: Local ) ,
304
- index as u32 ,
305
- SourceLocation :: internal ( ) ,
306
- ) ;
307
- members. push ( entry) ;
308
- }
309
-
310
- let information = DataTypeInformation :: Struct {
311
- name : Self :: get_vtable_name ( name) ,
312
- members,
313
- source : plc:: typesystem:: StructSource :: Internal ( plc:: typesystem:: InternalType :: VTable ) ,
314
- } ;
315
-
316
- DataType {
317
- information,
318
- name : Self :: get_vtable_name ( name) ,
319
- nature : ast:: ast:: TypeNature :: Derived ,
320
- initial_value : None ,
321
- location : SourceLocation :: internal ( ) ,
303
+ fn create_vtable (
304
+ name : & str ,
305
+ methods : Vec < & PouIndexEntry > ,
306
+ location : SourceLocation ,
307
+ ) -> UserTypeDeclaration {
308
+ let mut variables = Vec :: new ( ) ;
309
+ for method in methods. iter ( ) {
310
+ let variable = Variable {
311
+ name : method. get_name ( ) . to_string ( ) ,
312
+ data_type_declaration : DataTypeDeclaration :: Reference {
313
+ referenced_type : VOID_POINTER_TYPE . into ( ) ,
314
+ location : method. get_location ( ) . clone ( ) ,
315
+ } ,
316
+ initializer : None ,
317
+ address : None ,
318
+ location : method. get_location ( ) . clone ( ) ,
319
+ } ;
320
+ variables. push ( variable) ;
322
321
}
322
+ let data_type = DataType :: StructType { name : Some ( Self :: get_vtable_name ( name) ) , variables } ;
323
+ UserTypeDeclaration { data_type, initializer : None , location, scope : Some ( name. to_string ( ) ) }
323
324
}
324
325
}
325
326
326
327
impl PipelineParticipantMut for VTableIndexer {
327
- fn pre_annotate ( & mut self , indexed_project : IndexedProject ) -> IndexedProject {
328
+ fn post_index ( & mut self , indexed_project : IndexedProject ) -> IndexedProject {
328
329
//For each class or interface, create a vtable type
329
330
//and add it to the index
330
- let IndexedProject { project, index, unresolvables } = indexed_project;
331
+ let IndexedProject { mut project, index, .. } = indexed_project;
331
332
let mut vtables = Vec :: new ( ) ;
332
333
for interface in index. get_interfaces ( ) . values ( ) {
333
334
let methods = interface. get_methods ( & index) ;
334
- let vtable = Self :: create_vtable ( interface. get_name ( ) , methods) ;
335
+ let vtable = Self :: create_vtable ( interface. get_name ( ) , methods, interface . get_location ( ) . clone ( ) ) ;
335
336
vtables. push ( vtable) ;
336
337
}
337
338
338
339
for pou in index. get_pous ( ) . values ( ) . filter ( |it| it. is_function_block ( ) || it. is_class ( ) ) {
339
340
let methods = index. get_methods ( pou. get_name ( ) ) ;
340
- let vtable = Self :: create_vtable ( pou. get_name ( ) , methods) ;
341
+ let vtable = Self :: create_vtable ( pou. get_name ( ) , methods, pou . get_location ( ) . clone ( ) ) ;
341
342
vtables. push ( vtable) ;
342
343
}
343
344
344
- let mut index = index;
345
- for vtable in vtables {
346
- index. register_type ( vtable) ;
347
- }
348
-
349
- IndexedProject { project, index, unresolvables }
345
+ project. units . first_mut ( ) . unwrap ( ) . user_types . extend ( vtables) ;
346
+ project. index ( self . id_provider . clone ( ) )
350
347
}
351
348
}
0 commit comments