Skip to content

Commit baf6a16

Browse files
committed
Don't create individual ranges in the first place
1 parent 65f2604 commit baf6a16

File tree

1 file changed

+116
-89
lines changed

1 file changed

+116
-89
lines changed

turbopack/crates/turbopack-analyze/src/split_chunk.rs

Lines changed: 116 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use turbo_tasks_fs::{FileContent, FileLine, FileLinesContent, rope::Rope};
88
use turbopack_core::{
99
asset::{Asset, AssetContent},
1010
output::OutputAsset,
11-
source_map::{GenerateSourceMap, OriginalToken, SourceMap, SyntheticToken, Token},
11+
source_map::{GenerateSourceMap, OriginalToken, SourceMap, Token},
1212
};
1313

1414
use crate::compressed_size::compressed_size_bytes;
@@ -111,7 +111,8 @@ pub async fn split_output_asset_into_parts(
111111
let start_line = start_line.min(lines.len() as u32 - 1);
112112
let end_line = end_line.min(lines.len() as u32 - 1);
113113
if start_line == end_line {
114-
return end_column - start_column;
114+
// TODO: Figure out why start is larger than end sometimes
115+
return end_column.saturating_sub(start_column);
115116
}
116117
let mut len = lines[start_line as usize].len() as u32 - start_column + 1;
117118
for line in &lines[start_line as usize + 1..end_line as usize] {
@@ -139,17 +140,6 @@ pub async fn split_output_asset_into_parts(
139140
lines,
140141
});
141142
entry.real_size += size;
142-
143-
// Check if the new range is adjacent to the last range and merge if so
144-
if let Some(last_range) = entry.ranges.last_mut()
145-
&& last_range.line == chunk_part_range.line
146-
&& last_range.end_column == chunk_part_range.start_column
147-
&& chunk_part_range.end_column >= chunk_part_range.start_column
148-
{
149-
last_range.end_column = chunk_part_range.end_column;
150-
return;
151-
}
152-
153143
entry.ranges.push(chunk_part_range);
154144
}
155145

@@ -171,98 +161,144 @@ pub async fn split_output_asset_into_parts(
171161
entry.unaccounted_size += unaccounted;
172162
}
173163

164+
fn end_current_mapping(
165+
source: RcStr,
166+
current_line: u32,
167+
start_column: u32,
168+
next_line: u32,
169+
next_column: u32,
170+
lines: &[FileLine],
171+
chunk_parts: &mut FxIndexMap<RcStr, ChunkPart>,
172+
lines_vc: ResolvedVc<FileLinesContent>,
173+
) -> State {
174+
let mapping_end_column = end_of_mapping_column(current_line, next_line, next_column, lines);
175+
let len = mapping_end_column.saturating_sub(start_column);
176+
add_chunk_part_range(
177+
source.clone(),
178+
ChunkPartRange {
179+
line: current_line,
180+
start_column,
181+
end_column: mapping_end_column,
182+
},
183+
len,
184+
chunk_parts,
185+
lines_vc,
186+
);
187+
State::AfterMapping {
188+
source,
189+
generated_line: current_line,
190+
current_generated_column: mapping_end_column,
191+
}
192+
}
193+
194+
fn should_extend_mapping(
195+
state: &State,
196+
new_source: &RcStr,
197+
new_line: u32,
198+
new_column: u32,
199+
) -> bool {
200+
if let State::InMapping {
201+
source,
202+
generated_line,
203+
end_column,
204+
..
205+
} = state
206+
{
207+
// Extend if same source and line, and columns are adjacent or overlapping
208+
// end_column <= new_column handles both adjacent (equal) and overlapping cases
209+
source == new_source && *generated_line == new_line && *end_column <= new_column
210+
} else {
211+
false
212+
}
213+
}
214+
174215
enum State {
175216
StartOfFile,
176217
InMapping {
177218
source: RcStr,
178-
current_generated_line: u32,
179-
current_generated_column: u32,
219+
generated_line: u32,
220+
start_column: u32,
221+
end_column: u32,
180222
},
181223
AfterMapping {
182224
source: RcStr,
183-
current_generated_line: u32,
225+
generated_line: u32,
184226
current_generated_column: u32,
185227
},
186228
}
187229

188230
let mut state: State = State::StartOfFile;
189231

