diff options
Diffstat (limited to 'crates/ide/src/syntax_highlighting')
9 files changed, 213 insertions, 232 deletions
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index e921784bf..b586dcc17 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! Computes color for a single element. | 1 | //! Computes color for a single element. |
2 | 2 | ||
3 | use hir::{AsAssocItem, AssocItemContainer, Semantics, VariantDef}; | 3 | use hir::{AsAssocItem, Semantics}; |
4 | use ide_db::{ | 4 | use ide_db::{ |
5 | defs::{Definition, NameClass, NameRefClass}, | 5 | defs::{Definition, NameClass, NameRefClass}, |
6 | RootDatabase, SymbolKind, | 6 | RootDatabase, SymbolKind, |
@@ -12,7 +12,10 @@ use syntax::{ | |||
12 | SyntaxNode, SyntaxToken, T, | 12 | SyntaxNode, SyntaxToken, T, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | use crate::{syntax_highlighting::tags::HlPunct, Highlight, HlMod, HlTag}; | 15 | use crate::{ |
16 | syntax_highlighting::tags::{HlOperator, HlPunct}, | ||
17 | Highlight, HlMod, HlTag, | ||
18 | }; | ||
16 | 19 | ||
17 | pub(super) fn element( | 20 | pub(super) fn element( |
18 | sema: &Semantics<RootDatabase>, | 21 | sema: &Semantics<RootDatabase>, |
@@ -42,28 +45,26 @@ pub(super) fn element( | |||
42 | }; | 45 | }; |
43 | 46 | ||
44 | match name_kind { | 47 | match name_kind { |
45 | Some(NameClass::ExternCrate(_)) => HlTag::Symbol(SymbolKind::Module).into(), | 48 | Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(), |
46 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | 49 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, |
47 | Some(NameClass::ConstReference(def)) => highlight_def(db, def), | 50 | Some(NameClass::ConstReference(def)) => highlight_def(db, def), |
48 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { | 51 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { |
49 | let mut h = HlTag::Symbol(SymbolKind::Field).into(); | 52 | let mut h = HlTag::Symbol(SymbolKind::Field).into(); |
50 | if let Definition::Field(field) = field_ref { | 53 | if let Definition::Field(field) = field_ref { |
51 | if let VariantDef::Union(_) = field.parent_def(db) { | 54 | if let hir::VariantDef::Union(_) = field.parent_def(db) { |
52 | h |= HlMod::Unsafe; | 55 | h |= HlMod::Unsafe; |
53 | } | 56 | } |
54 | } | 57 | } |
55 | |||
56 | h | 58 | h |
57 | } | 59 | } |
58 | None => highlight_name_by_syntax(name) | HlMod::Definition, | 60 | None => highlight_name_by_syntax(name) | HlMod::Definition, |
59 | } | 61 | } |
60 | } | 62 | } |
61 | |||
62 | // Highlight references like the definitions they resolve to | 63 | // Highlight references like the definitions they resolve to |
63 | NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { | 64 | NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { |
64 | // even though we track whether we are in an attribute or not we still need this special case | 65 | // even though we track whether we are in an attribute or not we still need this special case |
65 | // as otherwise we would emit unresolved references for name refs inside attributes | 66 | // as otherwise we would emit unresolved references for name refs inside attributes |
66 | Highlight::from(HlTag::Symbol(SymbolKind::Function)) | 67 | SymbolKind::Function.into() |
67 | } | 68 | } |
68 | NAME_REF => { | 69 | NAME_REF => { |
69 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 70 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
@@ -71,7 +72,7 @@ pub(super) fn element( | |||
71 | let is_self = name_ref.self_token().is_some(); | 72 | let is_self = name_ref.self_token().is_some(); |
72 | let h = match NameRefClass::classify(sema, &name_ref) { | 73 | let h = match NameRefClass::classify(sema, &name_ref) { |
73 | Some(name_kind) => match name_kind { | 74 | Some(name_kind) => match name_kind { |
74 | NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(), | 75 | NameRefClass::ExternCrate(_) => SymbolKind::Module.into(), |
75 | NameRefClass::Definition(def) => { | 76 | NameRefClass::Definition(def) => { |
76 | if let Definition::Local(local) = &def { | 77 | if let Definition::Local(local) = &def { |
77 | if let Some(name) = local.name(db) { | 78 | if let Some(name) = local.name(db) { |
@@ -92,7 +93,7 @@ pub(super) fn element( | |||
92 | if let Some(parent) = name_ref.syntax().parent() { | 93 | if let Some(parent) = name_ref.syntax().parent() { |
93 | if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) { | 94 | if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) { |
94 | if let Definition::Field(field) = def { | 95 | if let Definition::Field(field) = def { |
95 | if let VariantDef::Union(_) = field.parent_def(db) { | 96 | if let hir::VariantDef::Union(_) = field.parent_def(db) { |
96 | h |= HlMod::Unsafe; | 97 | h |= HlMod::Unsafe; |
97 | } | 98 | } |
98 | } | 99 | } |
@@ -101,9 +102,7 @@ pub(super) fn element( | |||
101 | 102 | ||
102 | h | 103 | h |
103 | } | 104 | } |
104 | NameRefClass::FieldShorthand { .. } => { | 105 | NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(), |
105 | HlTag::Symbol(SymbolKind::Field).into() | ||
106 | } | ||
107 | }, | 106 | }, |
108 | None if syntactic_name_ref_highlighting => { | 107 | None if syntactic_name_ref_highlighting => { |
109 | highlight_name_ref_by_syntax(name_ref, sema) | 108 | highlight_name_ref_by_syntax(name_ref, sema) |
@@ -111,7 +110,7 @@ pub(super) fn element( | |||
111 | None => HlTag::UnresolvedReference.into(), | 110 | None => HlTag::UnresolvedReference.into(), |
112 | }; | 111 | }; |
113 | if h.tag == HlTag::Symbol(SymbolKind::Module) && is_self { | 112 | if h.tag == HlTag::Symbol(SymbolKind::Module) && is_self { |
114 | HlTag::Symbol(SymbolKind::SelfParam).into() | 113 | SymbolKind::SelfParam.into() |
115 | } else { | 114 | } else { |
116 | h | 115 | h |
117 | } | 116 | } |
@@ -132,7 +131,7 @@ pub(super) fn element( | |||
132 | INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), | 131 | INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), |
133 | BYTE => HlTag::ByteLiteral.into(), | 132 | BYTE => HlTag::ByteLiteral.into(), |
134 | CHAR => HlTag::CharLiteral.into(), | 133 | CHAR => HlTag::CharLiteral.into(), |
135 | QUESTION => Highlight::new(HlTag::Operator) | HlMod::ControlFlow, | 134 | QUESTION => HlTag::Operator(HlOperator::Other) | HlMod::ControlFlow, |
136 | LIFETIME => { | 135 | LIFETIME => { |
137 | let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); | 136 | let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); |
138 | 137 | ||
@@ -140,69 +139,78 @@ pub(super) fn element( | |||
140 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | 139 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, |
141 | None => match NameRefClass::classify_lifetime(sema, &lifetime) { | 140 | None => match NameRefClass::classify_lifetime(sema, &lifetime) { |
142 | Some(NameRefClass::Definition(def)) => highlight_def(db, def), | 141 | Some(NameRefClass::Definition(def)) => highlight_def(db, def), |
143 | _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)), | 142 | _ => SymbolKind::LifetimeParam.into(), |
144 | }, | 143 | }, |
145 | _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)) | HlMod::Definition, | 144 | _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition, |
146 | } | 145 | } |
147 | } | 146 | } |
148 | p if p.is_punct() => match p { | 147 | p if p.is_punct() => match p { |
148 | T![&] if parent_matches::<ast::BinExpr>(&element) => HlOperator::Bitwise.into(), | ||
149 | T![&] => { | 149 | T![&] => { |
150 | let h = HlTag::Operator.into(); | 150 | let h = HlTag::Operator(HlOperator::Other).into(); |
151 | let is_unsafe = element | 151 | let is_unsafe = element |
152 | .parent() | 152 | .parent() |
153 | .and_then(ast::RefExpr::cast) | 153 | .and_then(ast::RefExpr::cast) |
154 | .map(|ref_expr| sema.is_unsafe_ref_expr(&ref_expr)) | 154 | .map_or(false, |ref_expr| sema.is_unsafe_ref_expr(&ref_expr)); |
155 | .unwrap_or(false); | ||
156 | if is_unsafe { | 155 | if is_unsafe { |
157 | h | HlMod::Unsafe | 156 | h | HlMod::Unsafe |
158 | } else { | 157 | } else { |
159 | h | 158 | h |
160 | } | 159 | } |
161 | } | 160 | } |
162 | T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => HlTag::Operator.into(), | 161 | T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => HlOperator::Other.into(), |
163 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { | 162 | T![!] if parent_matches::<ast::MacroCall>(&element) => SymbolKind::Macro.into(), |
164 | HlTag::Symbol(SymbolKind::Macro).into() | 163 | T![!] if parent_matches::<ast::NeverType>(&element) => HlTag::BuiltinType.into(), |
165 | } | 164 | T![!] if parent_matches::<ast::PrefixExpr>(&element) => HlOperator::Logical.into(), |
166 | T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { | 165 | T![*] if parent_matches::<ast::PtrType>(&element) => HlTag::Keyword.into(), |
167 | HlTag::BuiltinType.into() | 166 | T![*] if parent_matches::<ast::PrefixExpr>(&element) => { |
168 | } | ||
169 | T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => { | ||
170 | HlTag::Keyword.into() | ||
171 | } | ||
172 | T![*] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
173 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | 167 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; |
174 | 168 | ||
175 | let expr = prefix_expr.expr()?; | 169 | let expr = prefix_expr.expr()?; |
176 | let ty = sema.type_of_expr(&expr)?; | 170 | let ty = sema.type_of_expr(&expr)?; |
177 | if ty.is_raw_ptr() { | 171 | if ty.is_raw_ptr() { |
178 | HlTag::Operator | HlMod::Unsafe | 172 | HlTag::Operator(HlOperator::Other) | HlMod::Unsafe |
179 | } else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() { | 173 | } else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() { |
180 | HlTag::Operator.into() | 174 | HlOperator::Other.into() |
181 | } else { | 175 | } else { |
182 | HlTag::Punctuation(HlPunct::Other).into() | 176 | HlPunct::Other.into() |
183 | } | 177 | } |
184 | } | 178 | } |
185 | T![-] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | 179 | T![-] if parent_matches::<ast::PrefixExpr>(&element) => { |
186 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | 180 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; |
187 | 181 | ||
188 | let expr = prefix_expr.expr()?; | 182 | let expr = prefix_expr.expr()?; |
189 | match expr { | 183 | match expr { |
190 | ast::Expr::Literal(_) => HlTag::NumericLiteral, | 184 | ast::Expr::Literal(_) => HlTag::NumericLiteral, |
191 | _ => HlTag::Operator, | 185 | _ => HlTag::Operator(HlOperator::Other), |
192 | } | 186 | } |
193 | .into() | 187 | .into() |
194 | } | 188 | } |
195 | _ if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | 189 | _ if parent_matches::<ast::PrefixExpr>(&element) => HlOperator::Other.into(), |
196 | HlTag::Operator.into() | 190 | T![+] | T![-] | T![*] | T![/] | T![+=] | T![-=] | T![*=] | T![/=] |
191 | if parent_matches::<ast::BinExpr>(&element) => | ||
192 | { | ||
193 | HlOperator::Arithmetic.into() | ||
194 | } | ||
195 | T![|] | T![&] | T![!] | T![^] | T![|=] | T![&=] | T![^=] | ||
196 | if parent_matches::<ast::BinExpr>(&element) => | ||
197 | { | ||
198 | HlOperator::Bitwise.into() | ||
197 | } | 199 | } |
198 | _ if element.parent().and_then(ast::BinExpr::cast).is_some() => HlTag::Operator.into(), | 200 | T![&&] | T![||] if parent_matches::<ast::BinExpr>(&element) => { |
199 | _ if element.parent().and_then(ast::RangeExpr::cast).is_some() => { | 201 | HlOperator::Logical.into() |
200 | HlTag::Operator.into() | ||
201 | } | 202 | } |
202 | _ if element.parent().and_then(ast::RangePat::cast).is_some() => HlTag::Operator.into(), | 203 | T![>] | T![<] | T![==] | T![>=] | T![<=] | T![!=] |
203 | _ if element.parent().and_then(ast::RestPat::cast).is_some() => HlTag::Operator.into(), | 204 | if parent_matches::<ast::BinExpr>(&element) => |
204 | _ if element.parent().and_then(ast::Attr::cast).is_some() => HlTag::Attribute.into(), | 205 | { |
205 | kind => HlTag::Punctuation(match kind { | 206 | HlOperator::Comparison.into() |
207 | } | ||
208 | _ if parent_matches::<ast::BinExpr>(&element) => HlOperator::Other.into(), | ||
209 | _ if parent_matches::<ast::RangeExpr>(&element) => HlOperator::Other.into(), | ||
210 | _ if parent_matches::<ast::RangePat>(&element) => HlOperator::Other.into(), | ||
211 | _ if parent_matches::<ast::RestPat>(&element) => HlOperator::Other.into(), | ||
212 | _ if parent_matches::<ast::Attr>(&element) => HlTag::Attribute.into(), | ||
213 | kind => match kind { | ||
206 | T!['['] | T![']'] => HlPunct::Bracket, | 214 | T!['['] | T![']'] => HlPunct::Bracket, |
207 | T!['{'] | T!['}'] => HlPunct::Brace, | 215 | T!['{'] | T!['}'] => HlPunct::Brace, |
208 | T!['('] | T![')'] => HlPunct::Parenthesis, | 216 | T!['('] | T![')'] => HlPunct::Parenthesis, |
@@ -212,22 +220,24 @@ pub(super) fn element( | |||
212 | T![;] => HlPunct::Semi, | 220 | T![;] => HlPunct::Semi, |
213 | T![.] => HlPunct::Dot, | 221 | T![.] => HlPunct::Dot, |
214 | _ => HlPunct::Other, | 222 | _ => HlPunct::Other, |
215 | }) | 223 | } |
216 | .into(), | 224 | .into(), |
217 | }, | 225 | }, |
218 | 226 | ||
219 | k if k.is_keyword() => { | 227 | k if k.is_keyword() => { |
220 | let h = Highlight::new(HlTag::Keyword); | 228 | let h = Highlight::new(HlTag::Keyword); |
221 | match k { | 229 | match k { |
222 | T![break] | 230 | T![await] |
231 | | T![break] | ||
223 | | T![continue] | 232 | | T![continue] |
224 | | T![else] | 233 | | T![else] |
225 | | T![if] | 234 | | T![if] |
235 | | T![in] | ||
226 | | T![loop] | 236 | | T![loop] |
227 | | T![match] | 237 | | T![match] |
228 | | T![return] | 238 | | T![return] |
229 | | T![while] | 239 | | T![while] |
230 | | T![in] => h | HlMod::ControlFlow, | 240 | | T![yield] => h | HlMod::ControlFlow, |
231 | T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow, | 241 | T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow, |
232 | T![unsafe] => h | HlMod::Unsafe, | 242 | T![unsafe] => h | HlMod::Unsafe, |
233 | T![true] | T![false] => HlTag::BoolLiteral.into(), | 243 | T![true] | T![false] => HlTag::BoolLiteral.into(), |
@@ -266,7 +276,6 @@ pub(super) fn element( | |||
266 | hash((name, shadow_count)) | 276 | hash((name, shadow_count)) |
267 | } | 277 | } |
268 | } | 278 | } |
269 | |||
270 | fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | 279 | fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { |
271 | match def { | 280 | match def { |
272 | Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), | 281 | Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), |
@@ -277,17 +286,22 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
277 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); | 286 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); |
278 | if let Some(item) = func.as_assoc_item(db) { | 287 | if let Some(item) = func.as_assoc_item(db) { |
279 | h |= HlMod::Associated; | 288 | h |= HlMod::Associated; |
280 | if func.self_param(db).is_none() { | 289 | match func.self_param(db) { |
281 | h |= HlMod::Static | 290 | Some(sp) => { |
291 | if let hir::Access::Exclusive = sp.access(db) { | ||
292 | h |= HlMod::Mutable; | ||
293 | } | ||
294 | } | ||
295 | None => h |= HlMod::Static, | ||
282 | } | 296 | } |
283 | 297 | ||
284 | match item.container(db) { | 298 | match item.container(db) { |
285 | AssocItemContainer::Impl(i) => { | 299 | hir::AssocItemContainer::Impl(i) => { |
286 | if i.trait_(db).is_some() { | 300 | if i.trait_(db).is_some() { |
287 | h |= HlMod::Trait; | 301 | h |= HlMod::Trait; |
288 | } | 302 | } |
289 | } | 303 | } |
290 | AssocItemContainer::Trait(_t) => { | 304 | hir::AssocItemContainer::Trait(_t) => { |
291 | h |= HlMod::Trait; | 305 | h |= HlMod::Trait; |
292 | } | 306 | } |
293 | } | 307 | } |
@@ -307,12 +321,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
307 | if let Some(item) = konst.as_assoc_item(db) { | 321 | if let Some(item) = konst.as_assoc_item(db) { |
308 | h |= HlMod::Associated; | 322 | h |= HlMod::Associated; |
309 | match item.container(db) { | 323 | match item.container(db) { |
310 | AssocItemContainer::Impl(i) => { | 324 | hir::AssocItemContainer::Impl(i) => { |
311 | if i.trait_(db).is_some() { | 325 | if i.trait_(db).is_some() { |
312 | h |= HlMod::Trait; | 326 | h |= HlMod::Trait; |
313 | } | 327 | } |
314 | } | 328 | } |
315 | AssocItemContainer::Trait(_t) => { | 329 | hir::AssocItemContainer::Trait(_t) => { |
316 | h |= HlMod::Trait; | 330 | h |= HlMod::Trait; |
317 | } | 331 | } |
318 | } | 332 | } |
@@ -326,12 +340,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
326 | if let Some(item) = type_.as_assoc_item(db) { | 340 | if let Some(item) = type_.as_assoc_item(db) { |
327 | h |= HlMod::Associated; | 341 | h |= HlMod::Associated; |
328 | match item.container(db) { | 342 | match item.container(db) { |
329 | AssocItemContainer::Impl(i) => { | 343 | hir::AssocItemContainer::Impl(i) => { |
330 | if i.trait_(db).is_some() { | 344 | if i.trait_(db).is_some() { |
331 | h |= HlMod::Trait; | 345 | h |= HlMod::Trait; |
332 | } | 346 | } |
333 | } | 347 | } |
334 | AssocItemContainer::Trait(_t) => { | 348 | hir::AssocItemContainer::Trait(_t) => { |
335 | h |= HlMod::Trait; | 349 | h |= HlMod::Trait; |
336 | } | 350 | } |
337 | } | 351 | } |
@@ -390,7 +404,7 @@ fn highlight_method_call( | |||
390 | method_call: &ast::MethodCallExpr, | 404 | method_call: &ast::MethodCallExpr, |
391 | ) -> Option<Highlight> { | 405 | ) -> Option<Highlight> { |
392 | let func = sema.resolve_method_call(&method_call)?; | 406 | let func = sema.resolve_method_call(&method_call)?; |
393 | let mut h = HlTag::Symbol(SymbolKind::Function).into(); | 407 | let mut h = SymbolKind::Function.into(); |
394 | h |= HlMod::Associated; | 408 | h |= HlMod::Associated; |
395 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | 409 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { |
396 | h |= HlMod::Unsafe; | 410 | h |= HlMod::Unsafe; |
@@ -426,20 +440,20 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | |||
426 | }; | 440 | }; |
427 | 441 | ||
428 | let tag = match parent.kind() { | 442 | let tag = match parent.kind() { |
429 | STRUCT => HlTag::Symbol(SymbolKind::Struct), | 443 | STRUCT => SymbolKind::Struct, |
430 | ENUM => HlTag::Symbol(SymbolKind::Enum), | 444 | ENUM => SymbolKind::Enum, |
431 | VARIANT => HlTag::Symbol(SymbolKind::Variant), | 445 | VARIANT => SymbolKind::Variant, |
432 | UNION => HlTag::Symbol(SymbolKind::Union), | 446 | UNION => SymbolKind::Union, |
433 | TRAIT => HlTag::Symbol(SymbolKind::Trait), | 447 | TRAIT => SymbolKind::Trait, |
434 | TYPE_ALIAS => HlTag::Symbol(SymbolKind::TypeAlias), | 448 | TYPE_ALIAS => SymbolKind::TypeAlias, |
435 | TYPE_PARAM => HlTag::Symbol(SymbolKind::TypeParam), | 449 | TYPE_PARAM => SymbolKind::TypeParam, |
436 | RECORD_FIELD => HlTag::Symbol(SymbolKind::Field), | 450 | RECORD_FIELD => SymbolKind::Field, |
437 | MODULE => HlTag::Symbol(SymbolKind::Module), | 451 | MODULE => SymbolKind::Module, |
438 | FN => HlTag::Symbol(SymbolKind::Function), | 452 | FN => SymbolKind::Function, |
439 | CONST => HlTag::Symbol(SymbolKind::Const), | 453 | CONST => SymbolKind::Const, |
440 | STATIC => HlTag::Symbol(SymbolKind::Static), | 454 | STATIC => SymbolKind::Static, |
441 | IDENT_PAT => HlTag::Symbol(SymbolKind::Local), | 455 | IDENT_PAT => SymbolKind::Local, |
442 | _ => default, | 456 | _ => return default.into(), |
443 | }; | 457 | }; |
444 | 458 | ||
445 | tag.into() | 459 | tag.into() |
@@ -457,20 +471,15 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
457 | METHOD_CALL_EXPR => { | 471 | METHOD_CALL_EXPR => { |
458 | return ast::MethodCallExpr::cast(parent) | 472 | return ast::MethodCallExpr::cast(parent) |
459 | .and_then(|it| highlight_method_call(sema, &it)) | 473 | .and_then(|it| highlight_method_call(sema, &it)) |
460 | .unwrap_or_else(|| HlTag::Symbol(SymbolKind::Function).into()); | 474 | .unwrap_or_else(|| SymbolKind::Function.into()); |
461 | } | 475 | } |
462 | FIELD_EXPR => { | 476 | FIELD_EXPR => { |
463 | let h = HlTag::Symbol(SymbolKind::Field); | 477 | let h = HlTag::Symbol(SymbolKind::Field); |
464 | let is_union = ast::FieldExpr::cast(parent) | 478 | let is_union = ast::FieldExpr::cast(parent) |
465 | .and_then(|field_expr| { | 479 | .and_then(|field_expr| sema.resolve_field(&field_expr)) |
466 | let field = sema.resolve_field(&field_expr)?; | 480 | .map_or(false, |field| { |
467 | Some(if let VariantDef::Union(_) = field.parent_def(sema.db) { | 481 | matches!(field.parent_def(sema.db), hir::VariantDef::Union(_)) |
468 | true | 482 | }); |
469 | } else { | ||
470 | false | ||
471 | }) | ||
472 | }) | ||
473 | .unwrap_or(false); | ||
474 | if is_union { | 483 | if is_union { |
475 | h | HlMod::Unsafe | 484 | h | HlMod::Unsafe |
476 | } else { | 485 | } else { |
@@ -487,9 +496,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
487 | _ => { | 496 | _ => { |
488 | // within path, decide whether it is module or adt by checking for uppercase name | 497 | // within path, decide whether it is module or adt by checking for uppercase name |
489 | return if name.text().chars().next().unwrap_or_default().is_uppercase() { | 498 | return if name.text().chars().next().unwrap_or_default().is_uppercase() { |
490 | HlTag::Symbol(SymbolKind::Struct) | 499 | SymbolKind::Struct |
491 | } else { | 500 | } else { |
492 | HlTag::Symbol(SymbolKind::Module) | 501 | SymbolKind::Module |
493 | } | 502 | } |
494 | .into(); | 503 | .into(); |
495 | } | 504 | } |
@@ -500,11 +509,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
500 | }; | 509 | }; |
501 | 510 | ||
502 | match parent.kind() { | 511 | match parent.kind() { |
503 | CALL_EXPR => HlTag::Symbol(SymbolKind::Function).into(), | 512 | CALL_EXPR => SymbolKind::Function.into(), |
504 | _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { | 513 | _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { |
505 | HlTag::Symbol(SymbolKind::Struct) | 514 | SymbolKind::Struct |
506 | } else { | 515 | } else { |
507 | HlTag::Symbol(SymbolKind::Const) | 516 | SymbolKind::Const |
508 | } | 517 | } |
509 | .into(), | 518 | .into(), |
510 | } | 519 | } |
@@ -539,6 +548,11 @@ fn parents_match(mut node: NodeOrToken<SyntaxNode, SyntaxToken>, mut kinds: &[Sy | |||
539 | kinds.len() == 0 | 548 | kinds.len() == 0 |
540 | } | 549 | } |
541 | 550 | ||
551 | #[inline] | ||
552 | fn parent_matches<N: AstNode>(element: &SyntaxElement) -> bool { | ||
553 | element.parent().map_or(false, |it| N::can_cast(it.kind())) | ||
554 | } | ||
555 | |||
542 | fn is_child_of_impl(element: &SyntaxElement) -> bool { | 556 | fn is_child_of_impl(element: &SyntaxElement) -> bool { |
543 | match element.parent() { | 557 | match element.parent() { |
544 | Some(e) => e.kind() == IMPL, | 558 | Some(e) => e.kind() == IMPL, |
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index 04fafd244..bc221d599 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs | |||
@@ -4,7 +4,7 @@ use std::mem; | |||
4 | 4 | ||
5 | use either::Either; | 5 | use either::Either; |
6 | use hir::{InFile, Semantics}; | 6 | use hir::{InFile, Semantics}; |
7 | use ide_db::{call_info::ActiveParameter, SymbolKind}; | 7 | use ide_db::{call_info::ActiveParameter, helpers::rust_doc::is_rust_fence, SymbolKind}; |
8 | use syntax::{ | 8 | use syntax::{ |
9 | ast::{self, AstNode}, | 9 | ast::{self, AstNode}, |
10 | AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize, | 10 | AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize, |
@@ -78,17 +78,6 @@ pub(super) fn ra_fixture( | |||
78 | } | 78 | } |
79 | 79 | ||
80 | const RUSTDOC_FENCE: &'static str = "```"; | 80 | const RUSTDOC_FENCE: &'static str = "```"; |
81 | const RUSTDOC_FENCE_TOKENS: &[&'static str] = &[ | ||
82 | "", | ||
83 | "rust", | ||
84 | "should_panic", | ||
85 | "ignore", | ||
86 | "no_run", | ||
87 | "compile_fail", | ||
88 | "edition2015", | ||
89 | "edition2018", | ||
90 | "edition2021", | ||
91 | ]; | ||
92 | 81 | ||
93 | /// Injection of syntax highlighting of doctests. | 82 | /// Injection of syntax highlighting of doctests. |
94 | pub(super) fn doc_comment( | 83 | pub(super) fn doc_comment( |
@@ -174,8 +163,7 @@ pub(super) fn doc_comment( | |||
174 | is_codeblock = !is_codeblock; | 163 | is_codeblock = !is_codeblock; |
175 | // Check whether code is rust by inspecting fence guards | 164 | // Check whether code is rust by inspecting fence guards |
176 | let guards = &line[idx + RUSTDOC_FENCE.len()..]; | 165 | let guards = &line[idx + RUSTDOC_FENCE.len()..]; |
177 | let is_rust = | 166 | let is_rust = is_rust_fence(guards); |
178 | guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); | ||
179 | is_doctest = is_codeblock && is_rust; | 167 | is_doctest = is_codeblock && is_rust; |
180 | continue; | 168 | continue; |
181 | } | 169 | } |
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index 1cec991aa..a304b3250 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs | |||
@@ -28,7 +28,7 @@ pub enum HlTag { | |||
28 | FormatSpecifier, | 28 | FormatSpecifier, |
29 | Keyword, | 29 | Keyword, |
30 | NumericLiteral, | 30 | NumericLiteral, |
31 | Operator, | 31 | Operator(HlOperator), |
32 | Punctuation(HlPunct), | 32 | Punctuation(HlPunct), |
33 | StringLiteral, | 33 | StringLiteral, |
34 | UnresolvedReference, | 34 | UnresolvedReference, |
@@ -40,28 +40,33 @@ pub enum HlTag { | |||
40 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | 40 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
41 | #[repr(u8)] | 41 | #[repr(u8)] |
42 | pub enum HlMod { | 42 | pub enum HlMod { |
43 | /// Used for items in traits and impls. | ||
44 | Associated = 0, | ||
43 | /// Used to differentiate individual elements within attributes. | 45 | /// Used to differentiate individual elements within attributes. |
44 | Attribute = 0, | 46 | Attribute, |
47 | /// Callable item or value. | ||
48 | Callable, | ||
49 | /// Value that is being consumed in a function call | ||
50 | Consuming, | ||
45 | /// Used with keywords like `if` and `break`. | 51 | /// Used with keywords like `if` and `break`. |
46 | ControlFlow, | 52 | ControlFlow, |
47 | /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is | 53 | /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is |
48 | /// not. | 54 | /// not. |
49 | Definition, | 55 | Definition, |
56 | /// Doc-strings like this one. | ||
50 | Documentation, | 57 | Documentation, |
58 | /// Highlighting injection like rust code in doc strings or ra_fixture. | ||
51 | Injected, | 59 | Injected, |
52 | Mutable, | ||
53 | Consuming, | ||
54 | Callable, | ||
55 | /// Used for associated functions | ||
56 | Static, | ||
57 | /// Used for items in impls&traits. | ||
58 | Associated, | ||
59 | /// Used for intra doc links in doc injection. | 60 | /// Used for intra doc links in doc injection. |
60 | IntraDocLink, | 61 | IntraDocLink, |
62 | /// Mutable binding. | ||
63 | Mutable, | ||
64 | /// Used for associated functions. | ||
65 | Static, | ||
61 | /// Used for items in traits and trait impls. | 66 | /// Used for items in traits and trait impls. |
62 | Trait, | 67 | Trait, |
63 | 68 | // Keep this last! | |
64 | /// Keep this last! | 69 | /// Used for unsafe functions, mutable statics, union accesses and unsafe operations. |
65 | Unsafe, | 70 | Unsafe, |
66 | } | 71 | } |
67 | 72 | ||
@@ -87,6 +92,20 @@ pub enum HlPunct { | |||
87 | Other, | 92 | Other, |
88 | } | 93 | } |
89 | 94 | ||
95 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
96 | pub enum HlOperator { | ||
97 | /// |, &, !, ^, |=, &=, ^= | ||
98 | Bitwise, | ||
99 | /// +, -, *, /, +=, -=, *=, /= | ||
100 | Arithmetic, | ||
101 | /// &&, ||, ! | ||
102 | Logical, | ||
103 | /// >, <, ==, >=, <=, != | ||
104 | Comparison, | ||
105 | /// | ||
106 | Other, | ||
107 | } | ||
108 | |||
90 | impl HlTag { | 109 | impl HlTag { |
91 | fn as_str(self) -> &'static str { | 110 | fn as_str(self) -> &'static str { |
92 | match self { | 111 | match self { |
@@ -133,7 +152,13 @@ impl HlTag { | |||
133 | HlPunct::Other => "punctuation", | 152 | HlPunct::Other => "punctuation", |
134 | }, | 153 | }, |
135 | HlTag::NumericLiteral => "numeric_literal", | 154 | HlTag::NumericLiteral => "numeric_literal", |
136 | HlTag::Operator => "operator", | 155 | HlTag::Operator(op) => match op { |
156 | HlOperator::Bitwise => "bitwise", | ||
157 | HlOperator::Arithmetic => "arithmetic", | ||
158 | HlOperator::Logical => "logical", | ||
159 | HlOperator::Comparison => "comparison", | ||
160 | HlOperator::Other => "operator", | ||
161 | }, | ||
137 | HlTag::StringLiteral => "string_literal", | 162 | HlTag::StringLiteral => "string_literal", |
138 | HlTag::UnresolvedReference => "unresolved_reference", | 163 | HlTag::UnresolvedReference => "unresolved_reference", |
139 | HlTag::None => "none", | 164 | HlTag::None => "none", |
@@ -149,17 +174,17 @@ impl fmt::Display for HlTag { | |||
149 | 174 | ||
150 | impl HlMod { | 175 | impl HlMod { |
151 | const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[ | 176 | const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[ |
177 | HlMod::Associated, | ||
152 | HlMod::Attribute, | 178 | HlMod::Attribute, |
179 | HlMod::Callable, | ||
180 | HlMod::Consuming, | ||
153 | HlMod::ControlFlow, | 181 | HlMod::ControlFlow, |
154 | HlMod::Definition, | 182 | HlMod::Definition, |
155 | HlMod::Documentation, | 183 | HlMod::Documentation, |
156 | HlMod::IntraDocLink, | ||
157 | HlMod::Injected, | 184 | HlMod::Injected, |
185 | HlMod::IntraDocLink, | ||
158 | HlMod::Mutable, | 186 | HlMod::Mutable, |
159 | HlMod::Consuming, | ||
160 | HlMod::Callable, | ||
161 | HlMod::Static, | 187 | HlMod::Static, |
162 | HlMod::Associated, | ||
163 | HlMod::Trait, | 188 | HlMod::Trait, |
164 | HlMod::Unsafe, | 189 | HlMod::Unsafe, |
165 | ]; | 190 | ]; |
@@ -209,6 +234,24 @@ impl From<HlTag> for Highlight { | |||
209 | } | 234 | } |
210 | } | 235 | } |
211 | 236 | ||
237 | impl From<HlOperator> for Highlight { | ||
238 | fn from(op: HlOperator) -> Highlight { | ||
239 | Highlight::new(HlTag::Operator(op)) | ||
240 | } | ||
241 | } | ||
242 | |||
243 | impl From<HlPunct> for Highlight { | ||
244 | fn from(punct: HlPunct) -> Highlight { | ||
245 | Highlight::new(HlTag::Punctuation(punct)) | ||
246 | } | ||
247 | } | ||
248 | |||
249 | impl From<SymbolKind> for Highlight { | ||
250 | fn from(sym: SymbolKind) -> Highlight { | ||
251 | Highlight::new(HlTag::Symbol(sym)) | ||
252 | } | ||
253 | } | ||
254 | |||
212 | impl Highlight { | 255 | impl Highlight { |
213 | pub(crate) fn new(tag: HlTag) -> Highlight { | 256 | pub(crate) fn new(tag: HlTag) -> Highlight { |
214 | Highlight { tag, mods: HlMods::default() } | 257 | Highlight { tag, mods: HlMods::default() } |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html index 8cde3906c..a0ea1db34 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html | |||
@@ -42,17 +42,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
42 | <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="brace">{</span><span class="brace">}</span> | 42 | <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="brace">{</span><span class="brace">}</span> |
43 | 43 | ||
44 | <span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span> | 44 | <span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span> |
45 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 45 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration static">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
46 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 46 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
47 | <span class="brace">}</span> | 47 | <span class="brace">}</span> |
48 | 48 | ||
49 | <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span> | 49 | <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span> |
50 | <span class="keyword">fn</span> <span class="function declaration static associated trait">t_is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 50 | <span class="keyword">fn</span> <span class="function associated declaration static trait">t_is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
51 | <span class="keyword">fn</span> <span class="function declaration associated trait">t_is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 51 | <span class="keyword">fn</span> <span class="function associated declaration trait">t_is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
52 | <span class="brace">}</span> | 52 | <span class="brace">}</span> |
53 | 53 | ||
54 | <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span> | 54 | <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span> |
55 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated trait">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 55 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration static trait">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
56 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated trait">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 56 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration trait">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
57 | <span class="brace">}</span> | 57 | <span class="brace">}</span> |
58 | </code></pre> \ No newline at end of file | 58 | </code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index b6d1cac4e..638f42c2f 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | |||
@@ -50,7 +50,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
50 | <span class="comment">// KILLER WHALE</span> | 50 | <span class="comment">// KILLER WHALE</span> |
51 | <span class="comment documentation">/// </span><span class="string_literal injected"> Ishmael."</span><span class="semicolon injected">;</span> | 51 | <span class="comment documentation">/// </span><span class="string_literal injected"> Ishmael."</span><span class="semicolon injected">;</span> |
52 | <span class="comment documentation">/// ```</span> | 52 | <span class="comment documentation">/// ```</span> |
53 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration associated">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="semicolon">;</span> | 53 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant associated declaration">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="semicolon">;</span> |
54 | 54 | ||
55 | <span class="comment documentation">/// Constructs a new `Foo`.</span> | 55 | <span class="comment documentation">/// Constructs a new `Foo`.</span> |
56 | <span class="comment documentation">///</span> | 56 | <span class="comment documentation">///</span> |
@@ -60,7 +60,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
60 | <span class="comment documentation">/// #</span><span class="none injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="parenthesis attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="parenthesis attribute injected">)</span><span class="attribute attribute injected">]</span> | 60 | <span class="comment documentation">/// #</span><span class="none injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="parenthesis attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="parenthesis attribute injected">)</span><span class="attribute attribute injected">]</span> |
61 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="keyword injected">mut</span><span class="none injected"> </span><span class="variable declaration injected mutable">foo</span><span class="colon injected">:</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> | 61 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="keyword injected">mut</span><span class="none injected"> </span><span class="variable declaration injected mutable">foo</span><span class="colon injected">:</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
62 | <span class="comment documentation">/// ```</span> | 62 | <span class="comment documentation">/// ```</span> |
63 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration static associated">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="struct">Foo</span> <span class="brace">{</span> | 63 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function associated declaration static">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="struct">Foo</span> <span class="brace">{</span> |
64 | <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">bar</span><span class="colon">:</span> <span class="bool_literal">true</span> <span class="brace">}</span> | 64 | <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">bar</span><span class="colon">:</span> <span class="bool_literal">true</span> <span class="brace">}</span> |
65 | <span class="brace">}</span> | 65 | <span class="brace">}</span> |
66 | 66 | ||
@@ -76,7 +76,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
76 | <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span> | 76 | <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span> |
77 | <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="parenthesis injected">(</span><span class="none injected">foo</span><span class="operator injected">.</span><span class="none injected">bar</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> | 77 | <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="parenthesis injected">(</span><span class="none injected">foo</span><span class="operator injected">.</span><span class="none injected">bar</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
78 | <span class="comment documentation">///</span> | 78 | <span class="comment documentation">///</span> |
79 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">bar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="none injected"> </span><span class="operator injected">||</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="semicolon injected">;</span> | 79 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">bar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="none injected"> </span><span class="logical injected">||</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="semicolon injected">;</span> |
80 | <span class="comment documentation">///</span> | 80 | <span class="comment documentation">///</span> |
81 | <span class="comment documentation">/// </span><span class="comment injected">/* multi-line</span> | 81 | <span class="comment documentation">/// </span><span class="comment injected">/* multi-line</span> |
82 | <span class="comment documentation">/// </span><span class="comment injected"> comment */</span> | 82 | <span class="comment documentation">/// </span><span class="comment injected"> comment */</span> |
@@ -94,15 +94,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
94 | <span class="comment documentation">/// ```sh</span> | 94 | <span class="comment documentation">/// ```sh</span> |
95 | <span class="comment documentation">/// echo 1</span> | 95 | <span class="comment documentation">/// echo 1</span> |
96 | <span class="comment documentation">/// ```</span> | 96 | <span class="comment documentation">/// ```</span> |
97 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="brace">{</span> | 97 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="brace">{</span> |
98 | <span class="bool_literal">true</span> | 98 | <span class="bool_literal">true</span> |
99 | <span class="brace">}</span> | 99 | <span class="brace">}</span> |
100 | <span class="brace">}</span> | 100 | <span class="brace">}</span> |
101 | 101 | ||
102 | <span class="comment documentation">/// </span><span class="struct documentation intra_doc_link injected">[`Foo`](Foo)</span><span class="comment documentation"> is a struct</span> | 102 | <span class="comment documentation">/// </span><span class="struct documentation injected intra_doc_link">[`Foo`](Foo)</span><span class="comment documentation"> is a struct</span> |
103 | <span class="comment documentation">/// This function is > </span><span class="function documentation intra_doc_link injected">[`all_the_links`](all_the_links)</span><span class="comment documentation"> <</span> | 103 | <span class="comment documentation">/// This function is > </span><span class="function documentation injected intra_doc_link">[`all_the_links`](all_the_links)</span><span class="comment documentation"> <</span> |
104 | <span class="comment documentation">/// [`noop`](noop) is a macro below</span> | 104 | <span class="comment documentation">/// [`noop`](noop) is a macro below</span> |
105 | <span class="comment documentation">/// </span><span class="struct documentation intra_doc_link injected">[`Item`]</span><span class="comment documentation"> is a struct in the module </span><span class="module documentation intra_doc_link injected">[`module`]</span> | 105 | <span class="comment documentation">/// </span><span class="struct documentation injected intra_doc_link">[`Item`]</span><span class="comment documentation"> is a struct in the module </span><span class="module documentation injected intra_doc_link">[`module`]</span> |
106 | <span class="comment documentation">///</span> | 106 | <span class="comment documentation">///</span> |
107 | <span class="comment documentation">/// [`Item`]: module::Item</span> | 107 | <span class="comment documentation">/// [`Item`]: module::Item</span> |
108 | <span class="comment documentation">/// [mix_and_match]: ThisShouldntResolve</span> | 108 | <span class="comment documentation">/// [mix_and_match]: ThisShouldntResolve</span> |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html index 7c6694a27..6202a03ce 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html | |||
@@ -42,7 +42,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
42 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> | 42 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
43 | <span class="function">fixture</span><span class="parenthesis">(</span><span class="string_literal">r#"</span> | 43 | <span class="function">fixture</span><span class="parenthesis">(</span><span class="string_literal">r#"</span> |
44 | <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="brace">{</span> | 44 | <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="brace">{</span> |
45 | <span class="keyword">fn</span> <span class="function declaration static associated trait">foo</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> | 45 | <span class="keyword">fn</span> <span class="function associated declaration static trait">foo</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
46 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="comma">,</span> <span class="numeric_literal">4</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 46 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="comma">,</span> <span class="numeric_literal">4</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
47 | <span class="brace">}</span> | 47 | <span class="brace">}</span> |
48 | <span class="brace">}</span><span class="string_literal">"#</span> | 48 | <span class="brace">}</span><span class="string_literal">"#</span> |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index 72910421d..68165bdbf 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html | |||
@@ -47,7 +47,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
47 | <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="semicolon">;</span> | 47 | <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="semicolon">;</span> |
48 | 48 | ||
49 | <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="brace">{</span> | 49 | <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="brace">{</span> |
50 | <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 50 | <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function associated declaration unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
51 | <span class="brace">}</span> | 51 | <span class="brace">}</span> |
52 | 52 | ||
53 | <span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="brace">{</span> | 53 | <span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="brace">{</span> |
@@ -62,11 +62,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
62 | <span class="brace">}</span> | 62 | <span class="brace">}</span> |
63 | 63 | ||
64 | <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span> | 64 | <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span> |
65 | <span class="keyword">fn</span> <span class="function declaration associated trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 65 | <span class="keyword">fn</span> <span class="function associated declaration trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
66 | <span class="brace">}</span> | 66 | <span class="brace">}</span> |
67 | 67 | ||
68 | <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="brace">{</span> | 68 | <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="brace">{</span> |
69 | <span class="keyword">fn</span> <span class="function declaration associated trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> | 69 | <span class="keyword">fn</span> <span class="function associated declaration trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
70 | <span class="brace">}</span> | 70 | <span class="brace">}</span> |
71 | 71 | ||
72 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> | 72 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 973173254..df4192194 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -67,25 +67,25 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
67 | <span class="brace">}</span> | 67 | <span class="brace">}</span> |
68 | 68 | ||
69 | <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="brace">{</span> | 69 | <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="brace">{</span> |
70 | <span class="keyword">fn</span> <span class="function declaration associated trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="semicolon">;</span> | 70 | <span class="keyword">fn</span> <span class="function associated declaration trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="semicolon">;</span> |
71 | <span class="brace">}</span> | 71 | <span class="brace">}</span> |
72 | 72 | ||
73 | <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="brace">{</span> | 73 | <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="brace">{</span> |
74 | <span class="keyword">fn</span> <span class="function declaration associated trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> | 74 | <span class="keyword">fn</span> <span class="function associated declaration trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> |
75 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 75 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
76 | <span class="brace">}</span> | 76 | <span class="brace">}</span> |
77 | <span class="brace">}</span> | 77 | <span class="brace">}</span> |
78 | 78 | ||
79 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="brace">{</span> | 79 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="brace">{</span> |
80 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">Foo</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> | 80 | <span class="keyword">fn</span> <span class="function associated declaration">baz</span><span class="parenthesis">(</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">Foo</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> |
81 | <span class="value_param">f</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="parenthesis">(</span><span class="self_keyword mutable consuming">self</span><span class="parenthesis">)</span> | 81 | <span class="value_param">f</span><span class="operator">.</span><span class="function associated consuming">baz</span><span class="parenthesis">(</span><span class="self_keyword consuming mutable">self</span><span class="parenthesis">)</span> |
82 | <span class="brace">}</span> | 82 | <span class="brace">}</span> |
83 | 83 | ||
84 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> | 84 | <span class="keyword">fn</span> <span class="function associated declaration mutable">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> |
85 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> | 85 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> |
86 | <span class="brace">}</span> | 86 | <span class="brace">}</span> |
87 | 87 | ||
88 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> | 88 | <span class="keyword">fn</span> <span class="function associated declaration">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> |
89 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 89 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
90 | <span class="brace">}</span> | 90 | <span class="brace">}</span> |
91 | <span class="brace">}</span> | 91 | <span class="brace">}</span> |
@@ -96,15 +96,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
96 | <span class="brace">}</span> | 96 | <span class="brace">}</span> |
97 | 97 | ||
98 | <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="brace">{</span> | 98 | <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="brace">{</span> |
99 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="self_keyword declaration">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">FooCopy</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span> | 99 | <span class="keyword">fn</span> <span class="function associated declaration">baz</span><span class="parenthesis">(</span><span class="self_keyword declaration">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">FooCopy</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span> |
100 | <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span> | 100 | <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span> |
101 | <span class="brace">}</span> | 101 | <span class="brace">}</span> |
102 | 102 | ||
103 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> | 103 | <span class="keyword">fn</span> <span class="function associated declaration mutable">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> |
104 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> | 104 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> |
105 | <span class="brace">}</span> | 105 | <span class="brace">}</span> |
106 | 106 | ||
107 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span> | 107 | <span class="keyword">fn</span> <span class="function associated declaration">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span> |
108 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 108 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
109 | <span class="brace">}</span> | 109 | <span class="brace">}</span> |
110 | <span class="brace">}</span> | 110 | <span class="brace">}</span> |
@@ -128,7 +128,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
128 | <span class="brace">}</span> | 128 | <span class="brace">}</span> |
129 | 129 | ||
130 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="semicolon">;</span> | 130 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="semicolon">;</span> |
131 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="angle"><</span><span class="type_param declaration">F</span><span class="colon">:</span> <span class="trait">Fn</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="angle">></span><span class="parenthesis">(</span><span class="value_param declaration callable">f</span><span class="colon">:</span> <span class="type_param">F</span><span class="parenthesis">)</span> <span class="brace">{</span> | 131 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="angle"><</span><span class="type_param declaration">F</span><span class="colon">:</span> <span class="trait">Fn</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="angle">></span><span class="parenthesis">(</span><span class="value_param callable declaration">f</span><span class="colon">:</span> <span class="type_param">F</span><span class="parenthesis">)</span> <span class="brace">{</span> |
132 | <span class="value_param callable">f</span><span class="parenthesis">(</span><span class="parenthesis">)</span> | 132 | <span class="value_param callable">f</span><span class="parenthesis">(</span><span class="parenthesis">)</span> |
133 | <span class="brace">}</span> | 133 | <span class="brace">}</span> |
134 | 134 | ||
@@ -199,21 +199,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
199 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="field">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> | 199 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="field">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
200 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="field">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> | 200 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="field">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
201 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated">quop</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 201 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated">quop</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
202 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 202 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated mutable">qux</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
203 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="parenthesis">(</span><span class="variable consuming">foo2</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 203 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated consuming">baz</span><span class="parenthesis">(</span><span class="variable consuming">foo2</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
204 | 204 | ||
205 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="brace">{</span> <span class="field">x</span> <span class="brace">}</span><span class="semicolon">;</span> | 205 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="brace">{</span> <span class="field">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
206 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">quop</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 206 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">quop</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
207 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 207 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated mutable">qux</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
208 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="variable mutable">copy</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 208 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="variable mutable">copy</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
209 | 209 | ||
210 | <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="semicolon">;</span> | 210 | <span class="keyword">let</span> <span class="variable callable declaration">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="semicolon">;</span> |
211 | <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="function associated">baz</span><span class="semicolon">;</span> | 211 | <span class="keyword">let</span> <span class="variable callable declaration">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="function associated">baz</span><span class="semicolon">;</span> |
212 | 212 | ||
213 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="semicolon">;</span> | 213 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="semicolon">;</span> |
214 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="semicolon">;</span> | 214 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="semicolon">;</span> |
215 | 215 | ||
216 | <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="operator">!</span><span class="bool_literal">true</span><span class="semicolon">;</span> | 216 | <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="logical">!</span><span class="bool_literal">true</span><span class="semicolon">;</span> |
217 | 217 | ||
218 | <span class="label declaration">'foo</span><span class="colon">:</span> <span class="keyword control">loop</span> <span class="brace">{</span> | 218 | <span class="label declaration">'foo</span><span class="colon">:</span> <span class="keyword control">loop</span> <span class="brace">{</span> |
219 | <span class="keyword control">break</span> <span class="label">'foo</span><span class="semicolon">;</span> | 219 | <span class="keyword control">break</span> <span class="label">'foo</span><span class="semicolon">;</span> |
@@ -228,7 +228,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
228 | <span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span> | 228 | <span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span> |
229 | 229 | ||
230 | <span class="keyword">impl</span><span class="angle"><</span><span class="type_param declaration">T</span><span class="angle">></span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">T</span><span class="angle">></span> <span class="brace">{</span> | 230 | <span class="keyword">impl</span><span class="angle"><</span><span class="type_param declaration">T</span><span class="angle">></span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">T</span><span class="angle">></span> <span class="brace">{</span> |
231 | <span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="angle"><</span><span class="type_param declaration">U</span><span class="angle">></span><span class="parenthesis">(</span><span class="self_keyword declaration">self</span><span class="comma">,</span> <span class="value_param declaration">other</span><span class="colon">:</span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">U</span><span class="angle">></span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="angle"><</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="comma">,</span> <span class="type_param">U</span><span class="parenthesis">)</span><span class="angle">></span> <span class="brace">{</span> | 231 | <span class="keyword">fn</span> <span class="function associated declaration">and</span><span class="angle"><</span><span class="type_param declaration">U</span><span class="angle">></span><span class="parenthesis">(</span><span class="self_keyword declaration">self</span><span class="comma">,</span> <span class="value_param declaration">other</span><span class="colon">:</span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">U</span><span class="angle">></span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="angle"><</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="comma">,</span> <span class="type_param">U</span><span class="parenthesis">)</span><span class="angle">></span> <span class="brace">{</span> |
232 | <span class="keyword control">match</span> <span class="value_param">other</span> <span class="brace">{</span> | 232 | <span class="keyword control">match</span> <span class="value_param">other</span> <span class="brace">{</span> |
233 | <span class="enum_variant">None</span> <span class="operator">=></span> <span class="macro">unimplemented!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span> | 233 | <span class="enum_variant">None</span> <span class="operator">=></span> <span class="macro">unimplemented!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span> |
234 | <span class="variable declaration">Nope</span> <span class="operator">=></span> <span class="variable">Nope</span><span class="comma">,</span> | 234 | <span class="variable declaration">Nope</span> <span class="operator">=></span> <span class="variable">Nope</span><span class="comma">,</span> |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index de2d22ac7..17cc6334b 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -2,8 +2,7 @@ use std::time::Instant; | |||
2 | 2 | ||
3 | use expect_test::{expect_file, ExpectFile}; | 3 | use expect_test::{expect_file, ExpectFile}; |
4 | use ide_db::SymbolKind; | 4 | use ide_db::SymbolKind; |
5 | use stdx::format_to; | 5 | use test_utils::{bench, bench_fixture, skip_slow_tests, AssertLinear}; |
6 | use test_utils::{bench, bench_fixture, skip_slow_tests}; | ||
7 | 6 | ||
8 | use crate::{fixture, FileRange, HlTag, TextRange}; | 7 | use crate::{fixture, FileRange, HlTag, TextRange}; |
9 | 8 | ||
@@ -266,90 +265,27 @@ fn syntax_highlighting_not_quadratic() { | |||
266 | return; | 265 | return; |
267 | } | 266 | } |
268 | 267 | ||
269 | let mut measures = Vec::new(); | 268 | let mut al = AssertLinear::default(); |
270 | for i in 6..=10 { | 269 | while al.next_round() { |
271 | let n = 1 << i; | 270 | for i in 6..=10 { |
272 | let fixture = bench_fixture::big_struct_n(n); | 271 | let n = 1 << i; |
273 | let (analysis, file_id) = fixture::file(&fixture); | ||
274 | 272 | ||
275 | let time = Instant::now(); | 273 | let fixture = bench_fixture::big_struct_n(n); |
274 | let (analysis, file_id) = fixture::file(&fixture); | ||
276 | 275 | ||
277 | let hash = analysis | 276 | let time = Instant::now(); |
278 | .highlight(file_id) | ||
279 | .unwrap() | ||
280 | .iter() | ||
281 | .filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct)) | ||
282 | .count(); | ||
283 | assert!(hash > n as usize); | ||
284 | 277 | ||
285 | let elapsed = time.elapsed(); | 278 | let hash = analysis |
286 | measures.push((n as f64, elapsed.as_millis() as f64)) | 279 | .highlight(file_id) |
287 | } | 280 | .unwrap() |
281 | .iter() | ||
282 | .filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct)) | ||
283 | .count(); | ||
284 | assert!(hash > n as usize); | ||
288 | 285 | ||
289 | assert_linear(&measures) | 286 | let elapsed = time.elapsed(); |
290 | } | 287 | al.sample(n as f64, elapsed.as_millis() as f64); |
291 | |||
292 | /// Checks that a set of measurements looks like a liner function rather than | ||
293 | /// like a quadratic function. Algorithm: | ||
294 | /// | ||
295 | /// 1. Linearly scale input to be in [0; 1) | ||
296 | /// 2. Using linear regression, compute the best linear function approximating | ||
297 | /// the input. | ||
298 | /// 3. Compute RMSE and maximal absolute error. | ||
299 | /// 4. Check that errors are within tolerances and that the constant term is not | ||
300 | /// too negative. | ||
301 | /// | ||
302 | /// Ideally, we should use a proper "model selection" to directly compare | ||
303 | /// quadratic and linear models, but that sounds rather complicated: | ||
304 | /// | ||
305 | /// https://stats.stackexchange.com/questions/21844/selecting-best-model-based-on-linear-quadratic-and-cubic-fit-of-data | ||
306 | fn assert_linear(xy: &[(f64, f64)]) { | ||
307 | let (mut xs, mut ys): (Vec<_>, Vec<_>) = xy.iter().copied().unzip(); | ||
308 | normalize(&mut xs); | ||
309 | normalize(&mut ys); | ||
310 | let xy = xs.iter().copied().zip(ys.iter().copied()); | ||
311 | |||
312 | // Linear regression: finding a and b to fit y = a + b*x. | ||
313 | |||
314 | let mean_x = mean(&xs); | ||
315 | let mean_y = mean(&ys); | ||
316 | |||
317 | let b = { | ||
318 | let mut num = 0.0; | ||
319 | let mut denom = 0.0; | ||
320 | for (x, y) in xy.clone() { | ||
321 | num += (x - mean_x) * (y - mean_y); | ||
322 | denom += (x - mean_x).powi(2); | ||
323 | } | 288 | } |
324 | num / denom | ||
325 | }; | ||
326 | |||
327 | let a = mean_y - b * mean_x; | ||
328 | |||
329 | let mut plot = format!("y_pred = {:.3} + {:.3} * x\n\nx y y_pred\n", a, b); | ||
330 | |||
331 | let mut se = 0.0; | ||
332 | let mut max_error = 0.0f64; | ||
333 | for (x, y) in xy { | ||
334 | let y_pred = a + b * x; | ||
335 | se += (y - y_pred).powi(2); | ||
336 | max_error = max_error.max((y_pred - y).abs()); | ||
337 | |||
338 | format_to!(plot, "{:.3} {:.3} {:.3}\n", x, y, y_pred); | ||
339 | } | ||
340 | |||
341 | let rmse = (se / xs.len() as f64).sqrt(); | ||
342 | format_to!(plot, "\nrmse = {:.3} max error = {:.3}", rmse, max_error); | ||
343 | |||
344 | assert!(rmse < 0.05 && max_error < 0.1 && a > -0.1, "\nLooks quadratic\n{}", plot); | ||
345 | |||
346 | fn normalize(xs: &mut Vec<f64>) { | ||
347 | let max = xs.iter().copied().max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap(); | ||
348 | xs.iter_mut().for_each(|it| *it /= max); | ||
349 | } | ||
350 | |||
351 | fn mean(xs: &[f64]) -> f64 { | ||
352 | xs.iter().copied().sum::<f64>() / (xs.len() as f64) | ||
353 | } | 289 | } |
354 | } | 290 | } |
355 | 291 | ||
@@ -371,7 +307,7 @@ fn benchmark_syntax_highlighting_parser() { | |||
371 | .filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function)) | 307 | .filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function)) |
372 | .count() | 308 | .count() |
373 | }; | 309 | }; |
374 | assert_eq!(hash, 1629); | 310 | assert_eq!(hash, 1632); |
375 | } | 311 | } |
376 | 312 | ||
377 | #[test] | 313 | #[test] |