Skip to content

Commit

Permalink
Resolve selected names of types (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
Schottkyc137 committed Aug 6, 2024
1 parent 0144e0e commit d44c141
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 10 deletions.
37 changes: 27 additions & 10 deletions vhdl_lang/src/analysis/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1506,23 +1506,39 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
return Err(EvalError::Unknown);
}
}
ResolvedName::Type(typ) => {
if let Suffix::CallOrIndexed(ref mut assocs) = suffix {
ResolvedName::Type(typ) => match suffix {
Suffix::Selected(selected) => {
let typed_selection = match typ.selected(self.ctx, prefix.span, selected) {
Ok(typed_selection) => typed_selection,
Err(diagnostic) => {
bail!(diagnostics, diagnostic);
}
};
return Ok(match typed_selection {
TypedSelection::RecordElement(element) => {
ResolvedName::Type(element.type_mark())
}
TypedSelection::ProtectedMethod(method) => ResolvedName::Overloaded(
selected.clone().map_into(|desi| desi.item),
method,
),
});
}
Suffix::CallOrIndexed(ref mut assocs) => {
if let Some((expr_pos, expr)) = as_type_conversion(assocs) {
self.check_type_conversion(scope, typ, expr_pos, expr, diagnostics)?;
return Ok(ResolvedName::Expression(DisambiguatedType::Unambiguous(
typ,
)));
}
}

diagnostics.push(Diagnostic::cannot_be_prefix(
&span.pos(self.ctx),
resolved,
suffix,
));
return Err(EvalError::Unknown);
}
_ => {
bail!(
diagnostics,
Diagnostic::cannot_be_prefix(&span.pos(self.ctx), resolved, suffix)
);
}
},
ResolvedName::Final(_) => {
diagnostics.push(Diagnostic::cannot_be_prefix(
&span.pos(self.ctx),
Expand All @@ -1535,6 +1551,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> {

Ok(resolved)
}

// Helper function:
// Resolve a name that must be some kind of object selection, index or slice
// Such names occur as assignment targets and aliases
Expand Down
22 changes: 22 additions & 0 deletions vhdl_lang/src/analysis/tests/resolves_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2163,3 +2163,25 @@ end package;",
let (_root, diagnostics) = builder.get_analyzed_root();
check_no_diagnostics(&diagnostics);
}

#[test]
pub fn resolve_selected_names_of_types() {
let mut builder = LibraryBuilder::new();
builder.code(
"libname",
"\
package foo is
type test_t is record
asdf: bit_vector(10 downto 0);
end record;
signal a: integer := test_t.asdf'high;
signal b: bit_vector(test_t.asdf'high downto test_t.asdf'low);
signal c: bit_vector(test_t.asdf'range);
signal d: integer := test_t.asdf'high;
signal e: bit_vector(test_t.asdf'range);
end package;
",
);
check_no_diagnostics(&builder.analyze())
}
2 changes: 2 additions & 0 deletions vhdl_lang/src/syntax/tokens/tokenizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,14 @@ macro_rules! expect_token {
/// Unlike the try_token_kind this macro gives errors always on the next token
/// Example:
///
/// ```vhdl
/// entity ent is
/// end entity;
/// ~ <- error should not be here
///
/// foo
/// ~~~ <- error should be here
/// ```
#[macro_export]
macro_rules! try_init_token_kind {
($token:expr, $($($kind:ident)|+ => $result:expr),*) => {
Expand Down
2 changes: 2 additions & 0 deletions vhdl_lang/src/syntax/tokens/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,12 @@ impl<'a> TokenStream<'a> {
/// A position that aligns with the previous token
///
/// Example:
/// ```vhdl
/// signal sig : natural
/// ~ <- want semi colon error here
/// signal
/// ~~~~~~ <- not here
/// ```
pub fn pos_before(&self, token: &Token) -> SrcPos {
if let Some(prev_token) = self.token_before(token) {
let prev_pos = prev_token.pos.end();
Expand Down

0 comments on commit d44c141

Please sign in to comment.