190232
for token in source_map.tokens() {
191-
// First end the previous mapping if we were in one
192-
let end_info = if let State::InMapping {
193-
ref source,
194-
current_generated_line,
195-
current_generated_column,
196-
} = state
197-
{
198-
let (Token::Original(OriginalToken {
199-
generated_line,
200-
generated_column,
201-
..
202-
})
203-
| Token::Synthetic(SyntheticToken {
204-
generated_line,
205-
generated_column,
206-
..
207-
})) = token;
208-
let mapping_end_column = end_of_mapping_column(
209-
current_generated_line,
210-
generated_line,
211-
generated_column,
212-
lines,
213-
);
214-
// TODO: Handle this better
215-
let len = mapping_end_column.saturating_sub(current_generated_column);
216-
Some((
217-
source.clone(),
218-
ChunkPartRange {
219-
line: current_generated_line,
220-
start_column: current_generated_column,
221-
end_column: mapping_end_column,
222-
},
223-
len,
224-
current_generated_line,
225-
mapping_end_column,
226-
))
227-
} else {
228-
None
229-
};
230-
231-
if let Some((source, range, len, line, col)) = end_info {
232-
add_chunk_part_range(source.clone(), range, len, &mut chunk_parts, lines_vc);
233-
state = State::AfterMapping {
234-
source,
235-
current_generated_line: line,
236-
current_generated_column: col,
237-
};
238-
}
239-
240233
if let Token::Original(OriginalToken {
241234
original_file,
242235
generated_line,
243236
generated_column,
244237
..
245238
}) = token
246239
{
240+
// Check if we can extend the current mapping
241+
if should_extend_mapping(&state, &original_file, generated_line, generated_column) {
242+
// Same source and line with adjacent columns - update end to next token position
243+
if let State::InMapping {
244+
source,
245+
generated_line: current_line,
246+
start_column,
247+
..
248+
} = state
249+
{
250+
state = State::InMapping {
251+
source,
252+
generated_line: current_line,
253+
start_column,
254+
end_column: generated_column,
255+
};
256+
continue;
257+
}
258+
}
259+
260+
// End the current mapping if we're in one
261+
if let State::InMapping {
262+
source,
263+
generated_line: current_line,
264+
start_column,
265+
..
266+
} = state
267+
{
268+
state = end_current_mapping(
269+
source,
270+
current_line,
271+
start_column,
272+
generated_line,
273+
generated_column,
274+
lines,
275+
&mut chunk_parts,
276+
lines_vc,
277+
);
278+
}
279+
247280
// Start a new mapping and put the unaccounted part in between somewhere
281+
// Set end_column to start_column initially; it will be updated when we see the next
282+
// token
248283
match replace(
249284
&mut state,
250285
State::InMapping {
251286
source: original_file.clone(),
252-
current_generated_line: generated_line,
253-
current_generated_column: generated_column,
287+
generated_line,
288+
start_column: generated_column,
289+
end_column: generated_column,
254290
},
255291
) {
256292
State::InMapping { .. } => {
257293
unreachable!();
258294
}
259295
State::AfterMapping {
260296
source,
261-
current_generated_line,
297+
generated_line,
262298
current_generated_column,
263299
} => {
264300
let len = len_between(
265-
current_generated_line,
301+
generated_line,
266302
current_generated_column,
267303
generated_line,
268304
generated_column,
@@ -295,30 +331,21 @@ pub async fn split_output_asset_into_parts(
295331
// End the current token at end of file
296332
if let State::InMapping {
297333
ref source,
298-
current_generated_line,
299-
current_generated_column,
334+
generated_line,
335+
start_column,
336+
..
300337
} = state
301338
{
302-
let mapping_end_column =
303-
end_of_mapping_column(current_generated_line, last_line, last_column, lines);
304-
// TODO: Handle this better
305-
let len = mapping_end_column.saturating_sub(current_generated_column);
306-
add_chunk_part_range(
339+
state = end_current_mapping(
307340
source.clone(),
308-
ChunkPartRange {
309-
line: current_generated_line,
310-
start_column: current_generated_column,
311-
end_column: mapping_end_column,
312-
},
313-
len,
341+
generated_line,
342+
start_column,
343+
last_line,
344+
last_column,
345+
lines,
314346
&mut chunk_parts,
315347
lines_vc,
316348
);
317-
state = State::AfterMapping {
318-
source: source.clone(),
319-
current_generated_line,
320-
current_generated_column: mapping_end_column,
321-
};
322349
}
323350

324351
match state {
@@ -327,11 +354,11 @@ pub async fn split_output_asset_into_parts(
327354
}
328355
State::AfterMapping {
329356
source,
330-
current_generated_line,
357+
generated_line,
331358
current_generated_column,
332359
} => {
333360
let len = len_between(
334-
current_generated_line,
361+
generated_line,
335362
current_generated_column,
336363
last_line,
337364
last_column,

0 commit comments

Comments
 (0)