Skip to content

Commit

Permalink
Add attribute arguments check #90
Browse files Browse the repository at this point in the history
  • Loading branch information
dalance committed Jan 20, 2023
1 parent a81b42e commit b9a6c45
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [Unreleased](https://github.com/dalance/veryl/compare/v0.2.1...Unreleased) - ReleaseDate

* [Added] attribute arguments check [#90](https://github.com/dalance/veryl/issues/90)

## [v0.2.1](https://github.com/dalance/veryl/compare/v0.2.0...v0.2.1) - 2023-01-19

* [Added] uknown member check [#84](https://github.com/dalance/veryl/issues/84)
Expand Down
43 changes: 43 additions & 0 deletions crates/analyzer/src/analyzer_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@ pub enum AnalyzerError {
error_location: SourceSpan,
},

#[diagnostic(code(AnalyzerError::MismatchAttributeArgs), help(""))]
#[error("Arguments of \"{name}\" is expected to \"{expected}\"")]
MismatchAttributeArgs {
name: String,
expected: String,
#[source_code]
input: NamedSource,
#[label("Error location")]
error_location: SourceSpan,
},

#[diagnostic(code(AnalyzerError::MissingPort), help("add \"{port}\" port"))]
#[error("module \"{name}\" has \"{port}\", but it is not connected")]
MissingPort {
Expand Down Expand Up @@ -134,6 +145,16 @@ pub enum AnalyzerError {
error_location: SourceSpan,
},

#[diagnostic(code(AnalyzerError::UnknownAttribute), help(""))]
#[error("\"{name}\" is not valid attribute")]
UnknownAttribute {
name: String,
#[source_code]
input: NamedSource,
#[label("Error location")]
error_location: SourceSpan,
},

#[diagnostic(code(AnalyzerError::DuplicatedIdentifier), help(""))]
#[error("{identifier} is duplicated")]
DuplicatedIdentifier {
Expand Down Expand Up @@ -296,6 +317,20 @@ impl AnalyzerError {
}
}

pub fn mismatch_attribute_args(
name: &str,
expected: &str,
source: &str,
token: &VerylToken,
) -> Self {
AnalyzerError::MismatchAttributeArgs {
name: name.to_string(),
expected: expected.to_string(),
input: AnalyzerError::named_source(source, token),
error_location: token.token.into(),
}
}

pub fn missing_port(name: &str, port: &str, source: &str, token: &VerylToken) -> Self {
AnalyzerError::MissingPort {
name: name.to_string(),
Expand Down Expand Up @@ -323,6 +358,14 @@ impl AnalyzerError {
}
}

pub fn unknown_attribute(name: &str, source: &str, token: &VerylToken) -> Self {
AnalyzerError::UnknownAttribute {
name: name.to_string(),
input: AnalyzerError::named_source(source, token),
error_location: token.token.into(),
}
}

pub fn duplicated_identifier(identifier: &str, source: &str, token: &VerylToken) -> Self {
AnalyzerError::DuplicatedIdentifier {
identifier: identifier.to_string(),
Expand Down
6 changes: 6 additions & 0 deletions crates/analyzer/src/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod check_attribute;
pub mod check_enum;
pub mod check_function;
pub mod check_instance;
Expand All @@ -9,6 +10,7 @@ pub mod check_number_overflow;
pub mod check_system_function;
pub mod create_reference;
pub mod create_symbol_table;
use check_attribute::*;
use check_enum::*;
use check_function::*;
use check_instance::*;
Expand All @@ -25,6 +27,7 @@ use crate::analyzer_error::AnalyzerError;
use veryl_parser::veryl_walker::Handler;

pub struct Pass1Handlers<'a> {
check_attribute: CheckAttribute<'a>,
check_invalid_direction: CheckInvalidDirection<'a>,
check_invalid_number_character: CheckInvalidNumberCharacter<'a>,
check_invalid_reset: CheckInvalidReset<'a>,
Expand All @@ -37,6 +40,7 @@ pub struct Pass1Handlers<'a> {
impl<'a> Pass1Handlers<'a> {
pub fn new(text: &'a str) -> Self {
Self {
check_attribute: CheckAttribute::new(text),
check_invalid_direction: CheckInvalidDirection::new(text),
check_invalid_number_character: CheckInvalidNumberCharacter::new(text),
check_invalid_reset: CheckInvalidReset::new(text),
Expand All @@ -49,6 +53,7 @@ impl<'a> Pass1Handlers<'a> {

pub fn get_handlers(&mut self) -> Vec<&mut dyn Handler> {
vec![
&mut self.check_attribute as &mut dyn Handler,
&mut self.check_invalid_direction as &mut dyn Handler,
&mut self.check_invalid_number_character as &mut dyn Handler,
&mut self.check_invalid_reset as &mut dyn Handler,
Expand All @@ -61,6 +66,7 @@ impl<'a> Pass1Handlers<'a> {

pub fn get_errors(&mut self) -> Vec<AnalyzerError> {
let mut ret = Vec::new();
ret.append(&mut self.check_attribute.errors);
ret.append(&mut self.check_invalid_direction.errors);
ret.append(&mut self.check_invalid_number_character.errors);
ret.append(&mut self.check_invalid_reset.errors);
Expand Down
96 changes: 96 additions & 0 deletions crates/analyzer/src/handlers/check_attribute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use crate::analyzer_error::AnalyzerError;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;

pub struct CheckAttribute<'a> {
pub errors: Vec<AnalyzerError>,
text: &'a str,
point: HandlerPoint,
}

impl<'a> CheckAttribute<'a> {
pub fn new(text: &'a str) -> Self {
Self {
errors: Vec::new(),
text,
point: HandlerPoint::Before,
}
}
}

impl<'a> Handler for CheckAttribute<'a> {
fn set_point(&mut self, p: HandlerPoint) {
self.point = p;
}
}

impl<'a> VerylGrammarTrait for CheckAttribute<'a> {
fn attribute(&mut self, arg: &Attribute) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
let identifier = arg.identifier.identifier_token.text();
match identifier.as_str() {
"ifdef" | "ifndef" => {
let valid_arg = if let Some(ref x) = arg.attribute_opt {
let args: Vec<AttributeItem> = x.attribute_list.as_ref().into();
if args.len() != 1 {
false
} else {
matches!(args[0], AttributeItem::Identifier(_))
}
} else {
false
};

if !valid_arg {
self.errors.push(AnalyzerError::mismatch_attribute_args(
&identifier,
"single identifier",
self.text,
&arg.identifier.identifier_token,
));
}
}
"sv" => {
let valid_arg = if let Some(ref x) = arg.attribute_opt {
let args: Vec<AttributeItem> = x.attribute_list.as_ref().into();
if args.len() != 1 {
false
} else {
matches!(args[0], AttributeItem::Strin(_))
}
} else {
false
};

if !valid_arg {
self.errors.push(AnalyzerError::mismatch_attribute_args(
&identifier,
"single string",
self.text,
&arg.identifier.identifier_token,
));
}
}
_ => {
self.errors.push(AnalyzerError::unknown_attribute(
&identifier,
self.text,
&arg.identifier.identifier_token,
));
}
}
}
Ok(())

//self.hash(&arg.hash);
//self.l_bracket(&arg.l_bracket);
//self.identifier(&arg.identifier);
//if let Some(ref x) = arg.attribute_opt {
// self.l_paren(&x.l_paren);
// self.attribute_list(&x.attribute_list);
// self.r_paren(&x.r_paren);
//}
//self.r_bracket(&arg.r_bracket);
}
}

0 comments on commit b9a6c45

Please sign in to comment.