Skip to content

Commit

Permalink
Merge pull request #82 from PlasmaFAIR/relational-symbols
Browse files Browse the repository at this point in the history
Add rule for deprecated relational operators
  • Loading branch information
LiamPattinson authored Oct 10, 2024
2 parents be2d6d8 + 5f74d35 commit dbda3c9
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ register_rules! {
(Category::Style, "S001", TEXT, style::line_length::LineTooLong, LineTooLong),
(Category::Style, "S021", AST, style::exit_labels::MissingExitOrCycleLabel, MissingExitOrCycleLabel),
(Category::Style, "S041", AST, style::old_style_array_literal::OldStyleArrayLiteral, OldStyleArrayLiteral),
(Category::Style, "S051", AST, style::relational_operators::DeprecatedRelationalOperator, DeprecatedRelationalOperator),
(Category::Style, "S101", TEXT, style::whitespace::TrailingWhitespace, TrailingWhitespace),
(Category::Typing, "T001", AST, typing::implicit_typing::ImplicitTyping, ImplicitTyping),
(Category::Typing, "T002", AST, typing::implicit_typing::InterfaceImplicitTyping, InterfaceImplicitTyping),
Expand Down
1 change: 1 addition & 0 deletions src/rules/style/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod exit_labels;
pub mod line_length;
pub mod old_style_array_literal;
pub mod relational_operators;
pub mod whitespace;
88 changes: 88 additions & 0 deletions src/rules/style/relational_operators.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::ast::FortitudeNode;
use crate::settings::Settings;
use crate::{ASTRule, Rule, Violation};
use tree_sitter::Node;

fn map_relational_symbols(name: &str) -> Option<&'static str> {
match name {
".gt." => Some(">"),
".ge." => Some(">="),
".lt." => Some("<"),
".le." => Some("<="),
".eq." => Some("=="),
".ne." => Some("/="),
_ => None,
}
}

pub struct DeprecatedRelationalOperator {}

impl Rule for DeprecatedRelationalOperator {
fn new(_settings: &Settings) -> Self {
Self {}
}

fn explain(&self) -> &'static str {
"
Fortran 90 introduced the traditional symbols for relational operators: `>`,
`>=`, `<`, and so on. Prefer these over the deprecated forms `.gt.`, `.le.`, and
so on.
"
}
}

impl ASTRule for DeprecatedRelationalOperator {
fn check(&self, node: &Node, src: &str) -> Option<Vec<Violation>> {
let relation = node.child(1)?;
let symbol = relation.to_text(src)?.to_lowercase();
let new_symbol = map_relational_symbols(symbol.as_str())?;
let msg =
format!("deprecated relational operator '{symbol}', prefer '{new_symbol}' instead");
some_vec![Violation::from_node(msg, &relation)]
}

fn entrypoints(&self) -> Vec<&'static str> {
vec!["relational_expression"]
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::settings::default_settings;
use crate::violation;
use pretty_assertions::assert_eq;
use textwrap::dedent;

#[test]
fn test_relational_symbol() -> anyhow::Result<()> {
let source = dedent(
"
program test
if (0 .gt. 1) error stop
if (1 .le. 0) error stop
if (a.eq.b.and.a.ne.b) error stop
if (1 == 2) error stop ! OK
if (2 /= 2) error stop ! OK
end program test
",
);
let expected: Vec<Violation> = [
(3, 9, ".gt.", ">"),
(4, 9, ".le.", "<="),
(5, 8, ".eq.", "=="),
(5, 19, ".ne.", "/="),
]
.iter()
.map(|(line, col, symbol, new_symbol)| {
let msg =
format!("deprecated relational operator '{symbol}', prefer '{new_symbol}' instead");
violation!(&msg, *line, *col)
})
.collect();
let rule = DeprecatedRelationalOperator::new(&default_settings());
let actual = rule.apply(source.as_str())?;
assert_eq!(actual, expected);
Ok(())
}
}

0 comments on commit dbda3c9

Please sign in to comment.