-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(indexer): indexing uses SymbolIndexer instead of visitor.rs
The indexer utilizes the visitor-trait to visit nodes that contain symbols. It delegates the concrete work to smaller, specialized indexer-implementations in src/index/indexer
- Loading branch information
Showing
14 changed files
with
963 additions
and
833 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use global_var_indexer::VarGlobalIndexer; | ||
use implementation_indexer::ImplementationIndexer; | ||
use plc_ast::{ | ||
ast::{CompilationUnit, Implementation, VariableBlockType}, | ||
visitor::{AstVisitor, Walker}, | ||
}; | ||
use pou_indexer::PouIndexer; | ||
use user_type_indexer::UserTypeIndexer; | ||
|
||
use super::Index; | ||
|
||
mod global_var_indexer; | ||
mod implementation_indexer; | ||
mod pou_indexer; | ||
mod user_type_indexer; | ||
|
||
/// Indexes all symbols found in the given Compiliation Unit | ||
/// and returns the resulting Index | ||
pub fn index(unit: &CompilationUnit) -> Index { | ||
// let mut index = Index::default(); | ||
let mut indexer = SymbolIndexer::default(); | ||
unit.walk(&mut indexer); | ||
indexer.index | ||
} | ||
|
||
/// Indexer that registers all symbols in the index | ||
#[derive(Default)] | ||
pub struct SymbolIndexer { | ||
pub index: Index, | ||
} | ||
|
||
/// The SymbolIndexer is responsible for registering all delcared types and symbols in the index. | ||
impl AstVisitor for SymbolIndexer { | ||
/// Visits a VAR_GLOBAL VariableBlock and registers all variables as globals in the index | ||
fn visit_variable_block(&mut self, block: &plc_ast::ast::VariableBlock) { | ||
if block.variable_block_type == VariableBlockType::Global { | ||
// let the global var indexer handle the global variables | ||
let mut indexer = VarGlobalIndexer::new(block.constant, block.linkage, &mut self.index); | ||
for var in &block.variables { | ||
indexer.visit_variable(var); | ||
} | ||
} | ||
} | ||
|
||
/// Visits a user type declaration | ||
/// Registers the user type in the index using the UserTypeIndexer | ||
fn visit_user_type_declaration(&mut self, user_type: &plc_ast::ast::UserTypeDeclaration) { | ||
UserTypeIndexer::new(&mut self.index, user_type).visit_user_type_declaration(user_type); | ||
} | ||
|
||
/// Visits a pou and registers all member variables in the index | ||
/// Also registers the pou's struct type in the index | ||
fn visit_pou(&mut self, pou: &plc_ast::ast::Pou) { | ||
PouIndexer::new(&mut self.index).visit_pou(pou); | ||
} | ||
|
||
/// Visits an implementation and registers the implementation in the index | ||
fn visit_implementation(&mut self, implementation: &Implementation) { | ||
ImplementationIndexer::new(&mut self.index).index_implementation(implementation); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use plc_ast::ast::LinkageType; | ||
|
||
use crate::index::{HardwareBinding, Index, VariableIndexEntry}; | ||
|
||
pub struct VarGlobalIndexer<'i> { | ||
constant: bool, | ||
linkage: LinkageType, | ||
index: &'i mut Index, | ||
} | ||
|
||
impl VarGlobalIndexer<'_> { | ||
pub fn new(constant: bool, linkage: LinkageType, index: &mut Index) -> VarGlobalIndexer<'_> { | ||
VarGlobalIndexer { constant, linkage, index } | ||
} | ||
|
||
pub fn visit_variable(&mut self, var: &plc_ast::ast::Variable) { | ||
let target_type = var.data_type_declaration.get_name().unwrap_or_default(); | ||
let initializer = self.index.get_mut_const_expressions().maybe_add_constant_expression( | ||
var.initializer.clone(), | ||
target_type, | ||
None, | ||
); | ||
let variable = VariableIndexEntry::create_global( | ||
&var.name, | ||
&var.name, | ||
var.data_type_declaration.get_name().expect("named variable datatype"), | ||
var.location.clone(), | ||
) | ||
.set_initial_value(initializer) | ||
.set_constant(self.constant) | ||
.set_linkage(self.linkage) | ||
.set_hardware_binding( | ||
var.address.as_ref().and_then(|it| HardwareBinding::from_statement(self.index, it, None)), | ||
); | ||
self.index.register_global_variable(&var.name, variable); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use plc_ast::ast::{Implementation, PouType, TypeNature}; | ||
|
||
use crate::{ | ||
index::{Index, PouIndexEntry}, | ||
typesystem::{self, DataTypeInformation}, | ||
}; | ||
|
||
pub struct ImplementationIndexer<'i> { | ||
index: &'i mut Index, | ||
} | ||
|
||
impl<'i> ImplementationIndexer<'i> { | ||
pub fn new(index: &'i mut Index) -> Self { | ||
Self { index } | ||
} | ||
|
||
pub fn index_implementation(&mut self, implementation: &Implementation) { | ||
let pou_type = &implementation.pou_type; | ||
let start_location = implementation | ||
.statements | ||
.first() | ||
.map(|it| it.get_location()) | ||
.as_ref() | ||
.or(Some(&implementation.location)) | ||
.cloned() | ||
.unwrap(); | ||
self.index.register_implementation( | ||
&implementation.name, | ||
&implementation.type_name, | ||
pou_type.get_optional_owner_class().as_ref(), | ||
pou_type.into(), | ||
implementation.generic, | ||
start_location, | ||
); | ||
//if we are registing an action, also register a datatype for it | ||
if pou_type == &PouType::Action { | ||
let datatype = typesystem::DataType { | ||
name: implementation.name.to_string(), | ||
initial_value: None, | ||
information: DataTypeInformation::Alias { | ||
name: implementation.name.clone(), | ||
referenced_type: implementation.type_name.clone(), | ||
}, | ||
nature: TypeNature::Derived, | ||
location: implementation.name_location.clone(), | ||
}; | ||
|
||
self.index.register_pou(PouIndexEntry::create_action_entry( | ||
implementation.name.as_str(), | ||
implementation.type_name.as_str(), | ||
implementation.linkage, | ||
implementation.name_location.clone(), | ||
)); | ||
self.index.register_pou_type(datatype); | ||
} | ||
} | ||
} |
Oops, something went wrong.