fallow_types/similar_code.rs
1//! Shared transient extraction types for similar-code candidate generation.
2//!
3//! These types carry source fragments only between extraction and a provider
4//! orchestration layer. They are intentionally not part of `ModuleInfo` or the
5//! persisted parse cache.
6
7/// Extraction semantics understood by the first similar-code source contract.
8///
9/// Increment this value whenever supported function forms, naming, spans, or
10/// source payload selection changes.
11pub const SIMILAR_CODE_EXTRACTION_SEMANTICS_VERSION: u32 = 1;
12
13/// Full SHA-256 digest of one exact extracted function source fragment.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct SimilarCodeSourceDigest([u8; 32]);
16
17impl SimilarCodeSourceDigest {
18 /// Construct a digest from the complete SHA-256 output bytes.
19 #[must_use]
20 pub const fn new(bytes: [u8; 32]) -> Self {
21 Self(bytes)
22 }
23
24 /// Return the complete SHA-256 output bytes.
25 #[must_use]
26 pub const fn as_bytes(&self) -> &[u8; 32] {
27 &self.0
28 }
29}
30
31/// Supported source form for an extracted similar-code function.
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33#[non_exhaustive]
34pub enum SimilarCodeFunctionKind {
35 /// A top-level named `function` declaration.
36 FunctionDeclaration,
37 /// A top-level identifier binding or default export using a function expression.
38 FunctionExpression,
39 /// A top-level identifier binding or default export using an arrow function.
40 ArrowFunction,
41 /// A statically named ordinary method on a top-level named class.
42 ClassMethod,
43 /// A statically named ordinary method on a top-level bound object literal.
44 ObjectMethod,
45}
46
47/// Conservative syntactic hint about possible function side effects.
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49#[non_exhaustive]
50pub enum SimilarCodeSideEffectHint {
51 /// No explicit effectful construct was present in a reliably parsed body.
52 PureLooking,
53 /// The body contains a call, write, throw, await, member access, or similar construct.
54 MayHaveSideEffects,
55 /// Parser recovery made the syntactic classification unreliable.
56 Unknown,
57}
58
59/// Complete location of one function in UTF-8 source text.
60#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
61pub struct SimilarCodeFunctionLocation {
62 /// UTF-8 project-root-relative path with forward-slash separators.
63 pub file: String,
64 /// Inclusive zero-based byte offset in the post-BOM source view.
65 pub start_byte: u32,
66 /// Exclusive zero-based byte offset in the post-BOM source view.
67 pub end_byte: u32,
68 /// One-based start line.
69 pub start_line: u32,
70 /// Zero-based start column counted in UTF-8 scalar values, not bytes.
71 pub start_column_utf8: u32,
72 /// One-based end line.
73 pub end_line: u32,
74 /// Zero-based end column counted in UTF-8 scalar values, not bytes.
75 pub end_column_utf8: u32,
76}
77
78/// One named top-level JS or TS function prepared for provider inference.
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct ExtractedSimilarCodeFunction {
81 /// Stable source-level name selected by the extraction semantics.
82 pub name: String,
83 /// Supported syntactic function form.
84 pub kind: SimilarCodeFunctionKind,
85 /// Full UTF-8 source location.
86 pub location: SimilarCodeFunctionLocation,
87 /// Full SHA-256 digest of `source`.
88 pub source_sha256: SimilarCodeSourceDigest,
89 /// Exact bounded source fragment, transient and never parse-cache data.
90 pub source: String,
91 /// Number of declared parameters, excluding TypeScript's `this` parameter.
92 pub param_count: u32,
93 /// Whether the function has an `async` modifier.
94 pub is_async: bool,
95 /// Whether the function is a generator.
96 pub is_generator: bool,
97 /// Whether the direct function body contains an `await` expression.
98 pub has_await: bool,
99 /// Whether the direct function body contains a `throw` statement.
100 pub has_throw: bool,
101 /// Conservative closed syntactic side-effect classification.
102 pub side_effect_hint: SimilarCodeSideEffectHint,
103}
104
105/// Hard source-payload limits for one on-demand extraction call.
106#[derive(Debug, Clone, Copy, PartialEq, Eq)]
107pub struct SimilarCodeExtractionLimits {
108 /// Maximum retained functions.
109 pub max_functions: usize,
110 /// Maximum bytes retained for any one function source fragment.
111 pub max_source_bytes_per_function: usize,
112 /// Maximum combined source bytes retained by the result.
113 pub max_total_source_bytes: usize,
114}
115
116impl Default for SimilarCodeExtractionLimits {
117 fn default() -> Self {
118 const MAX_FUNCTIONS: usize = 10_000;
119 const MAX_SOURCE_BYTES_PER_FUNCTION: usize = 64 * 1024;
120 const MAX_TOTAL_SOURCE_BYTES: usize = 16 * 1024 * 1024;
121
122 Self {
123 max_functions: MAX_FUNCTIONS,
124 max_source_bytes_per_function: MAX_SOURCE_BYTES_PER_FUNCTION,
125 max_total_source_bytes: MAX_TOTAL_SOURCE_BYTES,
126 }
127 }
128}
129
130/// Stable reason source work was omitted or recovered during extraction.
131#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
132#[non_exhaustive]
133pub enum SimilarCodeExtractionSkipReason {
134 /// The input path is not valid UTF-8.
135 NonUtf8Path,
136 /// The input is not a supported standalone JS or TS source file.
137 UnsupportedFileType,
138 /// TypeScript declaration files contain no runtime function bodies.
139 DeclarationFile,
140 /// A closed path or header rule classified the source as generated.
141 GeneratedSource,
142 /// Oxc recovered from one or more syntax diagnostics.
143 SyntaxDiagnostic,
144 /// A declaration or overload had no function body.
145 DeclarationWithoutBody,
146 /// Nested functions and callbacks are outside the first extraction semantics.
147 NestedFunction,
148 /// A method, computed binding, or other unsupported function form was omitted.
149 UnsupportedFunctionForm,
150 /// The AST span could not be sliced safely from the source.
151 InvalidSourceSpan,
152 /// A function source fragment exceeded its per-function byte limit.
153 SourceBytesPerFunctionLimit,
154 /// The retained function limit was reached.
155 FunctionLimit,
156 /// The combined source-payload byte limit was reached.
157 TotalSourceBytesLimit,
158}
159
160/// Counted omission or recovery evidence for one stable extraction reason.
161#[derive(Debug, Clone, Copy, PartialEq, Eq)]
162pub struct SimilarCodeExtractionSkip {
163 /// Stable reason.
164 pub reason: SimilarCodeExtractionSkipReason,
165 /// Number of functions or diagnostics represented by the reason.
166 pub count: usize,
167}
168
169/// Transient result of one bounded source-to-functions extraction call.
170#[derive(Debug, Clone, PartialEq, Eq)]
171pub struct SimilarCodeExtraction {
172 /// Semantics version used to select and name functions.
173 pub extraction_semantics_version: u32,
174 /// Retained functions in deterministic source order.
175 pub functions: Vec<ExtractedSimilarCodeFunction>,
176 /// Combined byte size of retained `source` payloads.
177 pub source_bytes: usize,
178 /// Counted skip and recovery evidence in stable reason order.
179 pub skipped: Vec<SimilarCodeExtractionSkip>,
180}