Move Binding initialization into SemanticModel (#4819)

This commit is contained in:
Charlie Marsh 2023-06-03 15:26:55 -04:00 committed by GitHub
parent 935094c2ff
commit c14896b42c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 189 deletions

View file

@ -257,21 +257,15 @@ where
Stmt::Global(ast::StmtGlobal { names, range: _ }) => { Stmt::Global(ast::StmtGlobal { names, range: _ }) => {
let ranges: Vec<TextRange> = helpers::find_names(stmt, self.locator).collect(); let ranges: Vec<TextRange> = helpers::find_names(stmt, self.locator).collect();
if !self.semantic_model.scope_id.is_global() { if !self.semantic_model.scope_id.is_global() {
// Add the binding to the current scope.
let context = self.semantic_model.execution_context();
let exceptions = self.semantic_model.exceptions();
let scope = &mut self.semantic_model.scopes[self.semantic_model.scope_id];
for (name, range) in names.iter().zip(ranges.iter()) { for (name, range) in names.iter().zip(ranges.iter()) {
// Add a binding to the current scope. // Add a binding to the current scope.
let binding_id = self.semantic_model.bindings.push(Binding { let binding = self.semantic_model.declared_binding(
kind: BindingKind::Global, *range,
range: *range, BindingKind::Global,
references: Vec::new(), BindingFlags::empty(),
source: self.semantic_model.stmt_id, );
context, let binding_id = self.semantic_model.bindings.push(binding);
exceptions, let scope = self.semantic_model.scope_mut();
flags: BindingFlags::empty(),
});
scope.add(name, binding_id); scope.add(name, binding_id);
} }
} }
@ -286,20 +280,15 @@ where
Stmt::Nonlocal(ast::StmtNonlocal { names, range: _ }) => { Stmt::Nonlocal(ast::StmtNonlocal { names, range: _ }) => {
let ranges: Vec<TextRange> = helpers::find_names(stmt, self.locator).collect(); let ranges: Vec<TextRange> = helpers::find_names(stmt, self.locator).collect();
if !self.semantic_model.scope_id.is_global() { if !self.semantic_model.scope_id.is_global() {
let context = self.semantic_model.execution_context();
let exceptions = self.semantic_model.exceptions();
let scope = &mut self.semantic_model.scopes[self.semantic_model.scope_id];
for (name, range) in names.iter().zip(ranges.iter()) { for (name, range) in names.iter().zip(ranges.iter()) {
// Add a binding to the current scope. // Add a binding to the current scope.
let binding_id = self.semantic_model.bindings.push(Binding { let binding = self.semantic_model.declared_binding(
kind: BindingKind::Nonlocal, *range,
range: *range, BindingKind::Nonlocal,
references: Vec::new(), BindingFlags::empty(),
source: self.semantic_model.stmt_id, );
context, let binding_id = self.semantic_model.bindings.push(binding);
exceptions, let scope = self.semantic_model.scope_mut();
flags: BindingFlags::empty(),
});
scope.add(name, binding_id); scope.add(name, binding_id);
} }
@ -841,18 +830,11 @@ where
for alias in names { for alias in names {
if &alias.name == "__future__" { if &alias.name == "__future__" {
let name = alias.asname.as_ref().unwrap_or(&alias.name); let name = alias.asname.as_ref().unwrap_or(&alias.name);
self.add_binding( self.add_binding(
name, name,
Binding { alias.range(),
kind: BindingKind::FutureImportation, BindingKind::FutureImportation,
range: alias.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
if self.enabled(Rule::LateFutureImport) { if self.enabled(Rule::LateFutureImport) {
@ -870,39 +852,25 @@ where
let full_name = &alias.name; let full_name = &alias.name;
self.add_binding( self.add_binding(
name, name,
Binding { alias.range(),
kind: BindingKind::SubmoduleImportation(SubmoduleImportation { BindingKind::SubmoduleImportation(SubmoduleImportation { full_name }),
full_name, BindingFlags::empty(),
}),
range: alias.range(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
} else { } else {
let name = alias.asname.as_ref().unwrap_or(&alias.name); let name = alias.asname.as_ref().unwrap_or(&alias.name);
let full_name = &alias.name; let full_name = &alias.name;
self.add_binding( self.add_binding(
name, name,
Binding { alias.range(),
kind: BindingKind::Importation(Importation { full_name }), BindingKind::Importation(Importation { full_name }),
range: alias.range(), if alias
references: Vec::new(), .asname
source: self.semantic_model.stmt_id, .as_ref()
context: self.semantic_model.execution_context(), .map_or(false, |asname| asname == &alias.name)
exceptions: self.semantic_model.exceptions(), {
flags: if alias BindingFlags::EXPLICIT_EXPORT
.asname } else {
.as_ref() BindingFlags::empty()
.map_or(false, |asname| asname == &alias.name)
{
BindingFlags::EXPLICIT_EXPORT
} else {
BindingFlags::empty()
},
}, },
); );
@ -1127,15 +1095,9 @@ where
self.add_binding( self.add_binding(
name, name,
Binding { alias.range(),
kind: BindingKind::FutureImportation, BindingKind::FutureImportation,
range: alias.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
if self.enabled(Rule::FutureFeatureNotDefined) { if self.enabled(Rule::FutureFeatureNotDefined) {
@ -1194,22 +1156,16 @@ where
helpers::format_import_from_member(level, module, &alias.name); helpers::format_import_from_member(level, module, &alias.name);
self.add_binding( self.add_binding(
name, name,
Binding { alias.range(),
kind: BindingKind::FromImportation(FromImportation { full_name }), BindingKind::FromImportation(FromImportation { full_name }),
range: alias.range(), if alias
references: Vec::new(), .asname
source: self.semantic_model.stmt_id, .as_ref()
context: self.semantic_model.execution_context(), .map_or(false, |asname| asname == &alias.name)
exceptions: self.semantic_model.exceptions(), {
flags: if alias BindingFlags::EXPLICIT_EXPORT
.asname } else {
.as_ref() BindingFlags::empty()
.map_or(false, |asname| asname == &alias.name)
{
BindingFlags::EXPLICIT_EXPORT
} else {
BindingFlags::empty()
},
}, },
); );
} }
@ -1927,15 +1883,9 @@ where
self.add_binding( self.add_binding(
name, name,
Binding { stmt.range(),
kind: BindingKind::FunctionDefinition, BindingKind::FunctionDefinition,
range: stmt.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
let definition = docstrings::extraction::extract_definition( let definition = docstrings::extraction::extract_definition(
@ -2163,15 +2113,9 @@ where
self.semantic_model.pop_definition(); self.semantic_model.pop_definition();
self.add_binding( self.add_binding(
name, name,
Binding { stmt.range(),
kind: BindingKind::ClassDefinition, BindingKind::ClassDefinition,
range: stmt.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
} }
_ => {} _ => {}
@ -4200,15 +4144,9 @@ where
// upstream. // upstream.
self.add_binding( self.add_binding(
&arg.arg, &arg.arg,
Binding { arg.range(),
kind: BindingKind::Argument, BindingKind::Argument,
range: arg.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
if self.enabled(Rule::AmbiguousVariableName) { if self.enabled(Rule::AmbiguousVariableName) {
@ -4248,15 +4186,9 @@ where
{ {
self.add_binding( self.add_binding(
name, name,
Binding { pattern.range(),
kind: BindingKind::Assignment, BindingKind::Assignment,
range: pattern.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
} }
@ -4380,8 +4312,16 @@ impl<'a> Checker<'a> {
} }
/// Add a [`Binding`] to the current scope, bound to the given name. /// Add a [`Binding`] to the current scope, bound to the given name.
fn add_binding(&mut self, name: &'a str, binding: Binding<'a>) -> BindingId { fn add_binding(
&mut self,
name: &'a str,
range: TextRange,
kind: BindingKind<'a>,
flags: BindingFlags,
) -> BindingId {
let binding_id = self.semantic_model.bindings.next_id(); let binding_id = self.semantic_model.bindings.next_id();
let binding = self.semantic_model.declared_binding(range, kind, flags);
if let Some((stack_index, existing_binding_id)) = self if let Some((stack_index, existing_binding_id)) = self
.semantic_model .semantic_model
.scopes .scopes
@ -4449,7 +4389,7 @@ impl<'a> Checker<'a> {
); );
if let Some(parent) = binding.source { if let Some(parent) = binding.source {
let parent = self.semantic_model.stmts[parent]; let parent = self.semantic_model.stmts[parent];
if matches!(parent, Stmt::ImportFrom(_)) if parent.is_import_from_stmt()
&& parent.range().contains_range(binding.range) && parent.range().contains_range(binding.range)
{ {
diagnostic.set_parent(parent.start()); diagnostic.set_parent(parent.start());
@ -4521,7 +4461,6 @@ impl<'a> Checker<'a> {
} }
fn bind_builtins(&mut self) { fn bind_builtins(&mut self) {
let scope = &mut self.semantic_model.scopes[self.semantic_model.scope_id];
for builtin in BUILTINS for builtin in BUILTINS
.iter() .iter()
.chain(MAGIC_GLOBALS.iter()) .chain(MAGIC_GLOBALS.iter())
@ -4529,15 +4468,9 @@ impl<'a> Checker<'a> {
.chain(self.settings.builtins.iter().map(String::as_str)) .chain(self.settings.builtins.iter().map(String::as_str))
{ {
// Add the builtin to the scope. // Add the builtin to the scope.
let binding_id = self.semantic_model.bindings.push(Binding { let binding = self.semantic_model.builtin_binding();
kind: BindingKind::Builtin, let binding_id = self.semantic_model.bindings.push(binding);
range: TextRange::default(), let scope = self.semantic_model.scope_mut();
source: None,
references: Vec::new(),
context: ExecutionContext::Runtime,
exceptions: Exceptions::empty(),
flags: BindingFlags::empty(),
});
scope.add(builtin, binding_id); scope.add(builtin, binding_id);
} }
} }
@ -4647,15 +4580,9 @@ impl<'a> Checker<'a> {
) { ) {
self.add_binding( self.add_binding(
id, id,
Binding { expr.range(),
kind: BindingKind::Annotation, BindingKind::Annotation,
range: expr.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
return; return;
} }
@ -4663,15 +4590,9 @@ impl<'a> Checker<'a> {
if matches!(parent, Stmt::For(_) | Stmt::AsyncFor(_)) { if matches!(parent, Stmt::For(_) | Stmt::AsyncFor(_)) {
self.add_binding( self.add_binding(
id, id,
Binding { expr.range(),
kind: BindingKind::LoopVar, BindingKind::LoopVar,
range: expr.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
return; return;
} }
@ -4679,15 +4600,9 @@ impl<'a> Checker<'a> {
if helpers::is_unpacking_assignment(parent, expr) { if helpers::is_unpacking_assignment(parent, expr) {
self.add_binding( self.add_binding(
id, id,
Binding { expr.range(),
kind: BindingKind::Binding, BindingKind::Binding,
range: expr.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
return; return;
} }
@ -4759,15 +4674,9 @@ impl<'a> Checker<'a> {
self.add_binding( self.add_binding(
id, id,
Binding { expr.range(),
kind: BindingKind::Export(Export { names: all_names }), BindingKind::Export(Export { names: all_names }),
range: expr.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
return; return;
} }
@ -4780,30 +4689,18 @@ impl<'a> Checker<'a> {
{ {
self.add_binding( self.add_binding(
id, id,
Binding { expr.range(),
kind: BindingKind::NamedExprAssignment, BindingKind::NamedExprAssignment,
range: expr.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
return; return;
} }
self.add_binding( self.add_binding(
id, id,
Binding { expr.range(),
kind: BindingKind::Assignment, BindingKind::Assignment,
range: expr.range(), BindingFlags::empty(),
references: Vec::new(),
source: self.semantic_model.stmt_id,
context: self.semantic_model.execution_context(),
exceptions: self.semantic_model.exceptions(),
flags: BindingFlags::empty(),
},
); );
} }

View file

@ -114,6 +114,37 @@ impl<'a> SemanticModel<'a> {
false false
} }
/// Create a new [`Binding`] for a builtin.
pub fn builtin_binding(&self) -> Binding<'static> {
Binding {
range: TextRange::default(),
kind: BindingKind::Builtin,
references: Vec::new(),
flags: BindingFlags::empty(),
source: None,
context: ExecutionContext::Runtime,
exceptions: Exceptions::empty(),
}
}
/// Create a new `Binding` for the given `name` and `range`.
pub fn declared_binding(
&self,
range: TextRange,
kind: BindingKind<'a>,
flags: BindingFlags,
) -> Binding<'a> {
Binding {
range,
kind,
flags,
references: Vec::new(),
source: self.stmt_id,
context: self.execution_context(),
exceptions: self.exceptions(),
}
}
/// Return the current `Binding` for a given `name`. /// Return the current `Binding` for a given `name`.
pub fn find_binding(&self, member: &str) -> Option<&Binding> { pub fn find_binding(&self, member: &str) -> Option<&Binding> {
self.scopes() self.scopes()