refactor(semantic): simplify ScopeTree::iter_bindings (#8723)

The previous implementation is a little weird, I think it should be a shortcut of `bindings.iter`, It is infrequent we need to iter all symbols and know its scope ID. Only two cases in tests, and no use case in `Rolldown`
This commit is contained in:
Dunqing 2025-01-26 10:53:48 +00:00
parent 2e9a5602e9
commit c79206850c
3 changed files with 17 additions and 21 deletions

View file

@ -287,13 +287,9 @@ mod tests {
let source = "function Fn() {}";
let allocator = Allocator::default();
let semantic = get_semantic(&allocator, source, SourceType::default());
let scopes = semantic.scopes();
let top_level_a = semantic
.scopes()
.iter_bindings()
.find(|(_scope_id, _symbol_id, name)| *name == "Fn")
.unwrap();
assert_eq!(semantic.symbols.get_scope_id(top_level_a.1), top_level_a.0);
assert!(scopes.get_binding(scopes.root_scope_id(), "Fn").is_some());
}
#[test]

View file

@ -310,10 +310,8 @@ impl ScopeTree {
/// If you only want bindings in a specific scope, use [`iter_bindings_in`].
///
/// [`iter_bindings_in`]: ScopeTree::iter_bindings_in
pub fn iter_bindings(&self) -> impl Iterator<Item = (ScopeId, SymbolId, &str)> + '_ {
self.cell.borrow_dependent().bindings.iter_enumerated().flat_map(|(scope_id, bindings)| {
bindings.iter().map(move |(&name, &symbol_id)| (scope_id, symbol_id, name))
})
pub fn iter_bindings(&self) -> impl Iterator<Item = (ScopeId, &Bindings)> + '_ {
self.cell.borrow_dependent().bindings.iter_enumerated()
}
/// Iterate over bindings declared inside a scope.

View file

@ -1,7 +1,7 @@
use std::rc::Rc;
use oxc_diagnostics::{Error, OxcDiagnostic};
use oxc_semantic::{Reference, ScopeFlags, ScopeId, Semantic, SymbolFlags, SymbolId};
use oxc_semantic::{Reference, ScopeFlags, Semantic, SymbolFlags, SymbolId};
use super::{Expect, SemanticTester};
@ -65,15 +65,15 @@ impl<'a> SymbolTester<'a> {
semantic: Semantic<'a>,
target: &str,
) -> Self {
let symbols_with_target_name: Vec<_> =
semantic.scopes().iter_bindings().filter(|(_, _, name)| *name == target).collect();
let mut symbols_with_target_name: Vec<SymbolId> = semantic
.scopes()
.iter_bindings()
.filter_map(|(_, bindings)| bindings.get(target).copied())
.collect();
let data = match symbols_with_target_name.len() {
0 => Err(OxcDiagnostic::error(format!("Could not find declaration for {target}"))),
1 => Ok(symbols_with_target_name
.iter()
.map(|&(_, symbol_id, _)| symbol_id)
.next()
.unwrap()),
1 => Ok(symbols_with_target_name.pop().unwrap()),
n if n > 1 => Err(OxcDiagnostic::error(format!(
"Couldn't uniquely resolve symbol id for target {target}; {n} symbols with that name are declared in the source."
))),
@ -98,11 +98,13 @@ impl<'a> SymbolTester<'a> {
semantic: Semantic<'a>,
target: &str,
) -> Self {
let symbols_with_target_name: Option<(ScopeId, SymbolId, &str)> =
semantic.scopes().iter_bindings().find(|(_, _, name)| *name == target);
let symbols_with_target_name: Option<SymbolId> = semantic
.scopes()
.iter_bindings()
.find_map(|(_, bindings)| bindings.get(target).copied());
let data = match symbols_with_target_name {
Some((_, symbol_id, _)) => Ok(symbol_id),
Some(symbol_id) => Ok(symbol_id),
None => Err(OxcDiagnostic::error(format!("Could not find declaration for {target}"))),
};