Skip to content

Commit e45e416

Browse files
DavisVaughanlionel-
authored andcommitted
Try use_def_maps: IndexVec<ScopeId, UseDefMapBuilder>
Closes #1156
1 parent 24754e7 commit e45e416

2 files changed

Lines changed: 24 additions & 69 deletions

File tree

crates/oak_index/src/builder.rs

Lines changed: 24 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use crate::semantic_index::SymbolFlags;
3030
use crate::semantic_index::SymbolTableBuilder;
3131
use crate::semantic_index::Use;
3232
use crate::semantic_index::UseId;
33-
use crate::use_def_map::UseDefMap;
3433
use crate::use_def_map::UseDefMapBuilder;
3534

3635
/// Build a [`SemanticIndex`] from a parsed R file.
@@ -49,9 +48,7 @@ struct SemanticIndexBuilder {
4948
symbol_tables: IndexVec<ScopeId, SymbolTableBuilder>,
5049
definitions: IndexVec<ScopeId, IndexVec<DefinitionId, Definition>>,
5150
uses: IndexVec<ScopeId, IndexVec<UseId, Use>>,
52-
use_def_maps: IndexVec<ScopeId, UseDefMap>,
53-
current_use_def: UseDefMapBuilder,
54-
use_def_stack: Vec<UseDefMapBuilder>,
51+
use_def_maps: IndexVec<ScopeId, UseDefMapBuilder>,
5552
current_scope: ScopeId,
5653
}
5754

@@ -79,16 +76,14 @@ impl SemanticIndexBuilder {
7976
symbol_tables.push(SymbolTableBuilder::new());
8077
definitions.push(IndexVec::new());
8178
uses.push(IndexVec::new());
82-
use_def_maps.push(UseDefMap::empty());
79+
use_def_maps.push(UseDefMapBuilder::new());
8380

8481
Self {
8582
scopes,
8683
symbol_tables,
8784
definitions,
8885
uses,
8986
use_def_maps,
90-
current_use_def: UseDefMapBuilder::new(),
91-
use_def_stack: Vec::new(),
9287
current_scope: file,
9388
}
9489
}
@@ -112,10 +107,7 @@ impl SemanticIndexBuilder {
112107
self.symbol_tables.push(SymbolTableBuilder::new());
113108
self.definitions.push(IndexVec::new());
114109
self.uses.push(IndexVec::new());
115-
self.use_def_maps.push(UseDefMap::empty());
116-
117-
let parent_use_def = std::mem::replace(&mut self.current_use_def, UseDefMapBuilder::new());
118-
self.use_def_stack.push(parent_use_def);
110+
self.use_def_maps.push(UseDefMapBuilder::new());
119111

120112
id
121113
}
@@ -128,13 +120,6 @@ impl SemanticIndexBuilder {
128120
Some(parent) => parent,
129121
None => panic!("`pop_scope()` called on the file scope"),
130122
};
131-
132-
let parent_use_def = match self.use_def_stack.pop() {
133-
Some(builder) => builder,
134-
None => panic!("`pop_scope()` called with empty use-def stack"),
135-
};
136-
let finalized = std::mem::replace(&mut self.current_use_def, parent_use_def).finish();
137-
self.use_def_maps[id] = finalized;
138123
}
139124

140125
fn add_definition(
@@ -150,9 +135,8 @@ impl SemanticIndexBuilder {
150135
kind,
151136
range,
152137
});
153-
154-
self.current_use_def.ensure_symbol(symbol_id);
155-
self.current_use_def.record_definition(symbol_id, def_id);
138+
self.use_def_maps[self.current_scope].ensure_symbol(symbol_id);
139+
self.use_def_maps[self.current_scope].record_definition(symbol_id, def_id);
156140
}
157141

158142
// Super-assignment is lexically in the current scope but binds in an
@@ -180,10 +164,8 @@ impl SemanticIndexBuilder {
180164
kind,
181165
range,
182166
});
183-
184-
let builder = self.use_def_builder_mut(target_scope);
185-
builder.ensure_symbol(target_symbol);
186-
builder.record_deferred_definition(target_symbol, target_def_id);
167+
self.use_def_maps[target_scope].ensure_symbol(target_symbol);
168+
self.use_def_maps[target_scope].record_deferred_definition(target_symbol, target_def_id);
187169
}
188170

189171
// Walk up from the parent scope looking for a scope where `name` already
@@ -212,34 +194,14 @@ impl SemanticIndexBuilder {
212194
}
213195
}
214196

215-
fn use_def_builder_mut(&mut self, target: ScopeId) -> &mut UseDefMapBuilder {
216-
if target == self.current_scope {
217-
return &mut self.current_use_def;
218-
}
219-
220-
let mut steps = 0;
221-
let mut scope = self.current_scope;
222-
while scope != target {
223-
scope = match self.scopes[scope].parent {
224-
Some(parent) => parent,
225-
None => panic!("Target scope {target:?} is not an ancestor of current scope"),
226-
};
227-
steps += 1;
228-
}
229-
230-
let index = self.use_def_stack.len() - steps;
231-
&mut self.use_def_stack[index]
232-
}
233-
234197
fn add_use(&mut self, name: &str, range: TextRange) {
235198
let symbol_id = self.symbol_tables[self.current_scope].intern(name, SymbolFlags::IS_USED);
236199
let use_id = self.uses[self.current_scope].push(Use {
237200
symbol: symbol_id,
238201
range,
239202
});
240-
241-
self.current_use_def.ensure_symbol(symbol_id);
242-
self.current_use_def.record_use(symbol_id, use_id);
203+
self.use_def_maps[self.current_scope].ensure_symbol(symbol_id);
204+
self.use_def_maps[self.current_scope].record_use(symbol_id, use_id);
243205
}
244206

