forked from M-Labs/nac3
nac3core: top level derive fmt::Debug, fix dead lock
This commit is contained in:
parent
54b4572c5f
commit
235b6e34d1
@ -1,4 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::{cell::RefCell, sync::Arc};
|
||||
|
||||
use crate::toplevel::{DefinitionId, TopLevelDef};
|
||||
@ -219,3 +220,9 @@ impl dyn SymbolResolver + Send + Sync {
|
||||
parse_type_annotation(self, top_level_defs, unifier, primitives, expr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for dyn SymbolResolver + Send + Sync {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "")
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use std::{borrow::{Borrow, BorrowMut}, collections::{HashMap, HashSet}, iter::FromIterator, ops::{Deref, DerefMut}, sync::Arc};
|
||||
use std::{borrow::BorrowMut, collections::{HashMap, HashSet}, iter::FromIterator, ops::{Deref, DerefMut}, sync::Arc};
|
||||
|
||||
use super::typecheck::type_inferencer::PrimitiveStore;
|
||||
use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier};
|
||||
@ -6,11 +6,11 @@ use crate::{
|
||||
symbol_resolver::SymbolResolver,
|
||||
typecheck::{type_inferencer::CodeLocation, typedef::CallId},
|
||||
};
|
||||
use itertools::{izip, Itertools};
|
||||
use itertools::Itertools;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use rustpython_parser::ast::{self, Stmt};
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
|
||||
pub struct DefinitionId(pub usize);
|
||||
|
||||
mod type_annotation;
|
||||
@ -19,7 +19,7 @@ mod helper;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FunInstance {
|
||||
pub body: Vec<Stmt<Option<Type>>>,
|
||||
pub calls: HashMap<CodeLocation, CallId>,
|
||||
@ -27,6 +27,7 @@ pub struct FunInstance {
|
||||
pub unifier_id: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TopLevelDef {
|
||||
Class {
|
||||
// name for error messages and symbols
|
||||
|
@ -8,12 +8,12 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use indoc::indoc;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use rustpython_parser::{ast::fold::Fold, parser::parse_program};
|
||||
use std::{borrow::BorrowMut, collections::{HashMap, HashSet}, sync::Arc};
|
||||
use parking_lot::Mutex;
|
||||
use rustpython_parser::parser::parse_program;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use test_case::test_case;
|
||||
|
||||
use super::TopLevelComposer;
|
||||
use super::*;
|
||||
|
||||
struct Resolver {
|
||||
id_to_type: HashMap<String, Type>,
|
||||
@ -48,13 +48,13 @@ impl SymbolResolver for Resolver {
|
||||
#[test_case(
|
||||
vec![
|
||||
indoc! {"
|
||||
def fun(a: int) -> int:
|
||||
def fun(a: int32) -> int32:
|
||||
return a
|
||||
"},
|
||||
indoc! {"
|
||||
class A:
|
||||
def __init__(self):
|
||||
self.a: int = 3
|
||||
self.a: int32 = 3
|
||||
"},
|
||||
indoc! {"
|
||||
class B:
|
||||
@ -71,7 +71,7 @@ impl SymbolResolver for Resolver {
|
||||
indoc! {"
|
||||
class C(B):
|
||||
def __init__(self):
|
||||
self.c: int = 4
|
||||
self.c: int32 = 4
|
||||
self.a: bool = True
|
||||
"}
|
||||
]
|
||||
@ -90,35 +90,30 @@ fn test_simple_register(source: Vec<&str>) {
|
||||
#[test_case(
|
||||
vec![
|
||||
indoc! {"
|
||||
def fun(a: int) -> int:
|
||||
def fun(a: int32) -> int32:
|
||||
return a
|
||||
"},
|
||||
// indoc! {"
|
||||
// class A:
|
||||
// def __init__(self):
|
||||
// self.a: int = 3
|
||||
// "},
|
||||
// indoc! {"
|
||||
// class B:
|
||||
// def __init__(self):
|
||||
// self.b: float = 4.3
|
||||
|
||||
// def fun(self):
|
||||
// self.b = self.b + 3.0
|
||||
// "},
|
||||
// indoc! {"
|
||||
// def foo(a: float):
|
||||
// a + 1.0
|
||||
// "},
|
||||
// indoc! {"
|
||||
// class C(B):
|
||||
// def __init__(self):
|
||||
// self.c: int = 4
|
||||
// self.a: bool = True
|
||||
// "}
|
||||
indoc! {"
|
||||
def foo(a: float):
|
||||
a + 1.0
|
||||
"},
|
||||
indoc! {"
|
||||
def f(b: int64) -> int32:
|
||||
return 3
|
||||
"},
|
||||
],
|
||||
vec![
|
||||
"fn[[a=0], 0]",
|
||||
"fn[[a=2], 4]",
|
||||
"fn[[b=1], 0]",
|
||||
],
|
||||
vec![
|
||||
"fun",
|
||||
"foo",
|
||||
"f"
|
||||
]
|
||||
)]
|
||||
fn test_simple_analyze(source: Vec<&str>) {
|
||||
fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&str>) {
|
||||
let mut composer = TopLevelComposer::new();
|
||||
|
||||
let resolver = Arc::new(Mutex::new(Box::new(Resolver {
|
||||
@ -136,4 +131,13 @@ fn test_simple_analyze(source: Vec<&str>) {
|
||||
}
|
||||
|
||||
composer.start_analysis().unwrap();
|
||||
|
||||
for (i, (def, _)) in composer.definition_ast_list.into_iter().enumerate() {
|
||||
let def = &*def.read();
|
||||
if let TopLevelDef::Function { signature, name, .. } = def {
|
||||
let ty_str = composer.unifier.stringify(*signature, &mut |id| id.to_string(), &mut |id| id.to_string());
|
||||
assert_eq!(ty_str, tys[i]);
|
||||
assert_eq!(name, names[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::typecheck::typedef::TypeVarMeta;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TypeAnnotation {
|
||||
PrimitiveKind(Type),
|
||||
// we use type vars kind at params to represent self type
|
||||
@ -33,7 +33,12 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||
"bool" => Ok(TypeAnnotation::PrimitiveKind(primitives.bool)),
|
||||
"None" => Ok(TypeAnnotation::PrimitiveKind(primitives.none)),
|
||||
x => {
|
||||
if let Some(obj_id) = resolver.lock().get_identifier_def(x) {
|
||||
if let Some(obj_id) = {
|
||||
// write this way because the lock in the if/let construct lives
|
||||
// for the whole if let construct
|
||||
let id = resolver.lock().get_identifier_def(x);
|
||||
id
|
||||
} {
|
||||
let def = top_level_defs[obj_id.0].read();
|
||||
if let TopLevelDef::Class { type_vars, .. } = &*def {
|
||||
// also check param number here
|
||||
@ -47,7 +52,10 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||
} else {
|
||||
Err("function cannot be used as a type".into())
|
||||
}
|
||||
} else if let Some(ty) = resolver.lock().get_symbol_type(unifier, primitives, id) {
|
||||
} else if let Some(ty) = {
|
||||
let ty = resolver.lock().get_symbol_type(unifier, primitives, id);
|
||||
ty
|
||||
} {
|
||||
if let TypeEnum::TVar { .. } = unifier.get_ty(ty).as_ref() {
|
||||
Ok(TypeAnnotation::TypeVarKind(ty))
|
||||
} else {
|
||||
|
@ -16,7 +16,7 @@ mod test;
|
||||
/// Handle for a type, implementated as a key in the unification table.
|
||||
pub type Type = UnificationKey;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct CallId(usize);
|
||||
|
||||
pub type Mapping<K, V = Type> = HashMap<K, V>;
|
||||
|
Loading…
Reference in New Issue
Block a user