Skip to content

Commit a3e6cae

Browse files
authored
Merge pull request #118 from CppCXY/refactor-union
refactor union
2 parents 0d2480e + 73421f9 commit a3e6cae

File tree

24 files changed

+395
-398
lines changed

24 files changed

+395
-398
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
`FIX` Fix select function and add std.Select type
2121

22+
`CHG` Refactor Union type
23+
2224
# 0.5.1
2325

2426
`FIX` Fix issue `emmylua_ls` might not exit in unix.

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ members = [
88
[workspace.dependencies]
99
# local
1010
emmylua_code_analysis = { path = "crates/emmylua_code_analysis", version = "0.5.0" }
11-
emmylua_parser = { path = "crates/emmylua_parser", version = "0.9.6" }
11+
emmylua_parser = { path = "crates/emmylua_parser", version = "0.10.0" }
1212
emmylua_diagnostic_macro = { path = "crates/emmylua_diagnostic_macro", version = "0.4.0" }
1313

1414
# external

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

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::sync::Arc;
22

33
use emmylua_parser::{
4-
LuaAst, LuaAstNode, LuaDocBinaryType, LuaDocFuncType, LuaDocGenericType, LuaDocObjectFieldKey,
5-
LuaDocObjectType, LuaDocStrTplType, LuaDocType, LuaDocUnaryType, LuaDocVariadicType,
6-
LuaLiteralToken, LuaSyntaxKind, LuaTypeBinaryOperator, LuaTypeUnaryOperator, LuaVarExpr,
4+
LuaAst, LuaAstNode, LuaDocBinaryType, LuaDocDetailOwner, LuaDocFuncType, LuaDocGenericType,
5+
LuaDocMultiLineUnionType, LuaDocObjectFieldKey, LuaDocObjectType, LuaDocStrTplType, LuaDocType,
6+
LuaDocUnaryType, LuaDocVariadicType, LuaLiteralToken, LuaSyntaxKind, LuaTypeBinaryOperator,
7+
LuaTypeUnaryOperator, LuaVarExpr,
78
};
89
use rowan::TextRange;
910
use smol_str::SmolStr;
@@ -13,10 +14,10 @@ use crate::{
1314
AnalyzeError, LuaAliasCallType, LuaFunctionType, LuaGenericType, LuaIndexAccessKey,
1415
LuaIntersectionType, LuaObjectType, LuaStringTplType, LuaTupleType, LuaType, LuaUnionType,
1516
},
16-
DiagnosticCode, GenericTpl, LuaAliasCallKind, TypeOps,
17+
DiagnosticCode, GenericTpl, LuaAliasCallKind, LuaMultiLineUnion, TypeOps,
1718
};
1819

19-
use super::DocAnalyzer;
20+
use super::{preprocess_description, DocAnalyzer};
2021

