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}