Skip to main content

ass_core/analysis/linting/
runner.rs

1//! Entry points for running linting over a script.
2//!
3//! Provides [`lint_script`] and [`lint_script_with_analysis`], which execute
4//! all enabled built-in rules and collect issues subject to the supplied
5//! [`LintConfig`].
6
7use super::{rules::BuiltinRules, LintConfig, LintIssue};
8use crate::{
9    analysis::{AnalysisConfig, ScriptAnalysis},
10    parser::Script,
11    Result,
12};
13use alloc::vec::Vec;
14
15/// Lint a script with the given configuration.
16/// Lint script with existing analysis
17///
18/// Runs all enabled rules against the provided analysis and returns found issues,
19/// respecting the configuration limits and filters.
20/// Lint script using existing analysis
21///
22/// # Errors
23///
24/// Returns an error if linting rule execution fails.
25pub fn lint_script_with_analysis(
26    analysis: &ScriptAnalysis,
27    config: &LintConfig,
28) -> Result<Vec<LintIssue>> {
29    let mut issues = Vec::new();
30    let rules = BuiltinRules::all_rules();
31
32    for rule in rules {
33        if !config.is_rule_enabled(rule.id()) {
34            continue;
35        }
36
37        let mut rule_issues = rule.check_script(analysis);
38        rule_issues.retain(|issue| config.should_report_severity(issue.severity()));
39
40        issues.extend(rule_issues);
41
42        if config.max_issues > 0 && issues.len() >= config.max_issues {
43            issues.truncate(config.max_issues);
44            break;
45        }
46    }
47
48    Ok(issues)
49}
50
51/// Lint script with configuration
52///
53/// Creates a minimal analysis without linting, then runs all enabled rules
54/// against the script and returns found issues, respecting the configuration
55/// limits and filters.
56///
57/// # Errors
58///
59/// Returns an error if script analysis or linting rule execution fails.
60pub fn lint_script(script: &Script, config: &LintConfig) -> Result<Vec<LintIssue>> {
61    // Create analysis without linting to avoid circular dependency
62    let mut analysis = ScriptAnalysis {
63        script,
64        lint_issues: Vec::new(),
65        resolved_styles: Vec::new(),
66        dialogue_info: Vec::new(),
67        config: AnalysisConfig::default(),
68        #[cfg(feature = "plugins")]
69        registry: None,
70    };
71
72    // Run only style resolution and event analysis (no linting)
73    analysis.resolve_all_styles();
74    analysis.analyze_events();
75
76    // Now run linting with the prepared analysis
77    lint_script_with_analysis(&analysis, config)
78}