use crate::linter::{Diagnostic, LintResult, Severity, Span};
pub fn check(source: &str) -> LintResult {
let mut result = LintResult::new();
for (line_num, line) in source.lines().enumerate() {
let line_num = line_num + 1;
let trimmed = line.trim();
if trimmed.starts_with('#') || trimmed.is_empty() {
continue;
}
if let Some(rest) = trimmed.strip_prefix("function ") {
let rest = rest.trim_start();
let name_end = rest
.find(|c: char| !c.is_ascii_alphanumeric() && c != '_')
.unwrap_or(rest.len());
if name_end == 0 {
continue;
}
let after_name = &rest[name_end..];
let after_name_trimmed = after_name.trim_start();
if after_name_trimmed.starts_with("()") && after_name.len() != after_name_trimmed.len()
{
let line_offset = line.find("function").unwrap_or(0);
let col = line_offset + 1;
result.add(Diagnostic::new(
"SC1095",
Severity::Warning,
"Use 'function name { .. }' or 'name() { .. }', not 'function name () { .. }'",
Span::new(line_num, col, line_num, col + trimmed.len()),
));
}
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sc1095_function_with_space_parens() {
let result = check("function greet () {");
assert_eq!(result.diagnostics.len(), 1);
assert_eq!(result.diagnostics[0].code, "SC1095");
assert_eq!(result.diagnostics[0].severity, Severity::Warning);
}
#[test]
fn test_sc1095_function_without_parens_ok() {
let result = check("function greet {");
assert_eq!(result.diagnostics.len(), 0);
}
#[test]
fn test_sc1095_plain_function_def_ok() {
let result = check("greet() {");
assert_eq!(result.diagnostics.len(), 0);
}
#[test]
fn test_sc1095_function_nospace_parens_ok() {
let result = check("function greet() {");
assert_eq!(result.diagnostics.len(), 0);
}
#[test]
fn test_sc1095_comment_not_flagged() {
let result = check("# function greet () {");
assert_eq!(result.diagnostics.len(), 0);
}
#[test]
fn test_sc1095_multiple_spaces() {
let result = check("function myFunc () {");
assert_eq!(result.diagnostics.len(), 1);
}
#[test]
fn test_sc1095_with_body() {
let script = "function test_func () {\n echo hello\n}";
let result = check(script);
assert_eq!(result.diagnostics.len(), 1);
}
}