245207
// --- Recursive descent ---
@@ -349,15 +311,15 @@ impl SemanticIndexBuilder {
349311
self.collect_expression(&sequence);
350312
}
351313

352-
let pre_loop = self.current_use_def.snapshot();
314+
let pre_loop = self.use_def_maps[self.current_scope].snapshot();
353315

354316
if let Ok(body) = stmt.body() {
355317
let first_use = self.uses[self.current_scope].next_id();
356318
self.collect_expression(&body);
357-
self.current_use_def.finish_loop_defs(&pre_loop, first_use);
319+
self.use_def_maps[self.current_scope].finish_loop_defs(&pre_loop, first_use);
358320
}
359321

360-
self.current_use_def.merge(pre_loop);
322+
self.use_def_maps[self.current_scope].merge(pre_loop);
361323
},
362324

363325
AnyRExpression::RIfStatement(stmt) => {
@@ -366,15 +328,15 @@ impl SemanticIndexBuilder {
366328
self.collect_expression(&condition);
367329
}
368330

369-
let pre_if = self.current_use_def.snapshot();
331+
let pre_if = self.use_def_maps[self.current_scope].snapshot();
370332

371333
// If-body (consequence)
372334
if let Ok(consequence) = stmt.consequence() {
373335
self.collect_expression(&consequence);
374336
}
375337

376-
let post_if = self.current_use_def.snapshot();
377-
self.current_use_def.restore(pre_if);
338+
let post_if = self.use_def_maps[self.current_scope].snapshot();
339+
self.use_def_maps[self.current_scope].restore(pre_if);
378340

379341
// Else-body (alternative), if present. If absent, the
380342
// "else path" is just the pre-if state we restored to.
@@ -385,33 +347,33 @@ impl SemanticIndexBuilder {
385347
}
386348

387349
// After: definitions from both branches are live
388-
self.current_use_def.merge(post_if);
350+
self.use_def_maps[self.current_scope].merge(post_if);
389351
},
390352

391353
AnyRExpression::RWhileStatement(stmt) => {
392354
if let Ok(condition) = stmt.condition() {
393355
self.collect_expression(&condition);
394356
}
395357

396-
let pre_loop = self.current_use_def.snapshot();
358+
let pre_loop = self.use_def_maps[self.current_scope].snapshot();
397359

398360
if let Ok(body) = stmt.body() {
399361
let first_use = self.uses[self.current_scope].next_id();
400362
self.collect_expression(&body);
401-
self.current_use_def.finish_loop_defs(&pre_loop, first_use);
363+
self.use_def_maps[self.current_scope].finish_loop_defs(&pre_loop, first_use);
402364
}
403365

404366
// Body may not execute
405-
self.current_use_def.merge(pre_loop);
367+
self.use_def_maps[self.current_scope].merge(pre_loop);
406368
},
407369

408370
AnyRExpression::RRepeatStatement(stmt) => {
409371
// Body always executes at least once, no snapshot needed
410372
if let Ok(body) = stmt.body() {
411-
let pre_loop = self.current_use_def.snapshot();
373+
let pre_loop = self.use_def_maps[self.current_scope].snapshot();
412374
let first_use = self.uses[self.current_scope].next_id();
413375
self.collect_expression(&body);
414-
self.current_use_def.finish_loop_defs(&pre_loop, first_use);
376+
self.use_def_maps[self.current_scope].finish_loop_defs(&pre_loop, first_use);
415377
}
416378
},
417379

@@ -563,16 +525,15 @@ impl SemanticIndexBuilder {
563525
fn finish(mut self) -> SemanticIndex {
564526
self.scopes[ScopeId::from(0)].descendants.end = self.scopes.next_id();
565527

566-
let file_use_def_map = self.current_use_def.finish();
567-
self.use_def_maps[ScopeId::from(0)] = file_use_def_map;
568-
569528
let symbol_tables = self.symbol_tables.into_iter().map(|b| b.build()).collect();
529+
let use_def_maps = self.use_def_maps.into_iter().map(|b| b.finish()).collect();
530+
570531
SemanticIndex::new(
571532
self.scopes,
572533
symbol_tables,
573534
self.definitions,
574535
self.uses,
575-
self.use_def_maps,
536+
use_def_maps,
576537
)
577538
}
578539
}

crates/oak_index/src/use_def_map.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,6 @@ pub struct UseDefMap {
139139
}
140140

141141
impl UseDefMap {
142-
pub(crate) fn empty() -> Self {
143-
Self {
144-
bindings_by_use: IndexVec::new(),
145-
}
146-
}
147-
148142
pub fn bindings_at_use(&self, use_id: UseId) -> &Bindings {
149143
&self.bindings_by_use[use_id]
150144
}

0 commit comments

Comments
 (0)