1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
use rowan::{
ast::{AstNode, AstPtr},
TextRange,
};
use crate::{db::Word, syntax::latex, Db};
#[salsa::tracked]
pub struct Number {
pub name: Word,
pub text: Word,
}
impl Number {
pub(super) fn of_number(
db: &dyn Db,
node: latex::SyntaxNode,
results: &mut Vec<Self>,
) -> Option<()> {
let number = latex::LabelNumber::cast(node)?;
let name = number.name()?.key()?.to_string();
let text = number
.text()?
.syntax()
.descendants_with_tokens()
.filter_map(|element| element.into_node())
.find(|node| node.kind() == latex::TEXT || node.kind() == latex::MIXED_GROUP)?
.text()
.to_string();
results.push(Self::new(db, Word::new(db, name), Word::new(db, text)));
Some(())
}
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum Origin {
Definition(AstPtr<latex::LabelDefinition>),
Reference(AstPtr<latex::LabelReference>),
ReferenceRange(AstPtr<latex::LabelReferenceRange>),
}
impl Origin {
pub fn as_definition(&self) -> Option<&AstPtr<latex::LabelDefinition>> {
match self {
Self::Definition(ptr) => Some(ptr),
_ => None,
}
}
}
#[salsa::tracked]
pub struct Name {
pub origin: Origin,
pub name: Word,
pub range: TextRange,
}
impl Name {
pub(super) fn of_definition(
db: &dyn Db,
node: latex::SyntaxNode,
results: &mut Vec<Self>,
) -> Option<()> {
let label = latex::LabelDefinition::cast(node)?;
let name = label.name()?.key()?;
results.push(Self::new(
db,
Origin::Definition(AstPtr::new(&label)),
Word::new(db, name.to_string()),
latex::small_range(&name),
));
Some(())
}
pub(super) fn of_reference(
db: &dyn Db,
node: latex::SyntaxNode,
results: &mut Vec<Self>,
) -> Option<()> {
let label = latex::LabelReference::cast(node)?;
for name in label.name_list()?.keys() {
results.push(Self::new(
db,
Origin::Reference(AstPtr::new(&label)),
Word::new(db, name.to_string()),
latex::small_range(&name),
));
}
Some(())
}
pub(super) fn of_reference_range(
db: &dyn Db,
node: latex::SyntaxNode,
results: &mut Vec<Self>,
) -> Option<()> {
let label = latex::LabelReferenceRange::cast(node)?;
if let Some(name) = label.from().and_then(|name| name.key()) {
results.push(Self::new(
db,
Origin::ReferenceRange(AstPtr::new(&label)),
Word::new(db, name.to_string()),
latex::small_range(&name),
));
}
if let Some(name) = label.to().and_then(|name| name.key()) {
results.push(Self::new(
db,
Origin::ReferenceRange(AstPtr::new(&label)),
Word::new(db, name.to_string()),
latex::small_range(&name),
));
}
Some(())
}
}
|