1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Source span representation for position tracking.
//!
//! This module provides [`SpanIR`], a stable, serializable span type that
//! represents byte ranges in source code. Unlike SWC's `Span` type, `SpanIR`
//! uses simple byte offsets and is designed for ABI stability.
//!
//! ## Byte Offsets
//!
//! Spans use byte offsets (not character indices or line/column pairs) for:
//! - Precision with multi-byte UTF-8 characters
//! - Efficient substring operations
//! - Simple arithmetic for position calculations
//!
//! ## Example
//!
//! ```rust,no_run
//! use macroforge_ts_syn::SpanIR;
//!
//! // Create a span for bytes 10-25
//! let span = SpanIR::new(10, 25);
//! assert_eq!(span.len(), 15);
//! assert!(!span.is_empty());
//!
//! // Extract the spanned text from source
//! let source = "let x = 42;";
//! let text = &source[span.start as usize..span.end as usize];
//! ```
use ;
/// A stable source span using byte offsets.
///
/// Represents a contiguous range in source code from `start` (inclusive)
/// to `end` (exclusive). The host system maps between SWC's internal
/// spans and `SpanIR` for macro communication.
///
/// # Fields
///
/// - `start` - The starting byte offset (inclusive)
/// - `end` - The ending byte offset (exclusive)
///
/// # Invariants
///
/// - `start <= end` for a valid, non-empty span
/// - `start == end` represents an empty span (e.g., for insertion points)
///
/// # Example
///
/// ```rust,no_run
/// use macroforge_ts_syn::SpanIR;
///
/// // Span covering "hello" in "say hello world"
/// // ^^^^^
/// // byte indices: 4 5678 9
/// let span = SpanIR::new(4, 9);
/// assert_eq!(span.len(), 5);
///
/// // Extract the text
/// let source = "say hello world";
/// let text = &source[span.start as usize..span.end as usize];
/// assert_eq!(text, "hello");
/// ```