Skip to content

Commit 75ea6fe

Browse files
committed
Merge remote-tracking branch 'CppCXY/main' into dev
2 parents 1eab8bf + 7d05fa1 commit 75ea6fe

File tree

12 files changed

+233
-244
lines changed

12 files changed

+233
-244
lines changed

crates/emmylua_code_analysis/src/compilation/analyzer/doc/type_ref_tags.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ fn analyze_cast_with_name_token(
313313
flow_chain.add_type_assert(TypeAssertion::Remove(typ), effect_range);
314314
}
315315
CastAction::Force => {
316-
flow_chain.add_type_assert(TypeAssertion::Force(typ), effect_range);
316+
flow_chain.add_type_assert(TypeAssertion::Narrow(typ), effect_range);
317317
}
318318
}
319319
}

crates/emmylua_code_analysis/src/compilation/analyzer/flow/assign_stats.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::collections::HashMap;
22

3-
#[allow(unused_imports)]
43
use emmylua_parser::{LuaAssignStat, LuaAstNode, LuaNameExpr, LuaSyntaxId, LuaSyntaxKind};
54
use emmylua_parser::{LuaAst, LuaBlock, LuaExpr, LuaIfStat, LuaSyntaxNode};
65
use rowan::TextRange;

crates/emmylua_code_analysis/src/compilation/analyzer/flow/name_ref.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ fn broadcast_up(
114114
TypeAssertion::NotExist
115115
}
116116
}
117-
LuaLiteralToken::Number(_) => TypeAssertion::Force(LuaType::Number),
118-
LuaLiteralToken::String(_) => TypeAssertion::Force(LuaType::String),
117+
LuaLiteralToken::Number(_) => TypeAssertion::Narrow(LuaType::Number),
118+
LuaLiteralToken::String(_) => TypeAssertion::Narrow(LuaType::String),
119119
_ => return None,
120120
};
121121

@@ -206,14 +206,14 @@ fn infer_lua_type_assert(
206206
};
207207

