Skip to content

Commit fbd05b1

Browse files
committed
attribute: 移除内嵌使用
1 parent a737ce9 commit fbd05b1

File tree

12 files changed

+111
-185
lines changed

12 files changed

+111
-185
lines changed

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

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use emmylua_parser::{
22
LuaAst, LuaAstNode, LuaDocTagAttributeUse, LuaDocType, LuaExpr, LuaKind, LuaLiteralExpr,
3-
LuaLiteralToken, LuaSyntaxKind, LuaSyntaxNode,
3+
LuaLiteralToken, LuaSyntaxKind, LuaSyntaxNode, LuaTokenKind,
44
};
55
use smol_str::SmolStr;
66

77
use crate::{
8-
LuaAttributeUse, LuaType,
8+
LuaAttributeUse, LuaSemanticDeclId, LuaType,
99
compilation::analyzer::doc::{
1010
DocAnalyzer,
1111
infer_type::infer_type,
@@ -18,13 +18,26 @@ pub fn analyze_tag_attribute_use(
1818
tag_use: LuaDocTagAttributeUse,
1919
) -> Option<()> {
2020
let owner = attribute_use_get_owner(analyzer, &tag_use);
21-
let owner_id = match get_owner_id(analyzer, owner, true) {
21+
let owner_id = match get_owner_id(analyzer, owner.clone(), true) {
2222
Some(id) => id,
2323
None => {
2424
report_orphan_tag(analyzer, &tag_use);
2525
return None;
2626
}
2727
};
28+
29+
if let Some(owner) = owner {
30+
match (owner, &owner_id) {
31+
(LuaAst::LuaDocTagParam(_), LuaSemanticDeclId::Signature(_)) => {
32+
return Some(());
33+
}
34+
(LuaAst::LuaDocTagReturn(_), LuaSemanticDeclId::Signature(_)) => {
35+
return Some(());
36+
}
37+
_ => {}
38+
}
39+
}
40+
2841
let attribute_uses = infer_attribute_uses(analyzer, tag_use)?;
2942
for attribute_use in attribute_uses {
3043
analyzer.db.get_property_index_mut().add_attribute_use(
@@ -107,35 +120,38 @@ fn infer_attribute_arg_type(expr: LuaLiteralExpr) -> LuaType {
107120
return LuaType::DocBooleanConst(bool_token.is_true());
108121
}
109122
LuaLiteralToken::Nil(_) => return LuaType::Nil,
110-
// todo
111123
LuaLiteralToken::Dots(_) => return LuaType::Any,
112124
LuaLiteralToken::Question(_) => return LuaType::Nil,
113125
}
114126
}
115127
LuaType::Unknown
116128
}
117129

118-
/// 特性的寻找所有者需要特殊处理
130+
/// 寻找特性的所有者
119131
fn attribute_use_get_owner(
120132
analyzer: &mut DocAnalyzer,
121133
attribute_use: &LuaDocTagAttributeUse,
122134
) -> Option<LuaAst> {
123-
// 针对 ---@field 特殊处理
124-
if let Some(attached_node) = attribute_find_doc_field(&attribute_use.syntax()) {
135+
if let Some(attached_node) = attribute_find_doc(&attribute_use.syntax()) {
125136
return LuaAst::cast(attached_node);
126137
}
127-
// 回退
128138
analyzer.comment.get_owner()
129139
}
130140

131-
fn attribute_find_doc_field(comment: &LuaSyntaxNode) -> Option<LuaSyntaxNode> {
132-
let mut next_sibling = comment.next_sibling();
141+
fn attribute_find_doc(comment: &LuaSyntaxNode) -> Option<LuaSyntaxNode> {
142+
let mut next_sibling = comment.next_sibling_or_token();
133143
loop {
134144
next_sibling.as_ref()?;
135145
if let Some(sibling) = &next_sibling {
136146
match sibling.kind() {
137-
LuaKind::Syntax(LuaSyntaxKind::DocTagField) => {
138-
return Some(sibling.clone());
147+
LuaKind::Syntax(
148+
LuaSyntaxKind::DocTagField
149+
| LuaSyntaxKind::DocTagParam
150+
| LuaSyntaxKind::DocTagReturn,
151+
) => {
152+
if let Some(node) = sibling.as_node() {
153+
return Some(node.clone());
154+
}
139155
}
140156
LuaKind::Syntax(LuaSyntaxKind::Comment) => {
141157
return None;
@@ -149,7 +165,50 @@ fn attribute_find_doc_field(comment: &LuaSyntaxNode) -> Option<LuaSyntaxNode> {
149165
}
150166
}
151167
}
152-
next_sibling = sibling.next_sibling();
168+
next_sibling = sibling.next_sibling_or_token();
153169
}
154170
}
155171
}
172+
173+
fn find_up_attribute(
174+
comment: &LuaSyntaxNode,
175+
result: &mut Vec<LuaDocTagAttributeUse>,
176+
stop_by_continue: bool,
177+
) -> Option<()> {
178+
let mut next_sibling = comment.prev_sibling_or_token();
179+
loop {
180+
next_sibling.as_ref()?;
181+
if let Some(sibling) = &next_sibling {
182+
match sibling.kind() {
183+
LuaKind::Syntax(LuaSyntaxKind::DocTagAttributeUse) => {
184+
if let Some(node) = sibling.as_node() {
185+
if let Some(node) = LuaDocTagAttributeUse::cast(node.clone()) {
186+
result.push(node);
187+
}
188+
}
189+
}
190+
// 某些情况下我们需要以 --- 为分割中断寻找
191+
LuaKind::Token(LuaTokenKind::TkDocContinue) => {
192+
if stop_by_continue {
193+
return None;
194+
}
195+
}
196+
LuaKind::Syntax(LuaSyntaxKind::DocDescription) => {}
197+
LuaKind::Syntax(_) => {
198+
return None;
199+
}
200+
_ => {}
201+
}
202+
next_sibling = sibling.prev_sibling_or_token();
203+
}
204+
}
205+
}
206+
207+
pub fn find_attach_attribute(ast: LuaAst) -> Option<Vec<LuaDocTagAttributeUse>> {
208+
if let LuaAst::LuaDocTagParam(param) = ast {
209+
let mut result = Vec::new();
210+
find_up_attribute(param.syntax(), &mut result, true);
211+
return Some(result);
212+
}
213+
None
214+
}

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

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use super::{
1111
DocAnalyzer, infer_type::infer_type, preprocess_description, tags::find_owner_closure,
1212
};
1313
use crate::GenericParam;
14-
use crate::compilation::analyzer::doc::attribute_tags::infer_attribute_uses;
1514
use crate::compilation::analyzer::doc::tags::report_orphan_tag;
1615
use crate::{
1716
LuaTypeCache, LuaTypeDeclId,
@@ -215,17 +214,12 @@ fn get_generic_params(
215214
} else {
216215
continue;
217216
};
218-
let attributes = if let Some(attribute_use) = param.get_tag_attribute_use() {
219-
infer_attribute_uses(analyzer, attribute_use)
220-
} else {
221-
None
222-
};
223217
let type_ref = param
224218
.get_type()
225219
.map(|type_ref| infer_type(analyzer, type_ref));
226220

227221
let is_variadic = param.is_variadic();
228-
params_result.push(GenericParam::new(name, type_ref, is_variadic, attributes));
222+
params_result.push(GenericParam::new(name, type_ref, is_variadic, None));
229223
}
230224

231225
params_result
@@ -360,20 +354,13 @@ pub fn analyze_func_generic(analyzer: &mut DocAnalyzer, tag: LuaDocTagGeneric) -
360354
.get_type()
361355
.map(|type_ref| infer_type(analyzer, type_ref));
362356

363-
let attributes = if let Some(attribute_use) = param.get_tag_attribute_use() {
364-
infer_attribute_uses(analyzer, attribute_use)
365-
} else {
366-
None
367-
};
368357
params_result.push(GenericParam::new(
369358
SmolStr::new(name.as_str()),
370359
type_ref.clone(),
371360
false,
372-
attributes.clone(),
361+
None,
373362
));
374-
param_info.push(Arc::new(LuaGenericParamInfo::new(
375-
name, type_ref, attributes,
376-
)));
363+
param_info.push(Arc::new(LuaGenericParamInfo::new(name, type_ref, None)));
377364
}
378365
}
379366

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

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ use super::{
1111
preprocess_description,
1212
tags::{find_owner_closure, get_owner_id_or_report},
1313
};
14-
use crate::compilation::analyzer::doc::{
15-
attribute_tags::infer_attribute_uses,
16-
tags::{find_owner_closure_or_report, get_owner_id, report_orphan_tag},
17-
};
1814
use crate::{
1915
InFiled, InferFailReason, LuaOperatorMetaMethod, LuaTypeCache, LuaTypeOwner, OperatorFunction,
2016
SignatureReturnStatus, TypeOps,
@@ -24,6 +20,13 @@ use crate::{
2420
LuaSignatureId, LuaType,
2521
},
2622
};
23+
use crate::{
24+
LuaAttributeUse,
25+
compilation::analyzer::doc::{
26+
attribute_tags::{find_attach_attribute, infer_attribute_uses},
27+
tags::{find_owner_closure_or_report, get_owner_id, report_orphan_tag},
28+
},
29+
};
2730

2831
pub fn analyze_type(analyzer: &mut DocAnalyzer, tag: LuaDocTagType) -> Option<()> {
2932
let description = tag
@@ -188,11 +191,15 @@ pub fn analyze_param(analyzer: &mut DocAnalyzer, tag: LuaDocTagParam) -> Option<
188191
if let Some(closure) = find_owner_closure(analyzer) {
189192
let id = LuaSignatureId::from_closure(analyzer.file_id, &closure);
190193
// 绑定`attribute`标记
191-
let attributes = if let Some(attribute_use) = tag.get_tag_attribute_use() {
192-
infer_attribute_uses(analyzer, attribute_use)
193-
} else {
194-
None
195-
};
194+
let attributes =
195+
find_attach_attribute(LuaAst::LuaDocTagParam(tag)).and_then(|tag_attribute_uses| {
196+
let result: Vec<LuaAttributeUse> = tag_attribute_uses
197+
.into_iter()
198+
.filter_map(|tag_use| infer_attribute_uses(analyzer, tag_use))
199+
.flatten()
200+
.collect();
201+
(!result.is_empty()).then_some(result)
202+
});
196203

197204
let signature = analyzer.db.get_signature_index_mut().get_or_create(id);
198205
let param_info = LuaDocParamInfo {
@@ -235,20 +242,15 @@ pub fn analyze_return(analyzer: &mut DocAnalyzer, tag: LuaDocTagReturn) -> Optio
235242
if let Some(closure) = find_owner_closure_or_report(analyzer, &tag) {
236243
let signature_id = LuaSignatureId::from_closure(analyzer.file_id, &closure);
237244
let returns = tag.get_info_list();
238-
for (doc_type, name_token, attribute_use_tag) in returns {
245+
for (doc_type, name_token) in returns {
239246
let name = name_token.map(|name| name.get_name_text().to_string());
240247

241248
let type_ref = infer_type(analyzer, doc_type);
242-
let attributes = if let Some(attribute) = attribute_use_tag {
243-
infer_attribute_uses(analyzer, attribute)
244-
} else {
245-
None
246-
};
247249
let return_info = LuaDocReturnInfo {
248250
name,
249251
type_ref,
250252
description: description.clone(),
251-
attributes,
253+
attributes: None,
252254
};
253255

254256
let signature = analyzer

crates/emmylua_code_analysis/src/compilation/test/annotation_test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ mod test {
131131
ws.def(
132132
r#"
133133
---@generic T
134-
---@param [constructor("__init")] name `T`
134+
---@[constructor("__init")]
135+
---@param name `T`
135136
---@return T
136137
function meta(name)
137138
end

crates/emmylua_code_analysis/src/compilation/test/attribute_test.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ mod test {
1616
(
1717
"meta.lua",
1818
r#"
19-
---@attribute constructor(name: string, strip_self: boolean?, return_self: boolean?)
19+
---@attribute constructor(name: string, root_class: string?, strip_self: boolean?, return_self: boolean?)
2020
2121
---@generic T
22-
---@param [constructor("__init")] name `T`
22+
---@[constructor("__init")]
23+
---@param name `T`
2324
---@return T
2425
function meta(name)
2526
end

crates/emmylua_code_analysis/src/compilation/test/overload_test.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ mod test {
2828
}
2929

3030
#[test]
31-
fn test_class_default_call() {
32-
let mut ws = VirtualWorkspace::new();
31+
fn test_class_default_constructor() {
32+
let mut ws = VirtualWorkspace::new_with_init_std_lib();
3333
ws.def(
3434
r#"
35-
---@attribute constructor(name: string, strip_self: boolean?, return_self: boolean?)
3635
3736
---@generic T
38-
---@param [constructor("__init")] name `T`
37+
---@[constructor("__init")]
38+
---@param name `T`
3939
---@return T
4040
function meta(name)
4141
end

crates/emmylua_ls/src/handlers/semantic_token/build_semantic_tokens.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ fn build_node_semantic_token(
373373
}
374374
LuaAst::LuaDocTagReturn(doc_return) => {
375375
let type_name_list = doc_return.get_info_list();
376-
for (_, name, _) in type_name_list {
376+
for (_, name) in type_name_list {
377377
if let Some(name) = name {
378378
builder.push(name.syntax(), SemanticTokenType::VARIABLE);
379379
}

crates/emmylua_ls/src/handlers/test/inlay_hint_test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ mod tests {
140140
ws.def(
141141
r#"
142142
---@generic T
143-
---@param [constructor("__init")] name `T`
143+
---@[constructor("__init")]
144+
---@param name `T`
144145
---@return T
145146
function meta(name)
146147
end

crates/emmylua_parser/src/grammar/doc/tag.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,6 @@ fn parse_generic_decl_list(p: &mut LuaDocParser, allow_angle_brackets: bool) ->
142142
// A ... : type
143143
fn parse_generic_param(p: &mut LuaDocParser) -> DocParseResult {
144144
let m = p.mark(LuaSyntaxKind::DocGenericParameter);
145-
// 允许泛型附带特性
146-
if p.current_token() == LuaTokenKind::TkLeftBracket {
147-
parse_tag_attribute_use(p, false)?;
148-
}
149145
expect_token(p, LuaTokenKind::TkName)?;
150146
if p.current_token() == LuaTokenKind::TkDots {
151147
p.bump();
@@ -311,9 +307,6 @@ fn parse_tag_param(p: &mut LuaDocParser) -> DocParseResult {
311307
p.set_state(LuaDocLexerState::Normal);
312308
let m = p.mark(LuaSyntaxKind::DocTagParam);
313309
p.bump();
314-
if p.current_token() == LuaTokenKind::TkLeftBracket {
315-
parse_tag_attribute_use(p, false)?;
316-
}
317310
if matches!(
318311
p.current_token(),
319312
LuaTokenKind::TkName | LuaTokenKind::TkDots
@@ -341,24 +334,17 @@ fn parse_tag_param(p: &mut LuaDocParser) -> DocParseResult {
341334
// ---@return number
342335
// ---@return number, string
343336
// ---@return number <name> , this just compact luals
344-
// ---@return [attribute] number
345337
fn parse_tag_return(p: &mut LuaDocParser) -> DocParseResult {
346338
p.set_state(LuaDocLexerState::Normal);
347339
let m = p.mark(LuaSyntaxKind::DocTagReturn);
348340
p.bump();
349-
if p.current_token() == LuaTokenKind::TkLeftBracket {
350-
parse_tag_attribute_use(p, false)?;
351-
}
352341

353342
parse_type(p)?;
354343

355344
if_token_bump(p, LuaTokenKind::TkName);
356345

357346
while p.current_token() == LuaTokenKind::TkComma {
358347
p.bump();
359-
if p.current_token() == LuaTokenKind::TkLeftBracket {
360-
parse_tag_attribute_use(p, false)?;
361-
}
362348
parse_type(p)?;
363349
if_token_bump(p, LuaTokenKind::TkName);
364350
}
@@ -704,9 +690,9 @@ fn parse_type_attribute(p: &mut LuaDocParser) -> DocParseResult {
704690
Ok(m.complete(p))
705691
}
706692

707-
// ---@[a(arg1, arg2, ...)]
708-
// ---@[a]
709-
// ---@[a, b, ...]
693+
// ---@[attribute(arg1, arg2, ...)]
694+
// ---@[attribute]
695+
// ---@[attribute1, attribute2, ...]
710696
// ---@generic [attribute] T
711697
pub fn parse_tag_attribute_use(p: &mut LuaDocParser, allow_description: bool) -> DocParseResult {
712698
let m = p.mark(LuaSyntaxKind::DocTagAttributeUse);

0 commit comments

Comments
 (0)