forked from M-Labs/nac3
nac3core: optimized by using HashSet
This commit is contained in:
parent
d81249cabe
commit
6633eabb89
@ -3,18 +3,18 @@ use crate::typecheck::typedef::TypeEnum;
|
||||
use super::type_inferencer::Inferencer;
|
||||
use super::typedef::Type;
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind};
|
||||
use std::iter::once;
|
||||
use std::{collections::HashSet, iter::once};
|
||||
|
||||
impl<'a> Inferencer<'a> {
|
||||
fn check_pattern(
|
||||
&mut self,
|
||||
pattern: &Expr<Option<Type>>,
|
||||
defined_identifiers: &mut Vec<String>,
|
||||
defined_identifiers: &mut HashSet<String>,
|
||||
) -> Result<(), String> {
|
||||
match &pattern.node {
|
||||
ExprKind::Name { id, .. } => {
|
||||
if !defined_identifiers.contains(id) {
|
||||
defined_identifiers.push(id.clone());
|
||||
defined_identifiers.insert(id.clone());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -42,7 +42,7 @@ impl<'a> Inferencer<'a> {
|
||||
fn check_expr(
|
||||
&mut self,
|
||||
expr: &Expr<Option<Type>>,
|
||||
defined_identifiers: &mut Vec<String>,
|
||||
defined_identifiers: &mut HashSet<String>,
|
||||
) -> Result<(), String> {
|
||||
// there are some cases where the custom field is None
|
||||
if let Some(ty) = &expr.custom {
|
||||
@ -58,7 +58,7 @@ impl<'a> Inferencer<'a> {
|
||||
ExprKind::Name { id, .. } => {
|
||||
if !defined_identifiers.contains(id) {
|
||||
if self.function_data.resolver.get_identifier_def(id).is_some() {
|
||||
defined_identifiers.push(id.clone());
|
||||
defined_identifiers.insert(id.clone());
|
||||
} else {
|
||||
return Err(format!(
|
||||
"unknown identifier {} (use before def?) at {}",
|
||||
@ -104,10 +104,10 @@ impl<'a> Inferencer<'a> {
|
||||
}
|
||||
}
|
||||
ExprKind::Lambda { args, body } => {
|
||||
let mut defined_identifiers = defined_identifiers.to_vec();
|
||||
let mut defined_identifiers = defined_identifiers.clone();
|
||||
for arg in args.args.iter() {
|
||||
if !defined_identifiers.contains(&arg.node.arg) {
|
||||
defined_identifiers.push(arg.node.arg.clone());
|
||||
defined_identifiers.insert(arg.node.arg.clone());
|
||||
}
|
||||
}
|
||||
self.check_expr(body, &mut defined_identifiers)?;
|
||||
@ -116,7 +116,7 @@ impl<'a> Inferencer<'a> {
|
||||
// in our type inference stage, we already make sure that there is only 1 generator
|
||||
let ast::Comprehension { target, iter, ifs, .. } = &generators[0];
|
||||
self.check_expr(iter, defined_identifiers)?;
|
||||
let mut defined_identifiers = defined_identifiers.to_vec();
|
||||
let mut defined_identifiers = defined_identifiers.clone();
|
||||
self.check_pattern(target, &mut defined_identifiers)?;
|
||||
for term in once(elt.as_ref()).chain(ifs.iter()) {
|
||||
self.check_expr(term, &mut defined_identifiers)?;
|
||||
@ -143,7 +143,7 @@ impl<'a> Inferencer<'a> {
|
||||
fn check_stmt(
|
||||
&mut self,
|
||||
stmt: &Stmt<Option<Type>>,
|
||||
defined_identifiers: &mut Vec<String>,
|
||||
defined_identifiers: &mut HashSet<String>,
|
||||
) -> Result<bool, String> {
|
||||
match &stmt.node {
|
||||
StmtKind::For { target, iter, body, orelse, .. } => {
|
||||
@ -167,7 +167,7 @@ impl<'a> Inferencer<'a> {
|
||||
|
||||
for ident in body_identifiers.iter() {
|
||||
if !defined_identifiers.contains(ident) && orelse_identifiers.contains(ident) {
|
||||
defined_identifiers.push(ident.clone())
|
||||
defined_identifiers.insert(ident.clone());
|
||||
}
|
||||
}
|
||||
Ok(body_returned && orelse_returned)
|
||||
@ -217,7 +217,7 @@ impl<'a> Inferencer<'a> {
|
||||
pub fn check_block(
|
||||
&mut self,
|
||||
block: &[Stmt<Option<Type>>],
|
||||
defined_identifiers: &mut Vec<String>,
|
||||
defined_identifiers: &mut HashSet<String>,
|
||||
) -> Result<bool, String> {
|
||||
let mut ret = false;
|
||||
for stmt in block {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::convert::{From, TryInto};
|
||||
use std::iter::once;
|
||||
use std::{cell::RefCell, sync::Arc};
|
||||
@ -45,7 +45,7 @@ pub struct FunctionData {
|
||||
|
||||
pub struct Inferencer<'a> {
|
||||
pub top_level: &'a TopLevelContext,
|
||||
pub defined_identifiers: Vec<String>,
|
||||
pub defined_identifiers: HashSet<String>,
|
||||
pub function_data: &'a mut FunctionData,
|
||||
pub unifier: &'a mut Unifier,
|
||||
pub primitives: &'a PrimitiveStore,
|
||||
@ -161,7 +161,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||
ast::ExprKind::Name { id, .. } => {
|
||||
if !self.defined_identifiers.contains(id) {
|
||||
if self.function_data.resolver.get_identifier_def(id.as_str()).is_some() {
|
||||
self.defined_identifiers.push(id.clone());
|
||||
self.defined_identifiers.insert(id.clone());
|
||||
} else {
|
||||
return Err(format!(
|
||||
"unknown identifier {} (use before def?) at {}",
|
||||
@ -215,7 +215,7 @@ impl<'a> Inferencer<'a> {
|
||||
match &pattern.node {
|
||||
ExprKind::Name { id, .. } => {
|
||||
if !self.defined_identifiers.contains(id) {
|
||||
self.defined_identifiers.push(id.clone());
|
||||
self.defined_identifiers.insert(id.clone());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -274,7 +274,7 @@ impl<'a> Inferencer<'a> {
|
||||
for arg in args.args.iter() {
|
||||
let name = &arg.node.arg;
|
||||
if !defined_identifiers.contains(name) {
|
||||
defined_identifiers.push(name.clone());
|
||||
defined_identifiers.insert(name.clone());
|
||||
}
|
||||
}
|
||||
let fn_args: Vec<_> = args
|
||||
|
Loading…
Reference in New Issue
Block a user