208208
let type_assert = match type_literal.as_str() {
209-
"number" => TypeAssertion::Force(LuaType::Number),
210-
"string" => TypeAssertion::Force(LuaType::String),
211-
"boolean" => TypeAssertion::Force(LuaType::Boolean),
212-
"table" => TypeAssertion::Force(LuaType::Table),
213-
"function" => TypeAssertion::Force(LuaType::Function),
214-
"thread" => TypeAssertion::Force(LuaType::Thread),
215-
"userdata" => TypeAssertion::Force(LuaType::Userdata),
216-
"nil" => TypeAssertion::Force(LuaType::Nil),
209+
"number" => TypeAssertion::Narrow(LuaType::Number),
210+
"string" => TypeAssertion::Narrow(LuaType::String),
211+
"boolean" => TypeAssertion::Narrow(LuaType::Boolean),
212+
"table" => TypeAssertion::Narrow(LuaType::Table),
213+
"function" => TypeAssertion::Narrow(LuaType::Function),
214+
"thread" => TypeAssertion::Narrow(LuaType::Thread),
215+
"userdata" => TypeAssertion::Narrow(LuaType::Userdata),
216+
"nil" => TypeAssertion::Narrow(LuaType::Nil),
217217
_ => {
218218
return None;
219219
}

crates/emmylua_code_analysis/src/db_index/type/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub use type_decl::{
1717
LuaDeclLocation, LuaDeclTypeKind, LuaTypeAttribute, LuaTypeDecl, LuaTypeDeclId,
1818
};
1919
pub use types::*;
20+
pub use type_ops::TypeOps;
2021

2122
#[derive(Debug)]
2223
pub struct LuaTypeIndex {

crates/emmylua_code_analysis/src/db_index/type/type_assert.rs

Lines changed: 13 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use std::{ops::Deref, sync::Arc};
33
use crate::{infer_expr, DbIndex, LuaInferConfig};
44
use emmylua_parser::{LuaAstNode, LuaExpr, LuaSyntaxId, LuaSyntaxNode};
55

6-
use super::{LuaMemberPathExistType, LuaType, LuaUnionType};
6+
use super::{type_ops::TypeOps, LuaMemberPathExistType, LuaType};
77

88
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
99
pub enum TypeAssertion {
1010
Exist,
1111
NotExist,
12-
Force(LuaType),
12+
Narrow(LuaType),
1313
MemberPathExist(Arc<String>),
1414
Add(LuaType),
1515
Remove(LuaType),
@@ -21,14 +21,14 @@ pub enum TypeAssertion {
2121
impl TypeAssertion {
2222
pub fn simple_tighten_type(&self, source: LuaType) -> LuaType {
2323
match self {
24-
TypeAssertion::Exist => remove_nil_and_not_false(source),
24+
TypeAssertion::Exist => TypeOps::Remove.apply(&source, &LuaType::Nil),
2525
TypeAssertion::NotExist => force_nil_or_false(source),
26-
TypeAssertion::Force(t) => narrow_down_type(source, t.clone()),
26+
TypeAssertion::Narrow(t) => TypeOps::Narrow.apply(&source, t),
2727
TypeAssertion::MemberPathExist(key) => LuaType::MemberPathExist(
2828
LuaMemberPathExistType::new(&key.deref(), source, 0).into(),
2929
),
30-
TypeAssertion::Add(lua_type) => add_type(source, lua_type.clone()),
31-
TypeAssertion::Remove(lua_type) => remove_type(source, lua_type.clone()),
30+
TypeAssertion::Add(lua_type) => TypeOps::Union.apply(&source, lua_type),
31+
TypeAssertion::Remove(lua_type) => TypeOps::Remove.apply(&source, lua_type),
3232
_ => source,
3333
}
3434
}
@@ -37,7 +37,7 @@ impl TypeAssertion {
3737
match self {
3838
TypeAssertion::Exist => Some(TypeAssertion::NotExist),
3939
TypeAssertion::NotExist => Some(TypeAssertion::Exist),
40-
TypeAssertion::Force(t) => Some(TypeAssertion::Remove(t.clone())),
40+
TypeAssertion::Narrow(t) => Some(TypeAssertion::Remove(t.clone())),
4141
_ => None,
4242
}
4343
}
@@ -50,25 +50,25 @@ impl TypeAssertion {
5050
source: LuaType,
5151
) -> Option<LuaType> {
5252
match self {
53-
TypeAssertion::Exist => Some(remove_nil_and_not_false(source)),
53+
TypeAssertion::Exist => Some(TypeOps::Remove.apply(&source, &LuaType::Nil)),
5454
TypeAssertion::NotExist => Some(force_nil_or_false(source)),
55-
TypeAssertion::Force(t) => Some(narrow_down_type(source, t.clone())),
55+
TypeAssertion::Narrow(t) => Some(TypeOps::Narrow.apply(&source, t)),
5656
TypeAssertion::MemberPathExist(key) => Some(LuaType::MemberPathExist(
5757
LuaMemberPathExistType::new(&key.deref(), source, 0).into(),
5858
)),
59-
TypeAssertion::Add(lua_type) => Some(add_type(source, lua_type.clone())),
60-
TypeAssertion::Remove(lua_type) => Some(remove_type(source, lua_type.clone())),
59+
TypeAssertion::Add(lua_type) => Some(TypeOps::Union.apply(&source, lua_type)),
60+
TypeAssertion::Remove(lua_type) => Some(TypeOps::Remove.apply(&source, lua_type)),
6161
TypeAssertion::Reassign(syntax_id) => {
6262
let expr = LuaExpr::cast(syntax_id.to_node_from_root(root)?)?;
6363
let expr_type = infer_expr(db, config, expr)?;
64-
Some(narrow_down_type(source, expr_type))
64+
Some(TypeOps::Narrow.apply(&source, &expr_type))
6565
}
6666
TypeAssertion::AddUnion(syntax_ids) => {
6767
let mut typ = source;
6868
for syntax_id in syntax_ids {
6969
let expr = LuaExpr::cast(syntax_id.to_node_from_root(root)?)?;
7070
let expr_type = infer_expr(db, config, expr)?;
71-
typ = add_type(typ, expr_type);
71+
typ = TypeOps::Union.apply(&typ, &expr_type);
7272
}
7373

7474
Some(typ)
@@ -78,27 +78,6 @@ impl TypeAssertion {
7878
}
7979
}
8080

81-
fn remove_nil_and_not_false(t: LuaType) -> LuaType {
82-
match t {
83-
LuaType::Nil => LuaType::Unknown,
84-
LuaType::Union(types) => {
85-
let mut new_types = Vec::new();
86-
for t in types.get_types() {
87-
let t = remove_nil_and_not_false(t.clone());
88-
if t != LuaType::Unknown {
89-
new_types.push(t);
90-
}
91-
}
92-
if new_types.len() == 1 {
93-
new_types.pop().unwrap()
94-
} else {
95-
LuaType::Union(LuaUnionType::new(new_types).into())
96-
}
97-
}
98-
LuaType::Nullable(t) => remove_nil_and_not_false((*t).clone()),
99-
t => t,
100-
}
101-
}
10281

10382
fn force_nil_or_false(t: LuaType) -> LuaType {
10483
if t.is_boolean() {
@@ -108,169 +87,3 @@ fn force_nil_or_false(t: LuaType) -> LuaType {
10887
return LuaType::Nil;
10988
}
11089

111-
// need to be optimized
112-
fn narrow_down_type(source: LuaType, target: LuaType) -> LuaType {
113-
match &source {
114-
LuaType::Union(union) => {
115-
let mut types = union.get_types().to_vec();
116-
match target {
117-
LuaType::Number | LuaType::FloatConst(_) | LuaType::IntegerConst(_) => {
118-
types.retain(|t| t.is_number());
119-
if types.len() == 1 {
120-
types.pop().unwrap()
121-
} else {
122-
LuaType::Union(LuaUnionType::new(types).into())
123-
}
124-
}
125-
LuaType::String | LuaType::StringConst(_) => {
126-
types.retain(|t| t.is_string());
127-
if types.len() == 1 {
128-
types.pop().unwrap()
129-
} else {
130-
LuaType::Union(LuaUnionType::new(types).into())
131-
}
132-
}
133-
LuaType::Boolean | LuaType::BooleanConst(_) => {
134-
types.retain(|t| t.is_boolean());
135-
if types.len() == 1 {
136-
types.pop().unwrap()
137-
} else {
138-
LuaType::Union(LuaUnionType::new(types).into())
139-
}
140-
}
141-
LuaType::Table | LuaType::TableConst(_) => {
142-
types.retain(|t| t.is_table());
143-
if types.len() == 1 {
144-
types.pop().unwrap()
145-
} else {
146-
LuaType::Union(LuaUnionType::new(types).into())
147-
}
148-
}
149-
LuaType::Function => {
150-
types.retain(|t| t.is_function());
151-
if types.len() == 1 {
152-
types.pop().unwrap()
153-
} else {
154-
LuaType::Union(LuaUnionType::new(types).into())
155-
}
156-
}
157-
LuaType::Thread => {
158-
types.retain(|t| t.is_thread());
159-
if types.len() == 1 {
160-
types.pop().unwrap()
161-
} else {
162-
LuaType::Union(LuaUnionType::new(types).into())
163-
}
164-
}
165-
LuaType::Userdata => {
166-
types.retain(|t| t.is_userdata());
167-
if types.len() == 1 {
168-
types.pop().unwrap()
169-
} else {
170-
LuaType::Union(LuaUnionType::new(types).into())
171-
}
172-
}
173-
LuaType::Nil => {
174-
types.retain(|t| t.is_nil());
175-
if types.len() == 1 {
176-
types.pop().unwrap()
177-
} else {
178-
LuaType::Union(LuaUnionType::new(types).into())
179-
}
180-
}
181-
_ => target,
182-
}
183-
}
184-
LuaType::Nullable(inner) => {
185-
if !target.is_nullable() {
186-
narrow_down_type(target, (**inner).clone())
187-
} else {
188-
LuaType::Nil
189-
}
190-
}
191-
LuaType::BooleanConst(_) => {
192-
if target.is_boolean() {
193-
return LuaType::Boolean;
194-
}
195-
196-
target
197-
}
198-
LuaType::FloatConst(_) => {
199-
if target.is_number() {
200-
return LuaType::Number;
201-
}
202-
203-
target
204-
}
205-
LuaType::IntegerConst(_) => {
206-
if target.is_number() {
207-
return LuaType::Number;
208-
}
209-
210-
target
211-
}
212-
LuaType::StringConst(_) => {
213-
if target.is_string() {
214-
return LuaType::String;
215-
}
216-
217-
target
218-
}
219-
_ => target,
220-
}
221-
}
222-
223-
fn add_type(source: LuaType, added_typ: LuaType) -> LuaType {
224-
if added_typ.is_nil() {
225-
return LuaType::Nullable(source.into());
226-
}
227-
228-
match source {
229-
LuaType::Union(union) => {
230-
let mut types = union.get_types().to_vec();
231-
types.push(added_typ);
232-
LuaType::Union(LuaUnionType::new(types).into())
233-
}
234-
LuaType::Nullable(inner) => {
235-
let inner = add_type((*inner).clone(), added_typ);
236-
LuaType::Nullable(inner.into())
237-
}
238-
LuaType::Unknown | LuaType::Any => added_typ,
239-
_ => {
240-
if source.is_number() && added_typ.is_number() {
241-
return LuaType::Number;
242-
} else if source.is_string() && added_typ.is_string() {
243-
return LuaType::String;
244-
} else if source.is_boolean() && added_typ.is_boolean() {
245-
return LuaType::Boolean;
246-
} else if source.is_table() && added_typ.is_table() {
247-
return LuaType::Table;
248-
}
249-
250-
LuaType::Union(LuaUnionType::new(vec![source, added_typ]).into())
251-
},
252-
}
253-
}
254-
255-
fn remove_type(source: LuaType, removed_type: LuaType) -> LuaType {
256-
if removed_type.is_nil() {
257-
return remove_nil_and_not_false(source);
258-
}
259-
260-
match source {
261-
LuaType::Union(union) => {
262-
let mut types = union.get_types().to_vec();
263-
types.retain(|t| t != &removed_type);
264-
if types.len() == 1 {
265-
types.pop().unwrap()
266-
} else {
267-
LuaType::Union(LuaUnionType::new(types).into())
268-
}
269-
}
270-
LuaType::Nullable(inner) => {
271-
let inner = remove_type((*inner).clone(), removed_type);
272-
LuaType::Nullable(inner.into())
273-
}
274-
_ => source,
275-
}
276-
}

crates/emmylua_code_analysis/src/db_index/type/type_ops/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
mod union_type;
2+
mod remove_type;
3+
mod narrow_type;
24

35
use super::LuaType;
46

@@ -16,9 +18,8 @@ impl TypeOps {
1618
pub fn apply(&self, source: &LuaType, target: &LuaType) -> LuaType {
1719
match self {
1820
TypeOps::Union => union_type::union_type(source.clone(), target.clone()),
19-
// TypeOps::Remove => remove_type(source, target),
20-
// TypeOps::Narrow => narrow_down_type(source, target),
21-
_ => source.clone(),
21+
TypeOps::Remove => remove_type::remove_type(source.clone(), target.clone()),
22+
TypeOps::Narrow => narrow_type::narrow_down_type(source.clone(), target.clone()),
2223
}
2324
}
2425
}

0 commit comments

Comments
 (0)