Files
@ 6ec2e0261a03
Branch filter:
Location: CSY/reowolf/src/protocol/parser/utils.rs - annotation
6ec2e0261a03
3.9 KiB
application/rls-services+xml
debugging type inference
cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 1811fe09856a cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 cd546710a6c9 | use crate::protocol::ast::*;
use crate::protocol::inputsource::*;
use super::symbol_table::*;
use super::type_table::*;
/// Utility result type.
pub(crate) enum FindTypeResult<'t, 'i> {
// Found the type exactly
Found(&'t DefinedType),
// Could not match symbol
SymbolNotFound{ident_pos: InputPosition},
// Matched part of the namespaced identifier, but not completely
SymbolPartial{ident_pos: InputPosition, symbol_pos: InputPosition, ident_iter: NamespacedIdentifierIter<'i>},
// Symbol matched, but points to a namespace/module instead of a type
SymbolNamespace{ident_pos: InputPosition, symbol_pos: InputPosition},
}
// TODO: @cleanup Find other uses of this pattern
impl<'t, 'i> FindTypeResult<'t, 'i> {
/// Utility function to transform the `FindTypeResult` into a `Result` where
/// `Ok` contains the resolved type, and `Err` contains a `ParseError` which
/// can be readily returned. This is the most common use.
pub(crate) fn as_parse_error(self, module_source: &InputSource) -> Result<&'t DefinedType, ParseError2> {
match self {
FindTypeResult::Found(defined_type) => Ok(defined_type),
FindTypeResult::SymbolNotFound{ident_pos} => {
Err(ParseError2::new_error(
module_source, ident_pos,
"Could not resolve this identifier to a symbol"
))
},
FindTypeResult::SymbolPartial{ident_pos, symbol_pos, ident_iter} => {
Err(ParseError2::new_error(
module_source, ident_pos,
"Could not fully resolve this identifier to a symbol"
).with_postfixed_info(
module_source, symbol_pos,
&format!(
"The partial identifier '{}' was matched to this symbol",
String::from_utf8_lossy(ident_iter.returned_section()),
)
))
},
FindTypeResult::SymbolNamespace{ident_pos, symbol_pos} => {
Err(ParseError2::new_error(
module_source, ident_pos,
"This identifier was resolved to a namespace instead of a type"
).with_postfixed_info(
module_source, symbol_pos,
"This is the referenced namespace"
))
}
}
}
}
/// Attempt to find the type pointer to by a (root, identifier) combination. The
/// type must match exactly (no parts in the namespace iterator remaining) and
/// must be a type, not a namespace.
pub(crate) fn find_type_definition<'t, 'i>(
symbols: &SymbolTable, types: &'t TypeTable,
root_id: RootId, identifier: &'i NamespacedIdentifier
) -> FindTypeResult<'t, 'i> {
// Lookup symbol
let symbol = symbols.resolve_namespaced_symbol(root_id, identifier);
if symbol.is_none() {
return FindTypeResult::SymbolNotFound{ident_pos: identifier.position};
}
// Make sure we resolved it exactly
let (symbol, ident_iter) = symbol.unwrap();
if ident_iter.num_remaining() != 0 {
return FindTypeResult::SymbolPartial{
ident_pos: identifier.position,
symbol_pos: symbol.position,
ident_iter
};
}
match symbol.symbol {
Symbol::Namespace(_) => {
FindTypeResult::SymbolNamespace{
ident_pos: identifier.position,
symbol_pos: symbol.position
}
},
Symbol::Definition((_, definition_id)) => {
// If this function is called correctly, then we should always be
// able to match the definition's ID to an entry in the type table.
let definition = types.get_base_definition(&definition_id);
debug_assert!(definition.is_some());
FindTypeResult::Found(definition.unwrap())
}
}
}
|