From 36d03df0582b44acbfb439a04c665b4c66f352e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E5=8D=9A=E6=96=87?= Date: Sat, 9 Nov 2024 00:41:14 +0800 Subject: [PATCH] refactor: Remove type wrappers --- lib/src/analysis/type_analyze.rs | 8 +-- lib/src/ast/mod.rs | 100 +++++++++++++---------------- lib/src/ast/types.rs | 24 +++++-- lib/src/parser/default_impl/mod.rs | 1 - lib/src/test/test_type_analyze.rs | 2 +- lsp/src/lsp.rs | 4 +- 6 files changed, 72 insertions(+), 67 deletions(-) diff --git a/lib/src/analysis/type_analyze.rs b/lib/src/analysis/type_analyze.rs index 23d9d41..7588c24 100644 --- a/lib/src/analysis/type_analyze.rs +++ b/lib/src/analysis/type_analyze.rs @@ -169,18 +169,18 @@ fn analyze_op_expr_type(op1: &Option, op2: &Option) -> Option let tc2 = op2.as_ref()?.type_class(); // Usertype is not handled - if matches!(tc1, TypeClass::UserType(..)) { + if matches!(tc1, TypeClass::UserType) { return None; } - if matches!(tc2, TypeClass::UserType(..)) { + if matches!(tc2, TypeClass::UserType) { return None; } // Array is not handled - if matches!(tc1, TypeClass::Array(..)) { + if matches!(tc1, TypeClass::Array) { return None; } - if matches!(tc2, TypeClass::Array(..)) { + if matches!(tc2, TypeClass::Array) { return None; } diff --git a/lib/src/ast/mod.rs b/lib/src/ast/mod.rs index faaa084..5004807 100644 --- a/lib/src/ast/mod.rs +++ b/lib/src/ast/mod.rs @@ -1,6 +1,7 @@ use crate::parser::{LiteralValue, Operator, StString}; use bitflags::bitflags; use smallvec::SmallVec; +use std::any::Any; use std::fmt::{self, Debug, Display, Formatter}; use std::hash::{Hash, Hasher}; use std::sync::{Arc, RwLock}; @@ -127,36 +128,61 @@ impl_into_expression!(LiteralValue, |x| Expression::literal(Box::new( LiteralExpression::new(x) ))); -#[derive(Clone, Debug)] +pub trait TypeTrait: Send + Sync { + fn class(&self) -> TypeClass; + fn as_any(&self) -> &dyn Any; +} + +#[derive(Clone)] pub struct Type { - inner: Arc, + inner: Arc, +} + +pub enum TypeEnum { + Basic(TypeClass), + Complex(Box), +} + +impl Debug for Type { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("{}", self.type_class())) + } } impl Type { pub fn from_class(class: TypeClass) -> Self { Self { - inner: Arc::new(TypeInner { class }), + inner: Arc::new(TypeEnum::Basic(class)), + } + } + + pub fn from_object(o: impl TypeTrait + 'static) -> Self { + Self { + inner: Arc::new(TypeEnum::Complex(Box::new(o))), } } - pub fn type_class(&self) -> &TypeClass { - &self.inner.class + pub fn type_class(&self) -> TypeClass { + match self.inner.as_ref() { + TypeEnum::Basic(basic) => *basic, + TypeEnum::Complex(complex) => complex.class(), + } } - pub fn cast(self) -> T { - todo!() + pub fn complex(&self) -> bool { + matches!(*self.inner, TypeEnum::Complex(..)) } } impl Display for Type { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}", *self.inner) + write!(f, "{}", self.type_class()) } } impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { - self.inner.as_ref() == other.inner.as_ref() + self.type_class() == other.type_class() } } @@ -286,7 +312,7 @@ pub enum UserTypeClass { Union, } -#[derive(Debug, Clone)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum TypeClass { /// 'BIT', one bit type Bit, @@ -315,36 +341,11 @@ pub enum TypeClass { /// 'STRING' string type String, /// UserType - UserType(Arc>), + UserType, /// ArrayType - Array(Arc>), + Array, } -impl PartialEq for TypeClass { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Self::Int, Self::Int) => true, - (Self::Bit, Self::Bit) => true, - (Self::Bool, Self::Bool) => true, - (Self::SInt, Self::SInt) => true, - (Self::Byte, Self::Byte) => true, - (Self::UInt, Self::UInt) => true, - (Self::UDInt, Self::UDInt) => true, - (Self::ULInt, Self::ULInt) => true, - (Self::Real, Self::Real) => true, - (Self::LReal, Self::LReal) => true, - (Self::String, Self::String) => true, - (Self::UserType(a), Self::UserType(b)) => { - a.read().unwrap().name() == b.read().unwrap().name() - } - (Self::Array(a), Self::Array(b)) => false, - _ => false, - } - } -} - -impl Eq for TypeClass {} - impl Hash for TypeClass { fn hash(&self, state: &mut H) { let tag = match self { @@ -353,25 +354,13 @@ impl Hash for TypeClass { TypeClass::Byte => 3, TypeClass::UInt => 4, TypeClass::Int => 5, - _ => unimplemented!("{:?}", self), + TypeClass::UserType => 6, + TypeClass::Array => 7, + // Some type shouldn't hash directly like ArrayType or UserType + _ => unreachable!("TypeClass shouldn't hash: {:?}", self), }; tag.hash(state); - - // TODO: incomplete implements - match self { - TypeClass::UserType(user_type) => { - // user_type.borrow().name().hash(state); - user_type.read().unwrap().name().hash(state); - } - TypeClass::Array(array_type) => { - // let array_type = array_type.borrow(); - let array_type = array_type.read().unwrap(); - let base_type = array_type.base_type().read().unwrap(); - base_type.type_class().hash(state); - } - _ => {} - } } } @@ -391,8 +380,9 @@ impl Display for TypeClass { TypeClass::Real => write!(f, "REAL"), TypeClass::LReal => write!(f, "LREAL"), TypeClass::String => write!(f, "STRING"), - TypeClass::UserType(u) => write!(f, "{}", u.read().unwrap()), - TypeClass::Array(arr) => write!(f, "{}", arr.read().unwrap()), + TypeClass::UserType | TypeClass::Array => { + unreachable!("UserType or ArrayType can't display without Type object") + } } } } diff --git a/lib/src/ast/types.rs b/lib/src/ast/types.rs index 6973eab..262b382 100644 --- a/lib/src/ast/types.rs +++ b/lib/src/ast/types.rs @@ -59,9 +59,17 @@ impl UserType { impl From for Type { fn from(value: UserType) -> Self { - let class = TypeClass::UserType(Arc::new(RwLock::new(value))); + Type::from_object(value) + } +} + +impl TypeTrait for UserType { + fn class(&self) -> TypeClass { + TypeClass::UserType + } - Type::from_class(class) + fn as_any(&self) -> &dyn Any { + self } } @@ -219,8 +227,16 @@ impl Clone for ArrayType { impl From for Type { fn from(value: ArrayType) -> Self { - let class = TypeClass::Array(Arc::new(RwLock::new(value))); + Type::from_object(value) + } +} + +impl TypeTrait for ArrayType { + fn class(&self) -> TypeClass { + TypeClass::Array + } - Type::from_class(class) + fn as_any(&self) -> &dyn Any { + self } } diff --git a/lib/src/parser/default_impl/mod.rs b/lib/src/parser/default_impl/mod.rs index 9c99383..6fcecc0 100644 --- a/lib/src/parser/default_impl/mod.rs +++ b/lib/src/parser/default_impl/mod.rs @@ -3,7 +3,6 @@ use crate::parser::token::Token; use crate::parser::*; use smallvec::smallvec; -use std::rc::Rc; use std::sync::Arc; /// diff --git a/lib/src/test/test_type_analyze.rs b/lib/src/test/test_type_analyze.rs index de6fa6d..497c05b 100644 --- a/lib/src/test/test_type_analyze.rs +++ b/lib/src/test/test_type_analyze.rs @@ -38,7 +38,7 @@ fn test_type_analyze() { // test left side type assert!(assign_expr.left().ty().is_some()); assert_eq!( - *assign_expr.left().ty().unwrap().type_class(), + assign_expr.left().ty().unwrap().type_class(), TypeClass::Real ); diff --git a/lsp/src/lsp.rs b/lsp/src/lsp.rs index 13919a7..9909416 100644 --- a/lsp/src/lsp.rs +++ b/lsp/src/lsp.rs @@ -33,7 +33,7 @@ fn semantic_token_type_id(tok: &TokenKind) -> (u32, u32) { pub struct StcLsp { client: Client, src_mgr: DashMap, - units_mgr: UnitsManager, + _units_mgr: UnitsManager, } impl StcLsp { @@ -41,7 +41,7 @@ impl StcLsp { Self { client: c, src_mgr: DashMap::new(), - units_mgr: UnitsManager::new(), + _units_mgr: UnitsManager::new(), } } }