feat: re-identify ref colon syntax and perform IDE operations (#1735)

* test: add cases about ref syntax

* feat: re-identify ref syntax and perform IDE operations
This commit is contained in:
Myriad-Dreamin 2025-05-03 19:03:07 +08:00 committed by GitHub
parent e4ed9defb1
commit 8f0d9c25d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 170 additions and 19 deletions

View file

@ -255,7 +255,7 @@ impl<'a> CompletionCursor<'a> {
// @identifier
// ^ from
let is_from_ref = matches!(self.syntax, Some(SyntaxClass::Ref(..)))
let is_from_ref = matches!(self.syntax, Some(SyntaxClass::Ref { .. }))
&& self.leaf.offset() + 1 == self.from;
if is_from_ref {
return Some(SelectedNode::Ref(self.leaf.clone()));
@ -287,6 +287,7 @@ impl<'a> CompletionCursor<'a> {
| SyntaxContext::VarAccess(..)
| SyntaxContext::Paren { .. }
| SyntaxContext::Label { .. }
| SyntaxContext::Ref { .. }
| SyntaxContext::Normal(..),
)
| None => {}
@ -641,8 +642,11 @@ impl CompletionPair<'_, '_, '_> {
return Some(());
}
// todo: complete reference by type
Some(SyntaxContext::Normal(node)) if (matches!(node.kind(), SyntaxKind::Ref)) => {
self.cursor.from = self.cursor.leaf.offset() + 1;
Some(SyntaxContext::Ref {
node,
suffix_colon: _,
}) => {
self.cursor.from = node.offset() + 1;
self.ref_completions();
return Some(());
}

View file

@ -95,11 +95,14 @@ pub fn definition(
DefResolver::new(ctx, source)?.of_span(path.span())
}
SyntaxClass::Label {
node: r,
node,
is_error: false,
}
| SyntaxClass::Ref(r) => {
let ref_expr: ast::Expr = r.cast()?;
| SyntaxClass::Ref {
node,
suffix_colon: false,
} => {
let ref_expr: ast::Expr = node.cast()?;
let name = match ref_expr {
ast::Expr::Ref(r) => r.target(),
ast::Expr::Label(r) => r.get(),
@ -114,6 +117,10 @@ pub fn definition(
node: _,
is_error: true,
}
| SyntaxClass::Ref {
node: _,
suffix_colon: true,
}
| SyntaxClass::Normal(..) => None,
}
}

View file

@ -319,12 +319,20 @@ impl<'a> PostTypeChecker<'a> {
| SyntaxContext::VarAccess(VarClass::FieldAccess(node))
| SyntaxContext::VarAccess(VarClass::DotAccess(node))
| SyntaxContext::Label { node, .. }
| SyntaxContext::Ref { node, .. }
| SyntaxContext::Normal(node) => {
let label_ty = matches!(cursor, SyntaxContext::Label { is_error: true, .. })
.then_some(Ty::Builtin(BuiltinTy::Label));
let label_or_ref_ty = match cursor {
SyntaxContext::Label { is_error: true, .. } => {
Some(Ty::Builtin(BuiltinTy::Label))
}
SyntaxContext::Ref {
suffix_colon: true, ..
} => Some(Ty::Builtin(BuiltinTy::RefLabel)),
_ => None,
};
let ty = self.check_or(node, context_ty);
crate::log_debug_ct!("post check target normal: {ty:?} {label_ty:?}");
ty.or(label_ty)
crate::log_debug_ct!("post check target normal: {ty:?} {label_or_ref_ty:?}");
ty.or(label_or_ref_ty)
}
}
}

View file

@ -32,6 +32,27 @@ input_file: crates/tinymist-query/src/fixtures/completion/ref_half_colon2.typ
},
{
"isIncomplete": false,
"items": []
"items": [
{
"kind": 18,
"label": "sec:it",
"labelDetails": {
"description": "H"
},
"textEdit": {
"newText": "sec:it",
"range": {
"end": {
"character": 5,
"line": 13
},
"start": {
"character": 1,
"line": 13
}
}
}
}
]
}
]

View file

@ -47,8 +47,17 @@ pub(crate) fn find_references(
) -> Option<Vec<LspLocation>> {
let finding_label = match syntax {
SyntaxClass::VarAccess(..) | SyntaxClass::Callee(..) => false,
SyntaxClass::Label { .. } | SyntaxClass::Ref(..) => true,
SyntaxClass::ImportPath(..) | SyntaxClass::IncludePath(..) | SyntaxClass::Normal(..) => {
SyntaxClass::Label { .. }
| SyntaxClass::Ref {
suffix_colon: false,
..
} => true,
SyntaxClass::ImportPath(..)
| SyntaxClass::IncludePath(..)
| SyntaxClass::Ref {
suffix_colon: true, ..
}
| SyntaxClass::Normal(..) => {
return None;
}
};