Skip to content

Commit

Permalink
Rename classes and functions
Browse files Browse the repository at this point in the history
  • Loading branch information
LiamPattinson committed Jan 11, 2024
1 parent 0cec80d commit 9909042
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 35 deletions.
20 changes: 10 additions & 10 deletions src/best_practices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,33 @@ use crate::rules::{register_rule, Category, Code, Method, Rule, Status};
use std::collections::HashMap;

pub mod floating_point;
pub mod use_implicit_none;
pub mod use_modules;
pub mod implicit_none;
pub mod modules_and_programs;

pub fn add_best_practices_rules(registry: &mut HashMap<String, Rule>) {
for rule in [
Rule::new(
Code::new(Category::BestPractices, 1),
Method::Tree(use_modules::use_modules),
use_modules::USE_MODULES,
Method::Tree(modules_and_programs::use_modules_and_programs),
modules_and_programs::USE_MODULES_AND_PROGRAMS,
Status::Standard,
),
Rule::new(
Code::new(Category::BestPractices, 10),
Method::Tree(use_implicit_none::use_implicit_none),
use_implicit_none::USE_IMPLICIT_NONE,
Method::Tree(implicit_none::use_implicit_none_modules_and_programs),
implicit_none::USE_IMPLICIT_NONE_MODULES_AND_PROGRAMS,
Status::Standard,
),
Rule::new(
Code::new(Category::BestPractices, 11),
Method::Tree(use_implicit_none::use_interface_implicit_none),
use_implicit_none::USE_INTERFACE_IMPLICIT_NONE,
Method::Tree(implicit_none::use_implicit_none_interfaces),
implicit_none::USE_IMPLICIT_NONE_INTERFACES,
Status::Standard,
),
Rule::new(
Code::new(Category::BestPractices, 12),
Method::Tree(use_implicit_none::avoid_superfluous_implicit_none),
use_implicit_none::AVOID_SUPERFLUOUS_IMPLICIT_NONE,
Method::Tree(implicit_none::avoid_superfluous_implicit_none),
implicit_none::AVOID_SUPERFLUOUS_IMPLICIT_NONE,
Status::Optional,
),
Rule::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ use crate::rules::{Code, Violation};
/// Defines rules that raise errors if implicit typing is in use.
use tree_sitter::{Node, Query};

pub const USE_IMPLICIT_NONE: &str = "\
pub const USE_IMPLICIT_NONE_MODULES_AND_PROGRAMS: &str = "\
'implicit none' should be used in all modules and programs, as implicit typing
reduces the readability of code and increases the chances of typing errors.";

pub fn use_implicit_none(code: Code, root: &Node, src: &str) -> Vec<Violation> {
pub fn use_implicit_none_modules_and_programs(
code: Code,
root: &Node,
src: &str,
) -> Vec<Violation> {
let mut violations = Vec::new();
for query_type in ["module", "submodule", "program"] {
// Search for a module, submodule or program, and optionally an 'implicit none'.
Expand Down Expand Up @@ -41,11 +45,11 @@ pub fn use_implicit_none(code: Code, root: &Node, src: &str) -> Vec<Violation> {
violations
}

pub const USE_INTERFACE_IMPLICIT_NONE: &str = "\
pub const USE_IMPLICIT_NONE_INTERFACES: &str = "\
Interface functions and subroutines require 'implicit none', even if they are inside
a module that uses 'implicit none'.";

pub fn use_interface_implicit_none(code: Code, root: &Node, src: &str) -> Vec<Violation> {
pub fn use_implicit_none_interfaces(code: Code, root: &Node, src: &str) -> Vec<Violation> {
let mut violations = Vec::new();
for query_type in ["function", "subroutine"] {
let query_txt = format!(
Expand Down Expand Up @@ -120,7 +124,7 @@ mod tests {
use crate::test_utils::test_utils::{test_tree_method, TEST_CODE};

#[test]
fn test_missing_implicit_none() {
fn test_module_and_program_missing_implicit_none() {
let source = "
module my_module
parameter(N = 1)
Expand All @@ -141,11 +145,15 @@ mod tests {
)
})
.collect();
test_tree_method(use_implicit_none, source, Some(expected_violations));
test_tree_method(
use_implicit_none_modules_and_programs,
source,
Some(expected_violations),
);
}

#[test]
fn test_uses_implicit_none() {
fn test_module_and_program_uses_implicit_none() {
let source = "
module my_module
implicit none
Expand All @@ -162,7 +170,7 @@ mod tests {
write(*,*) x
end program
";
test_tree_method(use_implicit_none, source, None);
test_tree_method(use_implicit_none_modules_and_programs, source, None);
}

#[test]
Expand Down Expand Up @@ -199,7 +207,7 @@ mod tests {
})
.collect();
test_tree_method(
use_interface_implicit_none,
use_implicit_none_interfaces,
source,
Some(expected_violations),
);
Expand Down Expand Up @@ -229,7 +237,7 @@ mod tests {
write(*,*) 42
end program
";
test_tree_method(use_interface_implicit_none, source, None);
test_tree_method(use_implicit_none_interfaces, source, None);
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use crate::rules::{Code, Violation};
/// submodules, or interfaces. It is also acceptable to define nested functions or subroutines.
use tree_sitter::{Node, Query};

pub const USE_MODULES: &str = "\
Functions and subroutines should be contained within (sub)modules, program blocks,
or interfaces. Fortran compilers are unable to perform type checks and conversions
on functions defined outside of these scopes, and this is a common source of bugs.";
pub const USE_MODULES_AND_PROGRAMS: &str = "\
Functions and subroutines should be contained within (sub)modules or programs.
Fortran compilers are unable to perform type checks and conversions on functions
defined outside of these scopes, and this is a common source of bugs.";

pub fn use_modules(code: Code, root: &Node, src: &str) -> Vec<Violation> {
pub fn use_modules_and_programs(code: Code, root: &Node, src: &str) -> Vec<Violation> {
let mut violations = Vec::new();
let query_txt = "(translation_unit [(function) @func (subroutine) @sub])";
let query = Query::new(fortran_language(), query_txt).unwrap();
Expand All @@ -24,7 +24,7 @@ pub fn use_modules(code: Code, root: &Node, src: &str) -> Vec<Violation> {
&node,
code,
format!(
"{} not contained within (sub)module, program, or interface",
"{} not contained within (sub)module or program",
node.kind(),
)
.as_str(),
Expand Down Expand Up @@ -59,15 +59,11 @@ mod tests {
Violation::new(
*line,
TEST_CODE,
format!(
"{} not contained within (sub)module, program, or interface",
kind
)
.as_str(),
format!("{} not contained within (sub)module or program", kind).as_str(),
)
})
.collect();
test_tree_method(use_modules, source, Some(expected_violations));
test_tree_method(use_modules_and_programs, source, Some(expected_violations));
}

#[test]
Expand All @@ -87,6 +83,6 @@ mod tests {
end subroutine
end module
";
test_tree_method(use_modules, source, None);
test_tree_method(use_modules_and_programs, source, None);
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ fn main() {
let mut parser = fortran_parser();
let tree = parser.parse(&content, None).unwrap();
let root = tree.root_node();
println!("{}", root.to_sexp());

// Collect available rules
// TODO Add feature to deselect rules, or add non-default ones.
Expand Down
3 changes: 1 addition & 2 deletions test.f90
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ integer function quad(x)
end function

! Should trigger for use of 'double precision'
function double_prec(x)
double precision function double_prec(x)
double precision, intent(in) :: x
double precision :: double_prec
double_prec = 2 * x
end function
end module
Expand Down

0 comments on commit 9909042

Please sign in to comment.