2122
pub fn infer_type(analyzer: &mut DocAnalyzer, node: LuaDocType) -> LuaType {
2223
match node {
@@ -103,6 +104,9 @@ pub fn infer_type(analyzer: &mut DocAnalyzer, node: LuaDocType) -> LuaType {
103104
LuaDocType::Variadic(variadic_type) => {
104105
return infer_variadic_type(analyzer, variadic_type).unwrap_or(LuaType::Unknown);
105106
}
107+
LuaDocType::MultiLineUnion(multi_union) => {
108+
return infer_multi_line_union_type(analyzer, multi_union);
109+
}
106110
_ => {} // LuaDocType::Conditional(lua_doc_conditional_type) => todo!(),
107111
}
108112
LuaType::Unknown
@@ -482,3 +486,35 @@ fn infer_variadic_type(
482486

483487
Some(LuaType::Variadic(base.into()))
484488
}
489+
490+
fn infer_multi_line_union_type(
491+
analyzer: &mut DocAnalyzer,
492+
multi_union: LuaDocMultiLineUnionType,
493+
) -> LuaType {
494+
let mut union_members = Vec::new();
495+
for field in multi_union.get_fields() {
496+
let alias_member_type = if let Some(field_type) = field.get_type() {
497+
let type_ref = infer_type(analyzer, field_type);
498+
if type_ref.is_unknown() {
499+
continue;
500+
}
501+
type_ref
502+
} else {
503+
continue;
504+
};
505+
506+
let description = if let Some(description_text) = field.get_detail_text() {
507+
if !description_text.is_empty() {
508+
Some(preprocess_description(&description_text))
509+
} else {
510+
None
511+
}
512+
} else {
513+
None
514+
};
515+
516+
union_members.push((alias_member_type, description));
517+
}
518+
519+
LuaType::MultiLineUnion(LuaMultiLineUnion::new(union_members).into())
520+
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,7 @@ pub fn preprocess_description(mut description: &str) -> String {
119119
}
120120
result.push('\n');
121121
}
122-
result
122+
123+
// trim end
124+
result.trim_end().to_string()
123125
}

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

Lines changed: 10 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use std::collections::HashMap;
22

33
use emmylua_parser::{
44
LuaAssignStat, LuaAst, LuaAstNode, LuaAstToken, LuaCommentOwner, LuaDocDescriptionOwner,
5-
LuaDocDetailOwner, LuaDocGenericDeclList, LuaDocTagAlias, LuaDocTagClass, LuaDocTagEnum,
6-
LuaDocTagGeneric, LuaFuncStat, LuaLocalName, LuaLocalStat, LuaNameExpr, LuaSyntaxId,
7-
LuaSyntaxKind, LuaTokenKind, LuaVarExpr,
5+
LuaDocGenericDeclList, LuaDocTagAlias, LuaDocTagClass, LuaDocTagEnum, LuaDocTagGeneric,
6+
LuaFuncStat, LuaLocalName, LuaLocalStat, LuaNameExpr, LuaSyntaxId, LuaSyntaxKind, LuaTokenKind,
7+
LuaVarExpr,
88
};
99
use rowan::TextRange;
1010

1111
use crate::db_index::{
12-
LuaDeclId, LuaDeclTypeKind, LuaMember, LuaMemberId, LuaMemberKey, LuaMemberOwner,
13-
LuaPropertyOwnerId, LuaSignatureId, LuaType,
12+
LuaDeclId, LuaDeclTypeKind, LuaMemberId, LuaPropertyOwnerId, LuaSignatureId, LuaType,
1413
};
1514

1615
use super::{
@@ -159,57 +158,14 @@ pub fn analyze_alias(analyzer: &mut DocAnalyzer, tag: LuaDocTagAlias) -> Option<
159158
.add_generic_scope(vec![range], params_index, false);
160159
}
161160

162-
if let Some(origin_type) = tag.get_type() {
163-
let replace_type = infer_type(analyzer, origin_type);
164-
if replace_type.is_unknown() {
165-
return None;
166-
}
167-
let alias = analyzer
168-
.db
169-
.get_type_index_mut()
170-
.get_type_decl_mut(&alias_decl_id)?;
171-
alias.add_alias_origin(replace_type);
172-
} else if let Some(field_list) = tag.get_alias_fields() {
173-
let mut union_members = Vec::new();
174-
for (i, field) in field_list.get_fields().enumerate() {
175-
let alias_member_type = if let Some(field_type) = field.get_type() {
176-
let type_ref = infer_type(analyzer, field_type);
177-
if type_ref.is_unknown() {
178-
continue;
179-
}
180-
type_ref
181-
} else {
182-
continue;
183-
};
161+
let origin_type = infer_type(analyzer, tag.get_type()?);
184162

185-
let member = LuaMember::new(
186-
LuaMemberOwner::Type(alias_decl_id.clone()),
187-
LuaMemberKey::Integer(i as i64),
188-
file_id,
189-
field.get_syntax_id(),
190-
Some(alias_member_type),
191-
);
192-
let member_id = analyzer.db.get_member_index_mut().add_member(member);
193-
union_members.push(member_id);
194-
if let Some(description_text) = field.get_detail_text() {
195-
if description_text.is_empty() {
196-
continue;
197-
}
198-
let description_text = preprocess_description(&description_text);
199-
analyzer.db.get_property_index_mut().add_description(
200-
file_id,
201-
LuaPropertyOwnerId::Member(member_id),
202-
description_text,
203-
);
204-
}
205-
}
163+
let alias = analyzer
164+
.db
165+
.get_type_index_mut()
166+
.get_type_decl_mut(&alias_decl_id)?;
206167

207-
let alias = analyzer
208-
.db
209-
.get_type_index_mut()
210-
.get_type_decl_mut(&alias_decl_id)?;
211-
alias.add_alias_union_members(union_members);
212-
}
168+
alias.add_alias_origin(origin_type);
213169

214170
let description_text = tag.get_description()?.get_description_text();
215171
if description_text.is_empty() {

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

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{
55
LuaUnionType, TypeSubstitutor,
66
};
77

8+
use super::LuaMultiLineUnion;
9+
810
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
911
pub enum RenderLevel {
1012
Detailed,
@@ -83,6 +85,9 @@ pub fn humanize_type(db: &DbIndex, ty: &LuaType, level: RenderLevel) -> String {
8385
LuaType::Signature(signature_id) => humanize_signature_type(db, signature_id, level),
8486
LuaType::Namespace(ns) => format!("{{ {} }}", ns),
8587
LuaType::Variadic(inner) => format!("{}...", humanize_type(db, inner, level.next_level())),
88+
LuaType::MultiLineUnion(multi_union) => {
89+
humanize_multi_line_union_type(db, multi_union, level)
90+
}
8691
_ => "unknown".to_string(),
8792
}
8893
}
@@ -97,8 +102,7 @@ fn humanize_def_type(db: &DbIndex, id: &LuaTypeDeclId, level: RenderLevel) -> St
97102
let full_name = type_decl.get_full_name();
98103
let generic = db.get_type_index().get_generic_params(id);
99104
if generic.is_none() {
100-
return humanize_simple_type(db, id, &full_name, level)
101-
.unwrap_or(full_name.to_string());
105+
return humanize_simple_type(db, id, &full_name, level).unwrap_or(full_name.to_string());
102106
}
103107

104108
let generic_names = generic
@@ -181,6 +185,51 @@ fn humanize_union_type(db: &DbIndex, union: &LuaUnionType, level: RenderLevel) -
181185
format!("({}{})", type_str, dots)
182186
}
183187

188+
fn humanize_multi_line_union_type(
189+
db: &DbIndex,
190+
multi_union: &LuaMultiLineUnion,
191+
level: RenderLevel,
192+
) -> String {
193+
let members = multi_union.get_unions();
194+
let num = match level {
195+
RenderLevel::Detailed => 10,
196+
RenderLevel::Simple => 8,
197+
RenderLevel::Normal => 4,
198+
RenderLevel::Brief => 2,
199+
RenderLevel::Minimal => {
200+
return "union<...>".to_string();
201+
}
202+
};
203+
let dots = if members.len() > num { "..." } else { "" };
204+
205+
let type_str = members
206+
.iter()
207+
.take(num)
208+
.map(|(ty, _)| humanize_type(db, ty, level.next_level()))
209+
.collect::<Vec<_>>()
210+
.join("|");
211+
212+
let mut text = format!("({}{})", type_str, dots);
213+
if level != RenderLevel::Detailed {
214+
return text;
215+
}
216+
217+
text.push_str("\n");
218+
for (typ, description) in members {
219+
let type_humanize_text = humanize_type(db, &typ, RenderLevel::Minimal);
220+
if let Some(description) = description {
221+
text.push_str(&format!(
222+
" | {} --{}\n",
223+
type_humanize_text, description
224+
));
225+
} else {
226+
text.push_str(&format!(" | {}\n", type_humanize_text));
227+
}
228+
}
229+
230+
text
231+
}
232+
184233
fn humanize_tuple_type(db: &DbIndex, tuple: &LuaTupleType, level: RenderLevel) -> String {
185234
let types = tuple.get_types();
186235
let num = match level {
@@ -371,7 +420,7 @@ fn humanize_generic_type(db: &DbIndex, generic: &LuaGenericType, level: RenderLe
371420
let simple_name = type_decl.get_name();
372421
match level {
373422
RenderLevel::Brief => {
374-
if type_decl.is_alias_replace() {
423+
if type_decl.is_alias() {
375424
let params = generic
376425
.get_params()
377426
.iter()
@@ -627,9 +676,13 @@ fn build_table_member_string(
627676
) -> String {
628677
let (member_value, separator) = if level == RenderLevel::Detailed {
629678
let val = match ty {
630-
LuaType::IntegerConst(_) | LuaType::DocIntegerConst(_) => format!("integer = {member_value_string}"),
679+
LuaType::IntegerConst(_) | LuaType::DocIntegerConst(_) => {
680+
format!("integer = {member_value_string}")
681+
}
631682
LuaType::FloatConst(_) => format!("number = {member_value_string}"),
632-
LuaType::StringConst(_) | LuaType::DocStringConst(_) => format!("string = {member_value_string}"),
683+
LuaType::StringConst(_) | LuaType::DocStringConst(_) => {
684+
format!("string = {member_value_string}")
685+
}
633686
LuaType::BooleanConst(_) => format!("boolean = {member_value_string}"),
634687
_ => member_value_string,
635688
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl LuaTypeIndex {
9898
}
9999

100100
let location = LuaDeclLocation { file_id, range };
101-
decls.defined_locations.push(location);
101+
decls.locations.push(location);
102102
} else {
103103
let just_name = if let Some(i) = basic_name.rfind('.') {
104104
basic_name[i + 1..].to_string()

0 commit comments

Comments
 (0)