1use crate::{
4 Error,
5 backend::{Backend, Match},
6};
7
8mod predicate;
9
10pub use predicate::Predicate;
11
12pub struct Query<Q> {
14 pub raw: Q,
16 pub capture_names: Vec<String>,
18 pub patterns: Vec<Pattern>,
20 pub metadata: Vec<Metadata>,
22}
23
24#[derive(Clone, Copy, Default)]
26pub struct Metadata {
27 pub ancestors: usize,
29 pub depth: bool,
31 pub parent: bool,
33 pub children: bool,
35}
36
37pub struct Pattern {
39 pub properties: Vec<Property>,
41 pub predicates: Vec<Predicate>,
43 pub local: Option<bool>,
45 pub priority: i32,
47 offsets: bool,
48}
49
50impl Pattern {
51 pub fn new(
57 properties: Vec<Property>,
58 predicates: Vec<(String, Vec<Argument>)>,
59 local: Option<bool>,
60 ) -> Result<Self, Error> {
61 let predicates = predicates
62 .into_iter()
63 .map(|(operator, arguments)| Predicate::compile(&operator, arguments))
64 .collect::<Result<Vec<_>, _>>()?;
65 let priority = properties
66 .iter()
67 .find(|property| property.key == "priority")
68 .and_then(|property| property.value.as_deref())
69 .and_then(|value| value.parse().ok())
70 .unwrap_or(100);
71 let offsets = predicates
72 .iter()
73 .any(|predicate| matches!(predicate, Predicate::Offset { .. }));
74
75 Ok(Self {
76 properties,
77 predicates,
78 local,
79 priority,
80 offsets,
81 })
82 }
83
84 pub fn property(&self, key: &str) -> Option<&Property> {
86 self.properties.iter().find(|property| property.key == key)
87 }
88
89 pub fn value(&self, key: &str) -> Option<&str> {
91 self.property(key)
92 .and_then(|property| property.value.as_deref())
93 }
94}
95
96pub struct Property {
98 pub key: String,
100 pub value: Option<String>,
102 pub capture: Option<u32>,
104}
105
106#[derive(Debug)]
108pub enum Argument {
109 Capture(u32),
111 String(String),
113}
114
115impl<Q> Query<Q> {
116 pub fn new(raw: Q, capture_names: Vec<String>, patterns: Vec<Pattern>) -> Self {
118 let mut metadata = vec![Metadata::default(); capture_names.len()];
119
120 for (name, metadata) in capture_names.iter().zip(&mut metadata) {
121 metadata.depth = matches!(name.as_str(), "local.scope" | "rainbow.scope");
122 metadata.parent = name == "rainbow.bracket";
123 metadata.children = name == "injection.content"
124 && patterns
125 .iter()
126 .any(|pattern| pattern.property("injection.include-children").is_none());
127 }
128
129 for pattern in &patterns {
130 for predicate in &pattern.predicates {
131 if let Predicate::Ancestor {
132 capture, parent, ..
133 } = predicate
134 {
135 let required = if *parent { 1 } else { usize::MAX };
136 metadata[*capture as usize].ancestors =
137 metadata[*capture as usize].ancestors.max(required);
138 }
139 }
140 }
141
142 Self {
143 raw,
144 capture_names,
145 patterns,
146 metadata,
147 }
148 }
149
150 pub fn matches<B: Backend<Query = Q>>(
156 &self,
157 backend: &mut B,
158 tree: &B::Tree,
159 source: &str,
160 ) -> Result<Vec<Match>, Error> {
161 if self.patterns.is_empty() {
162 return Ok(Vec::new());
163 }
164 self.filtered(backend.matches(self, tree, source)?, source)
165 }
166
167 pub fn filtered(&self, mut matches: Vec<Match>, source: &str) -> Result<Vec<Match>, Error> {
180 let mut accepted = 0;
181
182 for index in 0..matches.len() {
183 let matched = &mut matches[index];
184 for capture in &matched.captures {
185 if source.get(capture.node.range.clone()).is_none() {
186 return Err(Error::InvalidRange(capture.node.range.clone()));
187 }
188 }
189
190 let pattern = &self.patterns[matched.pattern];
191
192 if !pattern
193 .predicates
194 .iter()
195 .all(|predicate| predicate.accepts(matched, source))
196 {
197 continue;
198 }
199
200 if pattern.offsets {
201 for predicate in &pattern.predicates {
202 predicate.apply(matched, source)?;
203 }
204
205 for capture in &matched.captures {
206 if source.get(capture.node.range.clone()).is_none() {
207 return Err(Error::InvalidRange(capture.node.range.clone()));
208 }
209 }
210 }
211
212 matches.swap(accepted, index);
213 accepted += 1;
214 }
215
216 matches.truncate(accepted);
217 Ok(matches)
218 }
219}