Skip to main content

semantic/diff/
diff_types.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Shared semantic diff result and budget types.
3
4use std::path::PathBuf;
5
6use objects::object::{FileChangeSet, SemanticChange};
7
8use crate::analysis::AggregationResult;
9
10/// Resource limits used by semantic analysis.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct SemanticBudget {
13    /// Maximum number of changed files to analyze semantically.
14    pub max_changed_files: usize,
15    /// Maximum total bytes to load across changed files.
16    pub max_total_bytes: usize,
17    /// Maximum number of files that may be parsed structurally.
18    pub max_parsed_files: usize,
19    /// Maximum file size eligible for parsing.
20    pub max_file_bytes: usize,
21}
22
23impl SemanticBudget {
24    /// Returns a budget with no practical limits.
25    pub fn unlimited() -> Self {
26        Self {
27            max_changed_files: usize::MAX,
28            max_total_bytes: usize::MAX,
29            max_parsed_files: usize::MAX,
30            max_file_bytes: usize::MAX,
31        }
32    }
33}
34
35impl Default for SemanticBudget {
36    fn default() -> Self {
37        Self {
38            max_changed_files: 2_048,
39            max_total_bytes: 16 * 1024 * 1024,
40            max_parsed_files: 512,
41            max_file_bytes: 1024 * 1024,
42        }
43    }
44}
45
46/// Conservative reason that semantic analysis skipped or degraded work.
47#[derive(Clone, Debug, PartialEq, Eq)]
48pub enum SemanticFallbackReason {
49    /// The changed-file set exceeded the configured limit.
50    ChangedFileBudgetExceeded { limit: usize, actual: usize },
51    /// Loaded content exceeded the configured byte budget.
52    TotalByteBudgetExceeded { limit: usize, actual: usize },
53    /// A file was too large for structural parsing.
54    FileTooLarge {
55        path: PathBuf,
56        limit: usize,
57        actual: usize,
58    },
59    /// Structural parsing hit the configured file-count budget.
60    ParseBudgetExceeded { limit: usize, attempted: usize },
61    /// The file language is unsupported for structural parsing.
62    UnsupportedLanguage { path: PathBuf },
63    /// Tree-sitter failed to produce a clean parse.
64    ParseFailed { path: PathBuf },
65}
66
67/// Result classification for the cheap semantic check path.
68#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69pub enum SemanticCheckStatus {
70    /// The requested change-set is semantically empty.
71    NoChanges,
72    /// The requested change-set definitely contains changes.
73    HasChanges,
74    /// The fast path could not complete within the configured budget.
75    Fallback,
76}
77
78/// Result of the cheap semantic no-op check.
79#[derive(Clone, Debug)]
80pub struct SemanticCheckOnlyResult {
81    /// Final status of the fast path.
82    pub status: SemanticCheckStatus,
83    /// Raw file changes considered by the engine.
84    pub file_changes: FileChangeSet,
85    /// Explicit reasons why the fast path degraded.
86    pub fallback_reasons: Vec<SemanticFallbackReason>,
87}
88
89/// Aggregated semantic summary without the full detailed change list.
90#[derive(Clone, Debug, Default)]
91pub struct SemanticSummaryResult {
92    /// Files that were classified as renames.
93    pub file_renames: Vec<(PathBuf, PathBuf)>,
94    /// Raw file-level changes.
95    pub file_changes: FileChangeSet,
96    /// Aggregated semantic groups.
97    pub aggregated: Option<AggregationResult>,
98    /// Explicit reasons why parts of semantic analysis degraded.
99    pub fallback_reasons: Vec<SemanticFallbackReason>,
100}
101
102/// Result of full semantic diff analysis.
103#[derive(Clone, Debug, Default)]
104pub struct SemanticDiffResult {
105    /// High-level semantic changes detected.
106    pub changes: Vec<SemanticChange>,
107    /// Files that were renamed (old -> new).
108    pub file_renames: Vec<(PathBuf, PathBuf)>,
109    /// Raw file-level changes.
110    pub file_changes: FileChangeSet,
111    /// Aggregated changes (groups formatting passes, cross-file renames, etc.)
112    pub aggregated: Option<AggregationResult>,
113    /// Explicit reasons why parts of semantic analysis degraded.
114    pub fallback_reasons: Vec<SemanticFallbackReason>,
115}