diff options
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 66 | ||||
-rw-r--r-- | crates/ra_ide/src/runnables.rs | 250 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlight_injection.html | 1 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlight_strings.html | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlight_unsafe.html | 48 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlighting.html | 1 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/rainbow_highlighting.html | 1 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 25 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/html.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tags.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tests.rs | 32 |
11 files changed, 360 insertions, 75 deletions
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index 5da28edd2..c7bb1e69f 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs | |||
@@ -92,15 +92,16 @@ impl NavigationTarget { | |||
92 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 92 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
93 | if let Some(src) = module.declaration_source(db) { | 93 | if let Some(src) = module.declaration_source(db) { |
94 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); | 94 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); |
95 | return NavigationTarget::from_syntax( | 95 | let mut res = NavigationTarget::from_syntax( |
96 | frange.file_id, | 96 | frange.file_id, |
97 | name, | 97 | name, |
98 | None, | 98 | None, |
99 | frange.range, | 99 | frange.range, |
100 | src.value.syntax().kind(), | 100 | src.value.syntax().kind(), |
101 | src.value.doc_comment_text(), | ||
102 | src.value.short_label(), | ||
103 | ); | 101 | ); |
102 | res.docs = src.value.doc_comment_text(); | ||
103 | res.description = src.value.short_label(); | ||
104 | return res; | ||
104 | } | 105 | } |
105 | module.to_nav(db) | 106 | module.to_nav(db) |
106 | } | 107 | } |
@@ -130,11 +131,9 @@ impl NavigationTarget { | |||
130 | } | 131 | } |
131 | 132 | ||
132 | /// Allows `NavigationTarget` to be created from a `NameOwner` | 133 | /// Allows `NavigationTarget` to be created from a `NameOwner` |
133 | fn from_named( | 134 | pub(crate) fn from_named( |
134 | db: &RootDatabase, | 135 | db: &RootDatabase, |
135 | node: InFile<&dyn ast::NameOwner>, | 136 | node: InFile<&dyn ast::NameOwner>, |
136 | docs: Option<String>, | ||
137 | description: Option<String>, | ||
138 | ) -> NavigationTarget { | 137 | ) -> NavigationTarget { |
139 | //FIXME: use `_` instead of empty string | 138 | //FIXME: use `_` instead of empty string |
140 | let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); | 139 | let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); |
@@ -148,8 +147,6 @@ impl NavigationTarget { | |||
148 | focus_range, | 147 | focus_range, |
149 | frange.range, | 148 | frange.range, |
150 | node.value.syntax().kind(), | 149 | node.value.syntax().kind(), |
151 | docs, | ||
152 | description, | ||
153 | ) | 150 | ) |
154 | } | 151 | } |
155 | 152 | ||
@@ -159,8 +156,6 @@ impl NavigationTarget { | |||
159 | focus_range: Option<TextRange>, | 156 | focus_range: Option<TextRange>, |
160 | full_range: TextRange, | 157 | full_range: TextRange, |
161 | kind: SyntaxKind, | 158 | kind: SyntaxKind, |
162 | docs: Option<String>, | ||
163 | description: Option<String>, | ||
164 | ) -> NavigationTarget { | 159 | ) -> NavigationTarget { |
165 | NavigationTarget { | 160 | NavigationTarget { |
166 | file_id, | 161 | file_id, |
@@ -169,8 +164,8 @@ impl NavigationTarget { | |||
169 | full_range, | 164 | full_range, |
170 | focus_range, | 165 | focus_range, |
171 | container_name: None, | 166 | container_name: None, |
172 | description, | 167 | description: None, |
173 | docs, | 168 | docs: None, |
174 | } | 169 | } |
175 | } | 170 | } |
176 | } | 171 | } |
@@ -238,12 +233,11 @@ where | |||
238 | { | 233 | { |
239 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 234 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
240 | let src = self.source(db); | 235 | let src = self.source(db); |
241 | NavigationTarget::from_named( | 236 | let mut res = |
242 | db, | 237 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); |
243 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 238 | res.docs = src.value.doc_comment_text(); |
244 | src.value.doc_comment_text(), | 239 | res.description = src.value.short_label(); |
245 | src.value.short_label(), | 240 | res |
246 | ) | ||
247 | } | 241 | } |
248 | } | 242 | } |
249 | 243 | ||
@@ -258,15 +252,7 @@ impl ToNav for hir::Module { | |||
258 | } | 252 | } |
259 | }; | 253 | }; |
260 | let frange = original_range(db, src.with_value(syntax)); | 254 | let frange = original_range(db, src.with_value(syntax)); |
261 | NavigationTarget::from_syntax( | 255 | NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind()) |
262 | frange.file_id, | ||
263 | name, | ||
264 | focus, | ||
265 | frange.range, | ||
266 | syntax.kind(), | ||
267 | None, | ||
268 | None, | ||
269 | ) | ||
270 | } | 256 | } |
271 | } | 257 | } |
272 | 258 | ||
@@ -285,8 +271,6 @@ impl ToNav for hir::ImplDef { | |||
285 | None, | 271 | None, |
286 | frange.range, | 272 | frange.range, |
287 | src.value.syntax().kind(), | 273 | src.value.syntax().kind(), |
288 | None, | ||
289 | None, | ||
290 | ) | 274 | ) |
291 | } | 275 | } |
292 | } | 276 | } |
@@ -296,12 +280,12 @@ impl ToNav for hir::Field { | |||
296 | let src = self.source(db); | 280 | let src = self.source(db); |
297 | 281 | ||
298 | match &src.value { | 282 | match &src.value { |
299 | FieldSource::Named(it) => NavigationTarget::from_named( | 283 | FieldSource::Named(it) => { |
300 | db, | 284 | let mut res = NavigationTarget::from_named(db, src.with_value(it)); |
301 | src.with_value(it), | 285 | res.docs = it.doc_comment_text(); |
302 | it.doc_comment_text(), | 286 | res.description = it.short_label(); |
303 | it.short_label(), | 287 | res |
304 | ), | 288 | } |
305 | FieldSource::Pos(it) => { | 289 | FieldSource::Pos(it) => { |
306 | let frange = original_range(db, src.with_value(it.syntax())); | 290 | let frange = original_range(db, src.with_value(it.syntax())); |
307 | NavigationTarget::from_syntax( | 291 | NavigationTarget::from_syntax( |
@@ -310,8 +294,6 @@ impl ToNav for hir::Field { | |||
310 | None, | 294 | None, |
311 | frange.range, | 295 | frange.range, |
312 | it.syntax().kind(), | 296 | it.syntax().kind(), |
313 | None, | ||
314 | None, | ||
315 | ) | 297 | ) |
316 | } | 298 | } |
317 | } | 299 | } |
@@ -322,12 +304,10 @@ impl ToNav for hir::MacroDef { | |||
322 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 304 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
323 | let src = self.source(db); | 305 | let src = self.source(db); |
324 | log::debug!("nav target {:#?}", src.value.syntax()); | 306 | log::debug!("nav target {:#?}", src.value.syntax()); |
325 | NavigationTarget::from_named( | 307 | let mut res = |
326 | db, | 308 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); |
327 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 309 | res.docs = src.value.doc_comment_text(); |
328 | src.value.doc_comment_text(), | 310 | res |
329 | None, | ||
330 | ) | ||
331 | } | 311 | } |
332 | } | 312 | } |
333 | 313 | ||
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index 286d45eee..f32ce0d22 100644 --- a/crates/ra_ide/src/runnables.rs +++ b/crates/ra_ide/src/runnables.rs | |||
@@ -1,19 +1,19 @@ | |||
1 | use std::fmt; | ||
2 | |||
1 | use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; | 3 | use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; |
2 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | use ra_cfg::CfgExpr; | ||
3 | use ra_ide_db::RootDatabase; | 6 | use ra_ide_db::RootDatabase; |
4 | use ra_syntax::{ | 7 | use ra_syntax::{ |
5 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, | 8 | ast::{self, AstNode, AttrsOwner, DocCommentsOwner, ModuleItemOwner, NameOwner}, |
6 | match_ast, SyntaxNode, TextRange, | 9 | match_ast, SyntaxNode, |
7 | }; | 10 | }; |
8 | 11 | ||
9 | use crate::FileId; | 12 | use crate::{display::ToNav, FileId, NavigationTarget}; |
10 | use ast::DocCommentsOwner; | ||
11 | use ra_cfg::CfgExpr; | ||
12 | use std::fmt::Display; | ||
13 | 13 | ||
14 | #[derive(Debug)] | 14 | #[derive(Debug)] |
15 | pub struct Runnable { | 15 | pub struct Runnable { |
16 | pub range: TextRange, | 16 | pub nav: NavigationTarget, |
17 | pub kind: RunnableKind, | 17 | pub kind: RunnableKind, |
18 | pub cfg_exprs: Vec<CfgExpr>, | 18 | pub cfg_exprs: Vec<CfgExpr>, |
19 | } | 19 | } |
@@ -24,8 +24,8 @@ pub enum TestId { | |||
24 | Path(String), | 24 | Path(String), |
25 | } | 25 | } |
26 | 26 | ||
27 | impl Display for TestId { | 27 | impl fmt::Display for TestId { |
28 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | 28 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
29 | match self { | 29 | match self { |
30 | TestId::Name(name) => write!(f, "{}", name), | 30 | TestId::Name(name) => write!(f, "{}", name), |
31 | TestId::Path(path) => write!(f, "{}", path), | 31 | TestId::Path(path) => write!(f, "{}", path), |
@@ -131,7 +131,8 @@ fn runnable_fn( | |||
131 | let cfg_exprs = | 131 | let cfg_exprs = |
132 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); | 132 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); |
133 | 133 | ||
134 | Some(Runnable { range: fn_def.syntax().text_range(), kind, cfg_exprs }) | 134 | let nav = NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def)); |
135 | Some(Runnable { nav, kind, cfg_exprs }) | ||
135 | } | 136 | } |
136 | 137 | ||
137 | #[derive(Debug)] | 138 | #[derive(Debug)] |
@@ -183,7 +184,6 @@ fn runnable_mod( | |||
183 | if !has_test_function { | 184 | if !has_test_function { |
184 | return None; | 185 | return None; |
185 | } | 186 | } |
186 | let range = module.syntax().text_range(); | ||
187 | let module_def = sema.to_def(&module)?; | 187 | let module_def = sema.to_def(&module)?; |
188 | 188 | ||
189 | let path = module_def | 189 | let path = module_def |
@@ -197,7 +197,8 @@ fn runnable_mod( | |||
197 | let cfg_exprs = | 197 | let cfg_exprs = |
198 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); | 198 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); |
199 | 199 | ||
200 | Some(Runnable { range, kind: RunnableKind::TestMod { path }, cfg_exprs }) | 200 | let nav = module_def.to_nav(sema.db); |
201 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg_exprs }) | ||
201 | } | 202 | } |
202 | 203 | ||
203 | #[cfg(test)] | 204 | #[cfg(test)] |
@@ -227,12 +228,38 @@ mod tests { | |||
227 | @r###" | 228 | @r###" |
228 | [ | 229 | [ |
229 | Runnable { | 230 | Runnable { |
230 | range: 1..21, | 231 | nav: NavigationTarget { |
232 | file_id: FileId( | ||
233 | 1, | ||
234 | ), | ||
235 | full_range: 1..21, | ||
236 | name: "main", | ||
237 | kind: FN_DEF, | ||
238 | focus_range: Some( | ||
239 | 12..16, | ||
240 | ), | ||
241 | container_name: None, | ||
242 | description: None, | ||
243 | docs: None, | ||
244 | }, | ||
231 | kind: Bin, | 245 | kind: Bin, |
232 | cfg_exprs: [], | 246 | cfg_exprs: [], |
233 | }, | 247 | }, |
234 | Runnable { | 248 | Runnable { |
235 | range: 22..46, | 249 | nav: NavigationTarget { |
250 | file_id: FileId( | ||
251 | 1, | ||
252 | ), | ||
253 | full_range: 22..46, | ||
254 | name: "test_foo", | ||
255 | kind: FN_DEF, | ||
256 | focus_range: Some( | ||
257 | 33..41, | ||
258 | ), | ||
259 | container_name: None, | ||
260 | description: None, | ||
261 | docs: None, | ||
262 | }, | ||
236 | kind: Test { | 263 | kind: Test { |
237 | test_id: Path( | 264 | test_id: Path( |
238 | "test_foo", | 265 | "test_foo", |
@@ -244,7 +271,20 @@ mod tests { | |||
244 | cfg_exprs: [], | 271 | cfg_exprs: [], |
245 | }, | 272 | }, |
246 | Runnable { | 273 | Runnable { |
247 | range: 47..81, | 274 | nav: NavigationTarget { |
275 | file_id: FileId( | ||
276 | 1, | ||
277 | ), | ||
278 | full_range: 47..81, | ||
279 | name: "test_foo", | ||
280 | kind: FN_DEF, | ||
281 | focus_range: Some( | ||
282 | 68..76, | ||
283 | ), | ||
284 | container_name: None, | ||
285 | description: None, | ||
286 | docs: None, | ||
287 | }, | ||
248 | kind: Test { | 288 | kind: Test { |
249 | test_id: Path( | 289 | test_id: Path( |
250 | "test_foo", | 290 | "test_foo", |
@@ -279,12 +319,38 @@ mod tests { | |||
279 | @r###" | 319 | @r###" |
280 | [ | 320 | [ |
281 | Runnable { | 321 | Runnable { |
282 | range: 1..21, | 322 | nav: NavigationTarget { |
323 | file_id: FileId( | ||
324 | 1, | ||
325 | ), | ||
326 | full_range: 1..21, | ||
327 | name: "main", | ||
328 | kind: FN_DEF, | ||
329 | focus_range: Some( | ||
330 | 12..16, | ||
331 | ), | ||
332 | container_name: None, | ||
333 | description: None, | ||
334 | docs: None, | ||
335 | }, | ||
283 | kind: Bin, | 336 | kind: Bin, |
284 | cfg_exprs: [], | 337 | cfg_exprs: [], |
285 | }, | 338 | }, |
286 | Runnable { | 339 | Runnable { |
287 | range: 22..64, | 340 | nav: NavigationTarget { |
341 | file_id: FileId( | ||
342 | 1, | ||
343 | ), | ||
344 | full_range: 22..64, | ||
345 | name: "foo", | ||
346 | kind: FN_DEF, | ||
347 | focus_range: Some( | ||
348 | 56..59, | ||
349 | ), | ||
350 | container_name: None, | ||
351 | description: None, | ||
352 | docs: None, | ||
353 | }, | ||
288 | kind: DocTest { | 354 | kind: DocTest { |
289 | test_id: Path( | 355 | test_id: Path( |
290 | "foo", | 356 | "foo", |
@@ -319,12 +385,38 @@ mod tests { | |||
319 | @r###" | 385 | @r###" |
320 | [ | 386 | [ |
321 | Runnable { | 387 | Runnable { |
322 | range: 1..21, | 388 | nav: NavigationTarget { |
389 | file_id: FileId( | ||
390 | 1, | ||
391 | ), | ||
392 | full_range: 1..21, | ||
393 | name: "main", | ||
394 | kind: FN_DEF, | ||
395 | focus_range: Some( | ||
396 | 12..16, | ||
397 | ), | ||
398 | container_name: None, | ||
399 | description: None, | ||
400 | docs: None, | ||
401 | }, | ||
323 | kind: Bin, | 402 | kind: Bin, |
324 | cfg_exprs: [], | 403 | cfg_exprs: [], |
325 | }, | 404 | }, |
326 | Runnable { | 405 | Runnable { |
327 | range: 51..105, | 406 | nav: NavigationTarget { |
407 | file_id: FileId( | ||
408 | 1, | ||
409 | ), | ||
410 | full_range: 51..105, | ||
411 | name: "foo", | ||
412 | kind: FN_DEF, | ||
413 | focus_range: Some( | ||
414 | 97..100, | ||
415 | ), | ||
416 | container_name: None, | ||
417 | description: None, | ||
418 | docs: None, | ||
419 | }, | ||
328 | kind: DocTest { | 420 | kind: DocTest { |
329 | test_id: Path( | 421 | test_id: Path( |
330 | "Data::foo", | 422 | "Data::foo", |
@@ -354,14 +446,40 @@ mod tests { | |||
354 | @r###" | 446 | @r###" |
355 | [ | 447 | [ |
356 | Runnable { | 448 | Runnable { |
357 | range: 1..59, | 449 | nav: NavigationTarget { |
450 | file_id: FileId( | ||
451 | 1, | ||
452 | ), | ||
453 | full_range: 1..59, | ||
454 | name: "test_mod", | ||
455 | kind: MODULE, | ||
456 | focus_range: Some( | ||
457 | 13..21, | ||
458 | ), | ||
459 | container_name: None, | ||
460 | description: None, | ||
461 | docs: None, | ||
462 | }, | ||
358 | kind: TestMod { | 463 | kind: TestMod { |
359 | path: "test_mod", | 464 | path: "test_mod", |
360 | }, | 465 | }, |
361 | cfg_exprs: [], | 466 | cfg_exprs: [], |
362 | }, | 467 | }, |
363 | Runnable { | 468 | Runnable { |
364 | range: 28..57, | 469 | nav: NavigationTarget { |
470 | file_id: FileId( | ||
471 | 1, | ||
472 | ), | ||
473 | full_range: 28..57, | ||
474 | name: "test_foo1", | ||
475 | kind: FN_DEF, | ||
476 | focus_range: Some( | ||
477 | 43..52, | ||
478 | ), | ||
479 | container_name: None, | ||
480 | description: None, | ||
481 | docs: None, | ||
482 | }, | ||
365 | kind: Test { | 483 | kind: Test { |
366 | test_id: Path( | 484 | test_id: Path( |
367 | "test_mod::test_foo1", | 485 | "test_mod::test_foo1", |
@@ -396,14 +514,40 @@ mod tests { | |||
396 | @r###" | 514 | @r###" |
397 | [ | 515 | [ |
398 | Runnable { | 516 | Runnable { |
399 | range: 23..85, | 517 | nav: NavigationTarget { |
518 | file_id: FileId( | ||
519 | 1, | ||
520 | ), | ||
521 | full_range: 23..85, | ||
522 | name: "test_mod", | ||
523 | kind: MODULE, | ||
524 | focus_range: Some( | ||
525 | 27..35, | ||
526 | ), | ||
527 | container_name: None, | ||
528 | description: None, | ||
529 | docs: None, | ||
530 | }, | ||
400 | kind: TestMod { | 531 | kind: TestMod { |
401 | path: "foo::test_mod", | 532 | path: "foo::test_mod", |
402 | }, | 533 | }, |
403 | cfg_exprs: [], | 534 | cfg_exprs: [], |
404 | }, | 535 | }, |
405 | Runnable { | 536 | Runnable { |
406 | range: 46..79, | 537 | nav: NavigationTarget { |
538 | file_id: FileId( | ||
539 | 1, | ||
540 | ), | ||
541 | full_range: 46..79, | ||
542 | name: "test_foo1", | ||
543 | kind: FN_DEF, | ||
544 | focus_range: Some( | ||
545 | 65..74, | ||
546 | ), | ||
547 | container_name: None, | ||
548 | description: None, | ||
549 | docs: None, | ||
550 | }, | ||
407 | kind: Test { | 551 | kind: Test { |
408 | test_id: Path( | 552 | test_id: Path( |
409 | "foo::test_mod::test_foo1", | 553 | "foo::test_mod::test_foo1", |
@@ -440,14 +584,40 @@ mod tests { | |||
440 | @r###" | 584 | @r###" |
441 | [ | 585 | [ |
442 | Runnable { | 586 | Runnable { |
443 | range: 41..115, | 587 | nav: NavigationTarget { |
588 | file_id: FileId( | ||
589 | 1, | ||
590 | ), | ||
591 | full_range: 41..115, | ||
592 | name: "test_mod", | ||
593 | kind: MODULE, | ||
594 | focus_range: Some( | ||
595 | 45..53, | ||
596 | ), | ||
597 | container_name: None, | ||
598 | description: None, | ||
599 | docs: None, | ||
600 | }, | ||
444 | kind: TestMod { | 601 | kind: TestMod { |
445 | path: "foo::bar::test_mod", | 602 | path: "foo::bar::test_mod", |
446 | }, | 603 | }, |
447 | cfg_exprs: [], | 604 | cfg_exprs: [], |
448 | }, | 605 | }, |
449 | Runnable { | 606 | Runnable { |
450 | range: 68..105, | 607 | nav: NavigationTarget { |
608 | file_id: FileId( | ||
609 | 1, | ||
610 | ), | ||
611 | full_range: 68..105, | ||
612 | name: "test_foo1", | ||
613 | kind: FN_DEF, | ||
614 | focus_range: Some( | ||
615 | 91..100, | ||
616 | ), | ||
617 | container_name: None, | ||
618 | description: None, | ||
619 | docs: None, | ||
620 | }, | ||
451 | kind: Test { | 621 | kind: Test { |
452 | test_id: Path( | 622 | test_id: Path( |
453 | "foo::bar::test_mod::test_foo1", | 623 | "foo::bar::test_mod::test_foo1", |
@@ -479,7 +649,20 @@ mod tests { | |||
479 | @r###" | 649 | @r###" |
480 | [ | 650 | [ |
481 | Runnable { | 651 | Runnable { |
482 | range: 1..58, | 652 | nav: NavigationTarget { |
653 | file_id: FileId( | ||
654 | 1, | ||
655 | ), | ||
656 | full_range: 1..58, | ||
657 | name: "test_foo1", | ||
658 | kind: FN_DEF, | ||
659 | focus_range: Some( | ||
660 | 44..53, | ||
661 | ), | ||
662 | container_name: None, | ||
663 | description: None, | ||
664 | docs: None, | ||
665 | }, | ||
483 | kind: Test { | 666 | kind: Test { |
484 | test_id: Path( | 667 | test_id: Path( |
485 | "test_foo1", | 668 | "test_foo1", |
@@ -516,7 +699,20 @@ mod tests { | |||
516 | @r###" | 699 | @r###" |
517 | [ | 700 | [ |
518 | Runnable { | 701 | Runnable { |
519 | range: 1..80, | 702 | nav: NavigationTarget { |
703 | file_id: FileId( | ||
704 | 1, | ||
705 | ), | ||
706 | full_range: 1..80, | ||
707 | name: "test_foo1", | ||
708 | kind: FN_DEF, | ||
709 | focus_range: Some( | ||
710 | 66..75, | ||
711 | ), | ||
712 | container_name: None, | ||
713 | description: None, | ||
714 | docs: None, | ||
715 | }, | ||
520 | kind: Test { | 716 | kind: Test { |
521 | test_id: Path( | 717 | test_id: Path( |
522 | "test_foo1", | 718 | "test_foo1", |
diff --git a/crates/ra_ide/src/snapshots/highlight_injection.html b/crates/ra_ide/src/snapshots/highlight_injection.html index 68fc589bc..fcdc98201 100644 --- a/crates/ra_ide/src/snapshots/highlight_injection.html +++ b/crates/ra_ide/src/snapshots/highlight_injection.html | |||
@@ -10,6 +10,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
10 | .string_literal { color: #CC9393; } | 10 | .string_literal { color: #CC9393; } |
11 | .field { color: #94BFF3; } | 11 | .field { color: #94BFF3; } |
12 | .function { color: #93E0E3; } | 12 | .function { color: #93E0E3; } |
13 | .operator.unsafe { color: #E28C14; } | ||
13 | .parameter { color: #94BFF3; } | 14 | .parameter { color: #94BFF3; } |
14 | .text { color: #DCDCCC; } | 15 | .text { color: #DCDCCC; } |
15 | .type { color: #7CB8BB; } | 16 | .type { color: #7CB8BB; } |
diff --git a/crates/ra_ide/src/snapshots/highlight_strings.html b/crates/ra_ide/src/snapshots/highlight_strings.html index 326744361..e97192b61 100644 --- a/crates/ra_ide/src/snapshots/highlight_strings.html +++ b/crates/ra_ide/src/snapshots/highlight_strings.html | |||
@@ -10,6 +10,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
10 | .string_literal { color: #CC9393; } | 10 | .string_literal { color: #CC9393; } |
11 | .field { color: #94BFF3; } | 11 | .field { color: #94BFF3; } |
12 | .function { color: #93E0E3; } | 12 | .function { color: #93E0E3; } |
13 | .operator.unsafe { color: #E28C14; } | ||
13 | .parameter { color: #94BFF3; } | 14 | .parameter { color: #94BFF3; } |
14 | .text { color: #DCDCCC; } | 15 | .text { color: #DCDCCC; } |
15 | .type { color: #7CB8BB; } | 16 | .type { color: #7CB8BB; } |
@@ -52,6 +53,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
52 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal">"</span>, argument = <span class="string_literal">"test"</span>); <span class="comment">// => "test"</span> | 53 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal">"</span>, argument = <span class="string_literal">"test"</span>); <span class="comment">// => "test"</span> |
53 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span>, <span class="numeric_literal">1</span>, name = <span class="numeric_literal">2</span>); <span class="comment">// => "2 1"</span> | 54 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span>, <span class="numeric_literal">1</span>, name = <span class="numeric_literal">2</span>); <span class="comment">// => "2 1"</span> |
54 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal">"</span>, a=<span class="string_literal">"a"</span>, b=<span class="char_literal">'b'</span>, c=<span class="numeric_literal">3</span>); <span class="comment">// => "a 3 b"</span> | 55 | <span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal">"</span>, a=<span class="string_literal">"a"</span>, b=<span class="char_literal">'b'</span>, c=<span class="numeric_literal">3</span>); <span class="comment">// => "a 3 b"</span> |
56 | <span class="macro">println!</span>(<span class="string_literal">"{{</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">}}"</span>, <span class="numeric_literal">2</span>); <span class="comment">// => "{2}"</span> | ||
55 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>); | 57 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>); |
56 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>, <span class="numeric_literal">5</span>); | 58 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"x"</span>, <span class="numeric_literal">5</span>); |
57 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">5</span>, <span class="string_literal">"x"</span>); | 59 | <span class="macro">println!</span>(<span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="numeric_literal">5</span>, <span class="string_literal">"x"</span>); |
diff --git a/crates/ra_ide/src/snapshots/highlight_unsafe.html b/crates/ra_ide/src/snapshots/highlight_unsafe.html new file mode 100644 index 000000000..17ffc727c --- /dev/null +++ b/crates/ra_ide/src/snapshots/highlight_unsafe.html | |||
@@ -0,0 +1,48 @@ | |||
1 | |||
2 | <style> | ||
3 | body { margin: 0; } | ||
4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | ||
5 | |||
6 | .lifetime { color: #DFAF8F; font-style: italic; } | ||
7 | .comment { color: #7F9F7F; } | ||
8 | .struct, .enum { color: #7CB8BB; } | ||
9 | .enum_variant { color: #BDE0F3; } | ||
10 | .string_literal { color: #CC9393; } | ||
11 | .field { color: #94BFF3; } | ||
12 | .function { color: #93E0E3; } | ||
13 | .operator.unsafe { color: #E28C14; } | ||
14 | .parameter { color: #94BFF3; } | ||
15 | .text { color: #DCDCCC; } | ||
16 | .type { color: #7CB8BB; } | ||
17 | .builtin_type { color: #8CD0D3; } | ||
18 | .type_param { color: #DFAF8F; } | ||
19 | .attribute { color: #94BFF3; } | ||
20 | .numeric_literal { color: #BFEBBF; } | ||
21 | .bool_literal { color: #BFE6EB; } | ||
22 | .macro { color: #94BFF3; } | ||
23 | .module { color: #AFD8AF; } | ||
24 | .variable { color: #DCDCCC; } | ||
25 | .format_specifier { color: #CC696B; } | ||
26 | .mutable { text-decoration: underline; } | ||
27 | |||
28 | .keyword { color: #F0DFAF; font-weight: bold; } | ||
29 | .keyword.unsafe { color: #BC8383; font-weight: bold; } | ||
30 | .control { font-style: italic; } | ||
31 | </style> | ||
32 | <pre><code><span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_fn</span>() {} | ||
33 | |||
34 | <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span>; | ||
35 | |||
36 | <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> { | ||
37 | <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_method</span>(&<span class="self_keyword">self</span>) {} | ||
38 | } | ||
39 | |||
40 | <span class="keyword">fn</span> <span class="function declaration">main</span>() { | ||
41 | <span class="keyword">let</span> <span class="variable declaration">x</span> = &<span class="numeric_literal">5</span> <span class="keyword">as</span> *<span class="keyword">const</span> <span class="builtin_type">usize</span>; | ||
42 | <span class="keyword unsafe">unsafe</span> { | ||
43 | <span class="function unsafe">unsafe_fn</span>(); | ||
44 | <span class="struct">HasUnsafeFn</span>.<span class="function unsafe">unsafe_method</span>(); | ||
45 | <span class="keyword">let</span> <span class="variable declaration">y</span> = <span class="operator unsafe">*</span><span class="variable">x</span>; | ||
46 | <span class="keyword">let</span> <span class="variable declaration">z</span> = -<span class="variable">x</span>; | ||
47 | } | ||
48 | }</code></pre> \ No newline at end of file | ||
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html index 352e35095..42c5f3e55 100644 --- a/crates/ra_ide/src/snapshots/highlighting.html +++ b/crates/ra_ide/src/snapshots/highlighting.html | |||
@@ -10,6 +10,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
10 | .string_literal { color: #CC9393; } | 10 | .string_literal { color: #CC9393; } |
11 | .field { color: #94BFF3; } | 11 | .field { color: #94BFF3; } |
12 | .function { color: #93E0E3; } | 12 | .function { color: #93E0E3; } |
13 | .operator.unsafe { color: #E28C14; } | ||
13 | .parameter { color: #94BFF3; } | 14 | .parameter { color: #94BFF3; } |
14 | .text { color: #DCDCCC; } | 15 | .text { color: #DCDCCC; } |
15 | .type { color: #7CB8BB; } | 16 | .type { color: #7CB8BB; } |
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html index 2a0294f71..2dd61d20d 100644 --- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html +++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html | |||
@@ -10,6 +10,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
10 | .string_literal { color: #CC9393; } | 10 | .string_literal { color: #CC9393; } |
11 | .field { color: #94BFF3; } | 11 | .field { color: #94BFF3; } |
12 | .function { color: #93E0E3; } | 12 | .function { color: #93E0E3; } |
13 | .operator.unsafe { color: #E28C14; } | ||
13 | .parameter { color: #94BFF3; } | 14 | .parameter { color: #94BFF3; } |
14 | .text { color: #DCDCCC; } | 15 | .text { color: #DCDCCC; } |
15 | .type { color: #7CB8BB; } | 16 | .type { color: #7CB8BB; } |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 0b53ebe69..19ecd54d6 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -406,6 +406,23 @@ fn highlight_element( | |||
406 | _ => h, | 406 | _ => h, |
407 | } | 407 | } |
408 | } | 408 | } |
409 | PREFIX_EXPR => { | ||
410 | let prefix_expr = element.into_node().and_then(ast::PrefixExpr::cast)?; | ||
411 | match prefix_expr.op_kind() { | ||
412 | Some(ast::PrefixOp::Deref) => {} | ||
413 | _ => return None, | ||
414 | } | ||
415 | |||
416 | let expr = prefix_expr.expr()?; | ||
417 | let ty = sema.type_of_expr(&expr)?; | ||
418 | if !ty.is_raw_ptr() { | ||
419 | return None; | ||
420 | } | ||
421 | |||
422 | let mut h = Highlight::new(HighlightTag::Operator); | ||
423 | h |= HighlightModifier::Unsafe; | ||
424 | h | ||
425 | } | ||
409 | 426 | ||
410 | k if k.is_keyword() => { | 427 | k if k.is_keyword() => { |
411 | let h = Highlight::new(HighlightTag::Keyword); | 428 | let h = Highlight::new(HighlightTag::Keyword); |
@@ -458,7 +475,13 @@ fn highlight_name(db: &RootDatabase, def: Definition) -> Highlight { | |||
458 | Definition::Field(_) => HighlightTag::Field, | 475 | Definition::Field(_) => HighlightTag::Field, |
459 | Definition::ModuleDef(def) => match def { | 476 | Definition::ModuleDef(def) => match def { |
460 | hir::ModuleDef::Module(_) => HighlightTag::Module, | 477 | hir::ModuleDef::Module(_) => HighlightTag::Module, |
461 | hir::ModuleDef::Function(_) => HighlightTag::Function, | 478 | hir::ModuleDef::Function(func) => { |
479 | let mut h = HighlightTag::Function.into(); | ||
480 | if func.is_unsafe(db) { | ||
481 | h |= HighlightModifier::Unsafe; | ||
482 | } | ||
483 | return h; | ||
484 | } | ||
462 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, | 485 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, |
463 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, | 486 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, |
464 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, | 487 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, |
diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs index edfe61f39..7d946c98d 100644 --- a/crates/ra_ide/src/syntax_highlighting/html.rs +++ b/crates/ra_ide/src/syntax_highlighting/html.rs | |||
@@ -69,6 +69,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
69 | .string_literal { color: #CC9393; } | 69 | .string_literal { color: #CC9393; } |
70 | .field { color: #94BFF3; } | 70 | .field { color: #94BFF3; } |
71 | .function { color: #93E0E3; } | 71 | .function { color: #93E0E3; } |
72 | .operator.unsafe { color: #E28C14; } | ||
72 | .parameter { color: #94BFF3; } | 73 | .parameter { color: #94BFF3; } |
73 | .text { color: #DCDCCC; } | 74 | .text { color: #DCDCCC; } |
74 | .type { color: #7CB8BB; } | 75 | .type { color: #7CB8BB; } |
diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs index 1514531de..94f466966 100644 --- a/crates/ra_ide/src/syntax_highlighting/tags.rs +++ b/crates/ra_ide/src/syntax_highlighting/tags.rs | |||
@@ -24,12 +24,14 @@ pub enum HighlightTag { | |||
24 | Enum, | 24 | Enum, |
25 | EnumVariant, | 25 | EnumVariant, |
26 | Field, | 26 | Field, |
27 | FormatSpecifier, | ||
27 | Function, | 28 | Function, |
28 | Keyword, | 29 | Keyword, |
29 | Lifetime, | 30 | Lifetime, |
30 | Macro, | 31 | Macro, |
31 | Module, | 32 | Module, |
32 | NumericLiteral, | 33 | NumericLiteral, |
34 | Operator, | ||
33 | SelfKeyword, | 35 | SelfKeyword, |
34 | SelfType, | 36 | SelfType, |
35 | Static, | 37 | Static, |
@@ -41,8 +43,6 @@ pub enum HighlightTag { | |||
41 | Union, | 43 | Union, |
42 | Local, | 44 | Local, |
43 | UnresolvedReference, | 45 | UnresolvedReference, |
44 | FormatSpecifier, | ||
45 | Operator, | ||
46 | } | 46 | } |
47 | 47 | ||
48 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | 48 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
@@ -72,12 +72,14 @@ impl HighlightTag { | |||
72 | HighlightTag::Enum => "enum", | 72 | HighlightTag::Enum => "enum", |
73 | HighlightTag::EnumVariant => "enum_variant", | 73 | HighlightTag::EnumVariant => "enum_variant", |
74 | HighlightTag::Field => "field", | 74 | HighlightTag::Field => "field", |
75 | HighlightTag::FormatSpecifier => "format_specifier", | ||
75 | HighlightTag::Function => "function", | 76 | HighlightTag::Function => "function", |
76 | HighlightTag::Keyword => "keyword", | 77 | HighlightTag::Keyword => "keyword", |
77 | HighlightTag::Lifetime => "lifetime", | 78 | HighlightTag::Lifetime => "lifetime", |
78 | HighlightTag::Macro => "macro", | 79 | HighlightTag::Macro => "macro", |
79 | HighlightTag::Module => "module", | 80 | HighlightTag::Module => "module", |
80 | HighlightTag::NumericLiteral => "numeric_literal", | 81 | HighlightTag::NumericLiteral => "numeric_literal", |
82 | HighlightTag::Operator => "operator", | ||
81 | HighlightTag::SelfKeyword => "self_keyword", | 83 | HighlightTag::SelfKeyword => "self_keyword", |
82 | HighlightTag::SelfType => "self_type", | 84 | HighlightTag::SelfType => "self_type", |
83 | HighlightTag::Static => "static", | 85 | HighlightTag::Static => "static", |
@@ -89,8 +91,6 @@ impl HighlightTag { | |||
89 | HighlightTag::Union => "union", | 91 | HighlightTag::Union => "union", |
90 | HighlightTag::Local => "variable", | 92 | HighlightTag::Local => "variable", |
91 | HighlightTag::UnresolvedReference => "unresolved_reference", | 93 | HighlightTag::UnresolvedReference => "unresolved_reference", |
92 | HighlightTag::FormatSpecifier => "format_specifier", | ||
93 | HighlightTag::Operator => "operator", | ||
94 | } | 94 | } |
95 | } | 95 | } |
96 | } | 96 | } |
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index eb43a23da..36a1aa419 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs | |||
@@ -218,6 +218,7 @@ fn main() { | |||
218 | println!("{argument}", argument = "test"); // => "test" | 218 | println!("{argument}", argument = "test"); // => "test" |
219 | println!("{name} {}", 1, name = 2); // => "2 1" | 219 | println!("{name} {}", 1, name = 2); // => "2 1" |
220 | println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" | 220 | println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" |
221 | println!("{{{}}}", 2); // => "{2}" | ||
221 | println!("Hello {:5}!", "x"); | 222 | println!("Hello {:5}!", "x"); |
222 | println!("Hello {:1$}!", "x", 5); | 223 | println!("Hello {:1$}!", "x", 5); |
223 | println!("Hello {1:0$}!", 5, "x"); | 224 | println!("Hello {1:0$}!", 5, "x"); |
@@ -257,3 +258,34 @@ fn main() { | |||
257 | fs::write(dst_file, &actual_html).unwrap(); | 258 | fs::write(dst_file, &actual_html).unwrap(); |
258 | assert_eq_text!(expected_html, actual_html); | 259 | assert_eq_text!(expected_html, actual_html); |
259 | } | 260 | } |
261 | |||
262 | #[test] | ||
263 | fn test_unsafe_highlighting() { | ||
264 | let (analysis, file_id) = single_file( | ||
265 | r#" | ||
266 | unsafe fn unsafe_fn() {} | ||
267 | |||
268 | struct HasUnsafeFn; | ||
269 | |||
270 | impl HasUnsafeFn { | ||
271 | unsafe fn unsafe_method(&self) {} | ||
272 | } | ||
273 | |||
274 | fn main() { | ||
275 | let x = &5 as *const usize; | ||
276 | unsafe { | ||
277 | unsafe_fn(); | ||
278 | HasUnsafeFn.unsafe_method(); | ||
279 | let y = *x; | ||
280 | let z = -x; | ||
281 | } | ||
282 | } | ||
283 | "# | ||
284 | .trim(), | ||
285 | ); | ||
286 | let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_unsafe.html"); | ||
287 | let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); | ||
288 | let expected_html = &read_text(&dst_file); | ||
289 | fs::write(dst_file, &actual_html).unwrap(); | ||
290 | assert_eq_text!(expected_html, actual_html); | ||
291 | } | ||