diff options
33 files changed, 1092 insertions, 317 deletions
diff --git a/Cargo.lock b/Cargo.lock index 3b8df0c8a..db09967ba 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -87,6 +87,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
87 | 87 | ||
88 | [[package]] | 88 | [[package]] |
89 | name = "bitflags" | 89 | name = "bitflags" |
90 | version = "0.7.0" | ||
91 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
92 | |||
93 | [[package]] | ||
94 | name = "bitflags" | ||
90 | version = "1.0.4" | 95 | version = "1.0.4" |
91 | source = "registry+https://github.com/rust-lang/crates.io-index" | 96 | source = "registry+https://github.com/rust-lang/crates.io-index" |
92 | 97 | ||
@@ -110,6 +115,15 @@ version = "1.3.1" | |||
110 | source = "registry+https://github.com/rust-lang/crates.io-index" | 115 | source = "registry+https://github.com/rust-lang/crates.io-index" |
111 | 116 | ||
112 | [[package]] | 117 | [[package]] |
118 | name = "bytes" | ||
119 | version = "0.4.11" | ||
120 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
121 | dependencies = [ | ||
122 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
123 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
124 | ] | ||
125 | |||
126 | [[package]] | ||
113 | name = "cargo_metadata" | 127 | name = "cargo_metadata" |
114 | version = "0.7.1" | 128 | version = "0.7.1" |
115 | source = "registry+https://github.com/rust-lang/crates.io-index" | 129 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -336,6 +350,16 @@ version = "0.1.2" | |||
336 | source = "registry+https://github.com/rust-lang/crates.io-index" | 350 | source = "registry+https://github.com/rust-lang/crates.io-index" |
337 | 351 | ||
338 | [[package]] | 352 | [[package]] |
353 | name = "filetime" | ||
354 | version = "0.2.4" | ||
355 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
356 | dependencies = [ | ||
357 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
358 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
359 | "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", | ||
360 | ] | ||
361 | |||
362 | [[package]] | ||
339 | name = "flexi_logger" | 363 | name = "flexi_logger" |
340 | version = "0.10.5" | 364 | version = "0.10.5" |
341 | source = "registry+https://github.com/rust-lang/crates.io-index" | 365 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -352,6 +376,24 @@ version = "1.0.6" | |||
352 | source = "registry+https://github.com/rust-lang/crates.io-index" | 376 | source = "registry+https://github.com/rust-lang/crates.io-index" |
353 | 377 | ||
354 | [[package]] | 378 | [[package]] |
379 | name = "fsevent" | ||
380 | version = "0.2.17" | ||
381 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
382 | dependencies = [ | ||
383 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
384 | "fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
385 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
386 | ] | ||
387 | |||
388 | [[package]] | ||
389 | name = "fsevent-sys" | ||
390 | version = "0.1.6" | ||
391 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
392 | dependencies = [ | ||
393 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
394 | ] | ||
395 | |||
396 | [[package]] | ||
355 | name = "fst" | 397 | name = "fst" |
356 | version = "0.3.3" | 398 | version = "0.3.3" |
357 | source = "registry+https://github.com/rust-lang/crates.io-index" | 399 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -375,6 +417,11 @@ version = "0.3.3" | |||
375 | source = "registry+https://github.com/rust-lang/crates.io-index" | 417 | source = "registry+https://github.com/rust-lang/crates.io-index" |
376 | 418 | ||
377 | [[package]] | 419 | [[package]] |
420 | name = "futures" | ||
421 | version = "0.1.25" | ||
422 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
423 | |||
424 | [[package]] | ||
378 | name = "gen_lsp_server" | 425 | name = "gen_lsp_server" |
379 | version = "0.1.0" | 426 | version = "0.1.0" |
380 | dependencies = [ | 427 | dependencies = [ |
@@ -437,6 +484,28 @@ version = "1.0.2" | |||
437 | source = "registry+https://github.com/rust-lang/crates.io-index" | 484 | source = "registry+https://github.com/rust-lang/crates.io-index" |
438 | 485 | ||
439 | [[package]] | 486 | [[package]] |
487 | name = "inotify" | ||
488 | version = "0.6.1" | ||
489 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
490 | dependencies = [ | ||
491 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||
492 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", | ||
493 | "inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
494 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
495 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", | ||
496 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||
497 | "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
498 | ] | ||
499 | |||
500 | [[package]] | ||
501 | name = "inotify-sys" | ||
502 | version = "0.1.3" | ||
503 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
504 | dependencies = [ | ||
505 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
506 | ] | ||
507 | |||
508 | [[package]] | ||
440 | name = "insta" | 509 | name = "insta" |
441 | version = "0.5.2" | 510 | version = "0.5.2" |
442 | source = "registry+https://github.com/rust-lang/crates.io-index" | 511 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -456,6 +525,15 @@ dependencies = [ | |||
456 | ] | 525 | ] |
457 | 526 | ||
458 | [[package]] | 527 | [[package]] |
528 | name = "iovec" | ||
529 | version = "0.1.2" | ||
530 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
531 | dependencies = [ | ||
532 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
533 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
534 | ] | ||
535 | |||
536 | [[package]] | ||
459 | name = "itertools" | 537 | name = "itertools" |
460 | version = "0.8.0" | 538 | version = "0.8.0" |
461 | source = "registry+https://github.com/rust-lang/crates.io-index" | 539 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -474,11 +552,25 @@ version = "0.1.3" | |||
474 | source = "registry+https://github.com/rust-lang/crates.io-index" | 552 | source = "registry+https://github.com/rust-lang/crates.io-index" |
475 | 553 | ||
476 | [[package]] | 554 | [[package]] |
555 | name = "kernel32-sys" | ||
556 | version = "0.2.2" | ||
557 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
558 | dependencies = [ | ||
559 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
560 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
561 | ] | ||
562 | |||
563 | [[package]] | ||
477 | name = "lazy_static" | 564 | name = "lazy_static" |
478 | version = "1.2.0" | 565 | version = "1.2.0" |
479 | source = "registry+https://github.com/rust-lang/crates.io-index" | 566 | source = "registry+https://github.com/rust-lang/crates.io-index" |
480 | 567 | ||
481 | [[package]] | 568 | [[package]] |
569 | name = "lazycell" | ||
570 | version = "1.2.1" | ||
571 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
572 | |||
573 | [[package]] | ||
482 | name = "libc" | 574 | name = "libc" |
483 | version = "0.2.48" | 575 | version = "0.2.48" |
484 | source = "registry+https://github.com/rust-lang/crates.io-index" | 576 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -511,7 +603,7 @@ version = "0.55.1" | |||
511 | source = "registry+https://github.com/rust-lang/crates.io-index" | 603 | source = "registry+https://github.com/rust-lang/crates.io-index" |
512 | dependencies = [ | 604 | dependencies = [ |
513 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", | 605 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", |
514 | "num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", | 606 | "num-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", |
515 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", | 607 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", |
516 | "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", | 608 | "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", |
517 | "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", | 609 | "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -554,16 +646,83 @@ version = "0.2.1" | |||
554 | source = "registry+https://github.com/rust-lang/crates.io-index" | 646 | source = "registry+https://github.com/rust-lang/crates.io-index" |
555 | 647 | ||
556 | [[package]] | 648 | [[package]] |
649 | name = "mio" | ||
650 | version = "0.6.16" | ||
651 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
652 | dependencies = [ | ||
653 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
654 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
655 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
656 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
657 | "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
658 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
659 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
660 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
661 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", | ||
662 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
663 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
664 | ] | ||
665 | |||
666 | [[package]] | ||
667 | name = "mio-extras" | ||
668 | version = "2.0.5" | ||
669 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
670 | dependencies = [ | ||
671 | "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
672 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
673 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", | ||
674 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
675 | ] | ||
676 | |||
677 | [[package]] | ||
678 | name = "miow" | ||
679 | version = "0.2.1" | ||
680 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
681 | dependencies = [ | ||
682 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
683 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", | ||
684 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
685 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
686 | ] | ||
687 | |||
688 | [[package]] | ||
689 | name = "net2" | ||
690 | version = "0.2.33" | ||
691 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
692 | dependencies = [ | ||
693 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
694 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
695 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
696 | ] | ||
697 | |||
698 | [[package]] | ||
557 | name = "nodrop" | 699 | name = "nodrop" |
558 | version = "0.1.13" | 700 | version = "0.1.13" |
559 | source = "registry+https://github.com/rust-lang/crates.io-index" | 701 | source = "registry+https://github.com/rust-lang/crates.io-index" |
560 | 702 | ||
561 | [[package]] | 703 | [[package]] |
704 | name = "notify" | ||
705 | version = "4.0.7" | ||
706 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
707 | dependencies = [ | ||
708 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||
709 | "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||
710 | "fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", | ||
711 | "fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
712 | "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
713 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
714 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", | ||
715 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", | ||
716 | "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||
717 | "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", | ||
718 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
719 | ] | ||
720 | |||
721 | [[package]] | ||
562 | name = "num-derive" | 722 | name = "num-derive" |
563 | version = "0.2.3" | 723 | version = "0.2.4" |
564 | source = "registry+https://github.com/rust-lang/crates.io-index" | 724 | source = "registry+https://github.com/rust-lang/crates.io-index" |
565 | dependencies = [ | 725 | dependencies = [ |
566 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
567 | "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", | 726 | "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", |
568 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | 727 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", |
569 | "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", | 728 | "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -726,7 +885,7 @@ dependencies = [ | |||
726 | "ra_syntax 0.1.0", | 885 | "ra_syntax 0.1.0", |
727 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 886 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
728 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 887 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
729 | "salsa 0.10.0-alpha4 (registry+https://github.com/rust-lang/crates.io-index)", | 888 | "salsa 0.10.0-alpha5 (registry+https://github.com/rust-lang/crates.io-index)", |
730 | "test_utils 0.1.0", | 889 | "test_utils 0.1.0", |
731 | ] | 890 | ] |
732 | 891 | ||
@@ -849,7 +1008,11 @@ name = "ra_vfs" | |||
849 | version = "0.1.0" | 1008 | version = "0.1.0" |
850 | dependencies = [ | 1009 | dependencies = [ |
851 | "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1010 | "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1011 | "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1012 | "flexi_logger 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||
852 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1013 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1014 | "notify 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1015 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
853 | "ra_arena 0.1.0", | 1016 | "ra_arena 0.1.0", |
854 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1017 | "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
855 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1018 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1097,7 +1260,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1097 | 1260 | ||
1098 | [[package]] | 1261 | [[package]] |
1099 | name = "salsa" | 1262 | name = "salsa" |
1100 | version = "0.10.0-alpha4" | 1263 | version = "0.10.0-alpha5" |
1101 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1102 | dependencies = [ | 1265 | dependencies = [ |
1103 | "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1266 | "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1106,13 +1269,13 @@ dependencies = [ | |||
1106 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1269 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1107 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1270 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1108 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1271 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1109 | "salsa-macros 0.10.0-alpha4 (registry+https://github.com/rust-lang/crates.io-index)", | 1272 | "salsa-macros 0.10.0-alpha5 (registry+https://github.com/rust-lang/crates.io-index)", |
1110 | "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1273 | "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1111 | ] | 1274 | ] |
1112 | 1275 | ||
1113 | [[package]] | 1276 | [[package]] |
1114 | name = "salsa-macros" | 1277 | name = "salsa-macros" |
1115 | version = "0.10.0-alpha4" | 1278 | version = "0.10.0-alpha5" |
1116 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1117 | dependencies = [ | 1280 | dependencies = [ |
1118 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1281 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1199,6 +1362,11 @@ dependencies = [ | |||
1199 | ] | 1362 | ] |
1200 | 1363 | ||
1201 | [[package]] | 1364 | [[package]] |
1365 | name = "slab" | ||
1366 | version = "0.4.2" | ||
1367 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1368 | |||
1369 | [[package]] | ||
1202 | name = "slug" | 1370 | name = "slug" |
1203 | version = "0.1.4" | 1371 | version = "0.1.4" |
1204 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1372 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1382,6 +1550,42 @@ dependencies = [ | |||
1382 | ] | 1550 | ] |
1383 | 1551 | ||
1384 | [[package]] | 1552 | [[package]] |
1553 | name = "tokio-executor" | ||
1554 | version = "0.1.6" | ||
1555 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1556 | dependencies = [ | ||
1557 | "crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1558 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1559 | ] | ||
1560 | |||
1561 | [[package]] | ||
1562 | name = "tokio-io" | ||
1563 | version = "0.1.11" | ||
1564 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1565 | dependencies = [ | ||
1566 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1567 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1568 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1569 | ] | ||
1570 | |||
1571 | [[package]] | ||
1572 | name = "tokio-reactor" | ||
1573 | version = "0.1.8" | ||
1574 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1575 | dependencies = [ | ||
1576 | "crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1577 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1578 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1579 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1580 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1581 | "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1582 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1583 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1584 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1585 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1586 | ] | ||
1587 | |||
1588 | [[package]] | ||
1385 | name = "tools" | 1589 | name = "tools" |
1386 | version = "0.1.0" | 1590 | version = "0.1.0" |
1387 | dependencies = [ | 1591 | dependencies = [ |
@@ -1557,6 +1761,11 @@ dependencies = [ | |||
1557 | 1761 | ||
1558 | [[package]] | 1762 | [[package]] |
1559 | name = "winapi" | 1763 | name = "winapi" |
1764 | version = "0.2.8" | ||
1765 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1766 | |||
1767 | [[package]] | ||
1768 | name = "winapi" | ||
1560 | version = "0.3.6" | 1769 | version = "0.3.6" |
1561 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1770 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1562 | dependencies = [ | 1771 | dependencies = [ |
@@ -1565,6 +1774,11 @@ dependencies = [ | |||
1565 | ] | 1774 | ] |
1566 | 1775 | ||
1567 | [[package]] | 1776 | [[package]] |
1777 | name = "winapi-build" | ||
1778 | version = "0.1.1" | ||
1779 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1780 | |||
1781 | [[package]] | ||
1568 | name = "winapi-i686-pc-windows-gnu" | 1782 | name = "winapi-i686-pc-windows-gnu" |
1569 | version = "0.4.0" | 1783 | version = "0.4.0" |
1570 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1583,6 +1797,15 @@ version = "0.4.0" | |||
1583 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1797 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1584 | 1798 | ||
1585 | [[package]] | 1799 | [[package]] |
1800 | name = "ws2_32-sys" | ||
1801 | version = "0.2.1" | ||
1802 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1803 | dependencies = [ | ||
1804 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1805 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1806 | ] | ||
1807 | |||
1808 | [[package]] | ||
1586 | name = "yaml-rust" | 1809 | name = "yaml-rust" |
1587 | version = "0.4.2" | 1810 | version = "0.4.2" |
1588 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1811 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1602,10 +1825,12 @@ dependencies = [ | |||
1602 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" | 1825 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" |
1603 | "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a" | 1826 | "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a" |
1604 | "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf" | 1827 | "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf" |
1828 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" | ||
1605 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" | 1829 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" |
1606 | "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" | 1830 | "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" |
1607 | "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" | 1831 | "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" |
1608 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" | 1832 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" |
1833 | "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" | ||
1609 | "checksum cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "585784cac9b05c93a53b17a0b24a5cdd1dfdda5256f030e089b549d2390cc720" | 1834 | "checksum cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "585784cac9b05c93a53b17a0b24a5cdd1dfdda5256f030e089b549d2390cc720" |
1610 | "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" | 1835 | "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" |
1611 | "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" | 1836 | "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" |
@@ -1633,11 +1858,15 @@ dependencies = [ | |||
1633 | "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" | 1858 | "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" |
1634 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" | 1859 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" |
1635 | "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" | 1860 | "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" |
1861 | "checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646" | ||
1636 | "checksum flexi_logger 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bbd731387787f54fa333fa426e173fe42ea3d1123636b2b27ad802025fc5d182" | 1862 | "checksum flexi_logger 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bbd731387787f54fa333fa426e173fe42ea3d1123636b2b27ad802025fc5d182" |
1637 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" | 1863 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" |
1864 | "checksum fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c4bbbf71584aeed076100b5665ac14e3d85eeb31fdbb45fbd41ef9a682b5ec05" | ||
1865 | "checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874" | ||
1638 | "checksum fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "db72126ca7dff566cdbbdd54af44668c544897d9d3862b198141f176f1238bdf" | 1866 | "checksum fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "db72126ca7dff566cdbbdd54af44668c544897d9d3862b198141f176f1238bdf" |
1639 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" | 1867 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" |
1640 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" | 1868 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" |
1869 | "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" | ||
1641 | "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" | 1870 | "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" |
1642 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" | 1871 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" |
1643 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" | 1872 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" |
@@ -1645,11 +1874,16 @@ dependencies = [ | |||
1645 | "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" | 1874 | "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" |
1646 | "checksum im 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0627d417829c1d763d602687634869f254fc79f7e22dea6c824dab993db857e4" | 1875 | "checksum im 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0627d417829c1d763d602687634869f254fc79f7e22dea6c824dab993db857e4" |
1647 | "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" | 1876 | "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" |
1877 | "checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" | ||
1878 | "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" | ||
1648 | "checksum insta 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff57d9cbc4664b54a972c321155c7703794bc0f5c9944f29c36f40d10d626f3" | 1879 | "checksum insta 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff57d9cbc4664b54a972c321155c7703794bc0f5c9944f29c36f40d10d626f3" |
1880 | "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" | ||
1649 | "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" | 1881 | "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" |
1650 | "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" | 1882 | "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" |
1651 | "checksum join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc7a5290e8c2606ce2be49f456d50f69173cb96d1541e4f66e34ac8b331a98f" | 1883 | "checksum join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc7a5290e8c2606ce2be49f456d50f69173cb96d1541e4f66e34ac8b331a98f" |
1884 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" | ||
1652 | "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" | 1885 | "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" |
1886 | "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" | ||
1653 | "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" | 1887 | "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" |
1654 | "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" | 1888 | "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" |
1655 | "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" | 1889 | "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" |
@@ -1660,8 +1894,13 @@ dependencies = [ | |||
1660 | "checksum memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1dd4eaac298c32ce07eb6ed9242eda7d82955b9170b7d6db59b2e02cc63fcb8" | 1894 | "checksum memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1dd4eaac298c32ce07eb6ed9242eda7d82955b9170b7d6db59b2e02cc63fcb8" |
1661 | "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" | 1895 | "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" |
1662 | "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" | 1896 | "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" |
1897 | "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" | ||
1898 | "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" | ||
1899 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" | ||
1900 | "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" | ||
1663 | "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" | 1901 | "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" |
1664 | "checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d" | 1902 | "checksum notify 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c968cf37cf949114b00d51b0b23536d1c3a4a3963767cf4c969c65a6af78dc7d" |
1903 | "checksum num-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d9fe8fcafd1b86a37ce8a1cfa15ae504817e0c8c2e7ad42767371461ac1d316d" | ||
1665 | "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" | 1904 | "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" |
1666 | "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" | 1905 | "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" |
1667 | "checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" | 1906 | "checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" |
@@ -1704,8 +1943,8 @@ dependencies = [ | |||
1704 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" | 1943 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" |
1705 | "checksum rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c" | 1944 | "checksum rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c" |
1706 | "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" | 1945 | "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" |
1707 | "checksum salsa 0.10.0-alpha4 (registry+https://github.com/rust-lang/crates.io-index)" = "3f442595eae948da8fbb2aa1e13940d9d2d70031753a27a5d1434f91b706ff12" | 1946 | "checksum salsa 0.10.0-alpha5 (registry+https://github.com/rust-lang/crates.io-index)" = "8b5e2535d707dc5ced81106d3b71d806cfeef8a6e8a567472fde7ffd56b770dd" |
1708 | "checksum salsa-macros 0.10.0-alpha4 (registry+https://github.com/rust-lang/crates.io-index)" = "2e6c1a1bee4eb44881438e80c1a26db1c3b957b6cc51765615d429019babdec2" | 1947 | "checksum salsa-macros 0.10.0-alpha5 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c5da4c649f6d4fc1864fcd9a379b1f7c6d570b278559c84a6e15981c949cc6" |
1709 | "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" | 1948 | "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" |
1710 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" | 1949 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" |
1711 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" | 1950 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" |
@@ -1715,6 +1954,7 @@ dependencies = [ | |||
1715 | "checksum serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "4b90a9fbe1211e57d3e1c15670f1cb00802988fb23a1a4aad7a2b63544f1920e" | 1954 | "checksum serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "4b90a9fbe1211e57d3e1c15670f1cb00802988fb23a1a4aad7a2b63544f1920e" |
1716 | "checksum serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0887a8e097a69559b56aa2526bf7aff7c3048cf627dff781f0b56a6001534593" | 1955 | "checksum serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0887a8e097a69559b56aa2526bf7aff7c3048cf627dff781f0b56a6001534593" |
1717 | "checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded" | 1956 | "checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded" |
1957 | "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" | ||
1718 | "checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" | 1958 | "checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" |
1719 | "checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" | 1959 | "checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" |
1720 | "checksum smol_str 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9af1035bc5d742ab6b7ab16713e41cc2ffe78cb474f6f43cd696b2d16052007e" | 1960 | "checksum smol_str 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9af1035bc5d742ab6b7ab16713e41cc2ffe78cb474f6f43cd696b2d16052007e" |
@@ -1733,6 +1973,9 @@ dependencies = [ | |||
1733 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" | 1973 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" |
1734 | "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" | 1974 | "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" |
1735 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" | 1975 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" |
1976 | "checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" | ||
1977 | "checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f" | ||
1978 | "checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f" | ||
1736 | "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" | 1979 | "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" |
1737 | "checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" | 1980 | "checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" |
1738 | "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" | 1981 | "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" |
@@ -1757,8 +2000,11 @@ dependencies = [ | |||
1757 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" | 2000 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" |
1758 | "checksum wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349" | 2001 | "checksum wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349" |
1759 | "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" | 2002 | "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" |
2003 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" | ||
1760 | "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" | 2004 | "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" |
2005 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" | ||
1761 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | 2006 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" |
1762 | "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" | 2007 | "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" |
1763 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | 2008 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
2009 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" | ||
1764 | "checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e" | 2010 | "checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e" |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 3a0aa7d24..6e17f33f0 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -20,7 +20,7 @@ pub use crate::{ | |||
20 | loc2id::LocationIntener, | 20 | loc2id::LocationIntener, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { | 23 | pub trait CheckCanceled: salsa::Database + panic::RefUnwindSafe { |
24 | /// Aborts current query if there are pending changes. | 24 | /// Aborts current query if there are pending changes. |
25 | /// | 25 | /// |
26 | /// rust-analyzer needs to be able to answer semantic questions about the | 26 | /// rust-analyzer needs to be able to answer semantic questions about the |
@@ -63,11 +63,15 @@ pub struct FileRange { | |||
63 | pub range: TextRange, | 63 | pub range: TextRange, |
64 | } | 64 | } |
65 | 65 | ||
66 | #[salsa::query_group(FilesDatabaseStorage)] | 66 | /// Database which stores all significant input facts: source code and project |
67 | pub trait FilesDatabase: salsa::Database { | 67 | /// model. Everything else in rust-analyzer is derived from these queries. |
68 | #[salsa::query_group(SourceDatabaseStorage)] | ||
69 | pub trait SourceDatabase: salsa::Database + CheckCanceled { | ||
68 | /// Text of the file. | 70 | /// Text of the file. |
69 | #[salsa::input] | 71 | #[salsa::input] |
70 | fn file_text(&self, file_id: FileId) -> Arc<String>; | 72 | fn file_text(&self, file_id: FileId) -> Arc<String>; |
73 | // Parses the file into the syntax tree. | ||
74 | fn parse(&self, file_id: FileId) -> TreeArc<SourceFile>; | ||
71 | /// Path to a file, relative to the root of its source root. | 75 | /// Path to a file, relative to the root of its source root. |
72 | #[salsa::input] | 76 | #[salsa::input] |
73 | fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; | 77 | fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; |
@@ -78,20 +82,12 @@ pub trait FilesDatabase: salsa::Database { | |||
78 | #[salsa::input] | 82 | #[salsa::input] |
79 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; | 83 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; |
80 | fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>; | 84 | fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>; |
81 | /// The set of "local" (that is, from the current workspace) roots. | ||
82 | /// Files in local roots are assumed to change frequently. | ||
83 | #[salsa::input] | ||
84 | fn local_roots(&self) -> Arc<Vec<SourceRootId>>; | ||
85 | /// The set of roots for crates.io libraries. | ||
86 | /// Files in libraries are assumed to never change. | ||
87 | #[salsa::input] | ||
88 | fn library_roots(&self) -> Arc<Vec<SourceRootId>>; | ||
89 | /// The crate graph. | 85 | /// The crate graph. |
90 | #[salsa::input] | 86 | #[salsa::input] |
91 | fn crate_graph(&self) -> Arc<CrateGraph>; | 87 | fn crate_graph(&self) -> Arc<CrateGraph>; |
92 | } | 88 | } |
93 | 89 | ||
94 | fn source_root_crates(db: &impl FilesDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { | 90 | fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { |
95 | let root = db.source_root(id); | 91 | let root = db.source_root(id); |
96 | let graph = db.crate_graph(); | 92 | let graph = db.crate_graph(); |
97 | let res = root | 93 | let res = root |
@@ -102,12 +98,7 @@ fn source_root_crates(db: &impl FilesDatabase, id: SourceRootId) -> Arc<Vec<Crat | |||
102 | Arc::new(res) | 98 | Arc::new(res) |
103 | } | 99 | } |
104 | 100 | ||
105 | #[salsa::query_group(SyntaxDatabaseStorage)] | 101 | fn parse(db: &impl SourceDatabase, file_id: FileId) -> TreeArc<SourceFile> { |
106 | pub trait SyntaxDatabase: FilesDatabase + BaseDatabase { | ||
107 | fn source_file(&self, file_id: FileId) -> TreeArc<SourceFile>; | ||
108 | } | ||
109 | |||
110 | fn source_file(db: &impl SyntaxDatabase, file_id: FileId) -> TreeArc<SourceFile> { | ||
111 | let text = db.file_text(file_id); | 102 | let text = db.file_text(file_id); |
112 | SourceFile::parse(&*text) | 103 | SourceFile::parse(&*text) |
113 | } | 104 | } |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index dfbf41bd6..5df4bd4a1 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; | 3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; |
4 | use ra_db::{SyntaxDatabase, CrateId, salsa}; | 4 | use ra_db::{SourceDatabase, CrateId, salsa}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | MacroCallId, HirFileId, | 7 | MacroCallId, HirFileId, |
@@ -19,9 +19,9 @@ use crate::{ | |||
19 | }; | 19 | }; |
20 | 20 | ||
21 | #[salsa::query_group(HirDatabaseStorage)] | 21 | #[salsa::query_group(HirDatabaseStorage)] |
22 | pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> { | 22 | pub trait HirDatabase: SourceDatabase + AsRef<HirInterner> { |
23 | #[salsa::invoke(HirFileId::hir_source_file)] | 23 | #[salsa::invoke(HirFileId::hir_parse)] |
24 | fn hir_source_file(&self, file_id: HirFileId) -> TreeArc<SourceFile>; | 24 | fn hir_parse(&self, file_id: HirFileId) -> TreeArc<SourceFile>; |
25 | 25 | ||
26 | #[salsa::invoke(crate::macros::expand_macro_invocation)] | 26 | #[salsa::invoke(crate::macros::expand_macro_invocation)] |
27 | fn expand_macro_invocation(&self, invoc: MacroCallId) -> Option<Arc<MacroExpansion>>; | 27 | fn expand_macro_invocation(&self, invoc: MacroCallId) -> Option<Arc<MacroExpansion>>; |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 5272656ec..7dd4b540e 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -86,12 +86,9 @@ impl HirFileId { | |||
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | pub(crate) fn hir_source_file( | 89 | pub(crate) fn hir_parse(db: &impl HirDatabase, file_id: HirFileId) -> TreeArc<SourceFile> { |
90 | db: &impl HirDatabase, | ||
91 | file_id: HirFileId, | ||
92 | ) -> TreeArc<SourceFile> { | ||
93 | match file_id.0 { | 90 | match file_id.0 { |
94 | HirFileIdRepr::File(file_id) => db.source_file(file_id), | 91 | HirFileIdRepr::File(file_id) => db.parse(file_id), |
95 | HirFileIdRepr::Macro(m) => { | 92 | HirFileIdRepr::Macro(m) => { |
96 | if let Some(exp) = db.expand_macro_invocation(m) { | 93 | if let Some(exp) = db.expand_macro_invocation(m) { |
97 | return exp.file(); | 94 | return exp.file(); |
@@ -370,7 +367,7 @@ impl SourceFileItems { | |||
370 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | 367 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), |
371 | ); | 368 | ); |
372 | } | 369 | } |
373 | pub fn id_of_source_file(&self) -> SourceFileItemId { | 370 | pub fn id_of_parse(&self) -> SourceFileItemId { |
374 | let (id, _syntax) = self.arena.iter().next().unwrap(); | 371 | let (id, _syntax) = self.arena.iter().next().unwrap(); |
375 | id | 372 | id |
376 | } | 373 | } |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 2dc252b1e..7da15eca0 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -2,7 +2,7 @@ use std::{sync::Arc, panic}; | |||
2 | 2 | ||
3 | use parking_lot::Mutex; | 3 | use parking_lot::Mutex; |
4 | use ra_db::{ | 4 | use ra_db::{ |
5 | BaseDatabase, FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, FilesDatabase, salsa, | 5 | CheckCanceled, FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa, |
6 | }; | 6 | }; |
7 | use relative_path::RelativePathBuf; | 7 | use relative_path::RelativePathBuf; |
8 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; | 8 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; |
@@ -11,11 +11,7 @@ use crate::{db, HirInterner}; | |||
11 | 11 | ||
12 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | 12 | pub const WORKSPACE: SourceRootId = SourceRootId(0); |
13 | 13 | ||
14 | #[salsa::database( | 14 | #[salsa::database(ra_db::SourceDatabaseStorage, db::HirDatabaseStorage)] |
15 | ra_db::FilesDatabaseStorage, | ||
16 | ra_db::SyntaxDatabaseStorage, | ||
17 | db::HirDatabaseStorage | ||
18 | )] | ||
19 | #[derive(Debug)] | 15 | #[derive(Debug)] |
20 | pub(crate) struct MockDatabase { | 16 | pub(crate) struct MockDatabase { |
21 | events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, | 17 | events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, |
@@ -144,8 +140,6 @@ impl Default for MockDatabase { | |||
144 | file_counter: 0, | 140 | file_counter: 0, |
145 | }; | 141 | }; |
146 | db.set_crate_graph(Default::default()); | 142 | db.set_crate_graph(Default::default()); |
147 | db.set_local_roots(Default::default()); | ||
148 | db.set_library_roots(Default::default()); | ||
149 | db | 143 | db |
150 | } | 144 | } |
151 | } | 145 | } |
@@ -161,7 +155,7 @@ impl salsa::ParallelDatabase for MockDatabase { | |||
161 | } | 155 | } |
162 | } | 156 | } |
163 | 157 | ||
164 | impl BaseDatabase for MockDatabase {} | 158 | impl CheckCanceled for MockDatabase {} |
165 | 159 | ||
166 | impl AsRef<HirInterner> for MockDatabase { | 160 | impl AsRef<HirInterner> for MockDatabase { |
167 | fn as_ref(&self) -> &HirInterner { | 161 | fn as_ref(&self) -> &HirInterner { |
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index b4fe99ea7..1d77548f3 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -129,7 +129,7 @@ impl LoweredModule { | |||
129 | let id = loc.id(db); | 129 | let id = loc.id(db); |
130 | let file_id = HirFileId::from(id); | 130 | let file_id = HirFileId::from(id); |
131 | //FIXME: expand recursively | 131 | //FIXME: expand recursively |
132 | for item in db.hir_source_file(file_id).items() { | 132 | for item in db.hir_parse(file_id).items() { |
133 | self.add_def_id(source_map, db, module, file_id, item); | 133 | self.add_def_id(source_map, db, module, file_id, item); |
134 | } | 134 | } |
135 | } | 135 | } |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 24936976c..e72781f51 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_db::{CrateGraph, SourceRootId, FilesDatabase}; | 3 | use ra_db::{CrateGraph, SourceRootId, SourceDatabase}; |
4 | use relative_path::RelativePath; | 4 | use relative_path::RelativePath; |
5 | use test_utils::{assert_eq_text, covers}; | 5 | use test_utils::{assert_eq_text, covers}; |
6 | 6 | ||
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index cf8c7e435..61c93a964 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -23,7 +23,7 @@ pub(super) fn fn_scopes(db: &impl HirDatabase, func: Function) -> Arc<FnScopes> | |||
23 | } | 23 | } |
24 | 24 | ||
25 | pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { | 25 | pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { |
26 | let source_file = db.hir_source_file(file_id); | 26 | let source_file = db.hir_parse(file_id); |
27 | let res = SourceFileItems::new(file_id, &source_file); | 27 | let res = SourceFileItems::new(file_id, &source_file); |
28 | Arc::new(res) | 28 | Arc::new(res) |
29 | } | 29 | } |
@@ -34,10 +34,7 @@ pub(super) fn file_item( | |||
34 | ) -> TreeArc<SyntaxNode> { | 34 | ) -> TreeArc<SyntaxNode> { |
35 | match source_item_id.item_id { | 35 | match source_item_id.item_id { |
36 | Some(id) => db.file_items(source_item_id.file_id)[id].to_owned(), | 36 | Some(id) => db.file_items(source_item_id.file_id)[id].to_owned(), |
37 | None => db | 37 | None => db.hir_parse(source_item_id.file_id).syntax().to_owned(), |
38 | .hir_source_file(source_item_id.file_id) | ||
39 | .syntax() | ||
40 | .to_owned(), | ||
41 | } | 38 | } |
42 | } | 39 | } |
43 | 40 | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index dbe040805..c0b3f1cd4 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -43,7 +43,7 @@ pub fn module_from_declaration( | |||
43 | 43 | ||
44 | /// Locates the module by position in the source code. | 44 | /// Locates the module by position in the source code. |
45 | pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { | 45 | pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { |
46 | let file = db.source_file(position.file_id); | 46 | let file = db.parse(position.file_id); |
47 | match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { | 47 | match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { |
48 | Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), | 48 | Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), |
49 | _ => module_from_file_id(db, position.file_id.into()), | 49 | _ => module_from_file_id(db, position.file_id.into()), |
@@ -95,7 +95,7 @@ fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Mod | |||
95 | } | 95 | } |
96 | 96 | ||
97 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { | 97 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { |
98 | let file = db.source_file(position.file_id); | 98 | let file = db.parse(position.file_id); |
99 | let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), position.offset)?; | 99 | let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), position.offset)?; |
100 | function_from_source(db, position.file_id, fn_def) | 100 | function_from_source(db, position.file_id, fn_def) |
101 | } | 101 | } |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 389bdaf23..e0b0689f8 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | use std::fmt::Write; | 2 | use std::fmt::Write; |
3 | 3 | ||
4 | use ra_db::{SyntaxDatabase, salsa::Database}; | 4 | use ra_db::{SourceDatabase, salsa::Database}; |
5 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
@@ -547,7 +547,7 @@ fn quux() { | |||
547 | 547 | ||
548 | fn infer(content: &str) -> String { | 548 | fn infer(content: &str) -> String { |
549 | let (db, _, file_id) = MockDatabase::with_single_file(content); | 549 | let (db, _, file_id) = MockDatabase::with_single_file(content); |
550 | let source_file = db.source_file(file_id); | 550 | let source_file = db.parse(file_id); |
551 | let mut acc = String::new(); | 551 | let mut acc = String::new(); |
552 | for fn_def in source_file | 552 | for fn_def in source_file |
553 | .syntax() | 553 | .syntax() |
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 0449c1902..3267fff96 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use ra_db::SyntaxDatabase; | 1 | use ra_db::SourceDatabase; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | AstNode, SyntaxNode, TextUnit, TextRange, | 3 | AstNode, SyntaxNode, TextUnit, TextRange, |
4 | SyntaxKind::FN_DEF, | 4 | SyntaxKind::FN_DEF, |
@@ -10,7 +10,7 @@ use crate::{FilePosition, CallInfo, db::RootDatabase}; | |||
10 | 10 | ||
11 | /// Computes parameter information for the given call expression. | 11 | /// Computes parameter information for the given call expression. |
12 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { | 12 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { |
13 | let file = db.source_file(position.file_id); | 13 | let file = db.parse(position.file_id); |
14 | let syntax = file.syntax(); | 14 | let syntax = file.syntax(); |
15 | 15 | ||
16 | // Find the calling expression and it's NameRef | 16 | // Find the calling expression and it's NameRef |
@@ -22,7 +22,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
22 | let symbol = file_symbols | 22 | let symbol = file_symbols |
23 | .into_iter() | 23 | .into_iter() |
24 | .find(|it| it.ptr.kind() == FN_DEF)?; | 24 | .find(|it| it.ptr.kind() == FN_DEF)?; |
25 | let fn_file = db.source_file(symbol.file_id); | 25 | let fn_file = db.parse(symbol.file_id); |
26 | let fn_def = symbol.ptr.to_node(&fn_file); | 26 | let fn_def = symbol.ptr.to_node(&fn_file); |
27 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); | 27 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); |
28 | let mut call_info = CallInfo::new(fn_def)?; | 28 | let mut call_info = CallInfo::new(fn_def)?; |
diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index 565d57c37..b1867de42 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs | |||
@@ -9,7 +9,7 @@ mod complete_path; | |||
9 | mod complete_scope; | 9 | mod complete_scope; |
10 | mod complete_postfix; | 10 | mod complete_postfix; |
11 | 11 | ||
12 | use ra_db::SyntaxDatabase; | 12 | use ra_db::SourceDatabase; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | db, | 15 | db, |
@@ -45,7 +45,7 @@ pub use crate::completion::completion_item::{CompletionItem, CompletionItemKind, | |||
45 | /// identifier prefix/fuzzy match should be done higher in the stack, together | 45 | /// identifier prefix/fuzzy match should be done higher in the stack, together |
46 | /// with ordering of completions (currently this is done by the client). | 46 | /// with ordering of completions (currently this is done by the client). |
47 | pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Option<Completions> { | 47 | pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Option<Completions> { |
48 | let original_file = db.source_file(position.file_id); | 48 | let original_file = db.parse(position.file_id); |
49 | let ctx = CompletionContext::new(db, &original_file, position)?; | 49 | let ctx = CompletionContext::new(db, &original_file, position)?; |
50 | 50 | ||
51 | let mut acc = Completions::default(); | 51 | let mut acc = Completions::default(); |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index 30891aed4..3da93ec35 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -1,15 +1,14 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_db::{ | 3 | use ra_db::{ |
4 | BaseDatabase, FileId, Canceled, | 4 | CheckCanceled, FileId, Canceled, SourceDatabase, |
5 | salsa::{self, Database}, | 5 | salsa, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{symbol_index, LineIndex}; | 8 | use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}}; |
9 | 9 | ||
10 | #[salsa::database( | 10 | #[salsa::database( |
11 | ra_db::FilesDatabaseStorage, | 11 | ra_db::SourceDatabaseStorage, |
12 | ra_db::SyntaxDatabaseStorage, | ||
13 | LineIndexDatabaseStorage, | 12 | LineIndexDatabaseStorage, |
14 | symbol_index::SymbolsDatabaseStorage, | 13 | symbol_index::SymbolsDatabaseStorage, |
15 | hir::db::HirDatabaseStorage | 14 | hir::db::HirDatabaseStorage |
@@ -35,12 +34,9 @@ impl Default for RootDatabase { | |||
35 | runtime: salsa::Runtime::default(), | 34 | runtime: salsa::Runtime::default(), |
36 | interner: Default::default(), | 35 | interner: Default::default(), |
37 | }; | 36 | }; |
38 | db.query_mut(ra_db::CrateGraphQuery) | 37 | db.set_crate_graph(Default::default()); |
39 | .set((), Default::default()); | 38 | db.set_local_roots(Default::default()); |
40 | db.query_mut(ra_db::LocalRootsQuery) | 39 | db.set_library_roots(Default::default()); |
41 | .set((), Default::default()); | ||
42 | db.query_mut(ra_db::LibraryRootsQuery) | ||
43 | .set((), Default::default()); | ||
44 | db | 40 | db |
45 | } | 41 | } |
46 | } | 42 | } |
@@ -54,7 +50,7 @@ impl salsa::ParallelDatabase for RootDatabase { | |||
54 | } | 50 | } |
55 | } | 51 | } |
56 | 52 | ||
57 | impl BaseDatabase for RootDatabase {} | 53 | impl CheckCanceled for RootDatabase {} |
58 | 54 | ||
59 | impl AsRef<hir::HirInterner> for RootDatabase { | 55 | impl AsRef<hir::HirInterner> for RootDatabase { |
60 | fn as_ref(&self) -> &hir::HirInterner { | 56 | fn as_ref(&self) -> &hir::HirInterner { |
@@ -63,11 +59,11 @@ impl AsRef<hir::HirInterner> for RootDatabase { | |||
63 | } | 59 | } |
64 | 60 | ||
65 | #[salsa::query_group(LineIndexDatabaseStorage)] | 61 | #[salsa::query_group(LineIndexDatabaseStorage)] |
66 | pub(crate) trait LineIndexDatabase: ra_db::FilesDatabase + BaseDatabase { | 62 | pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled { |
67 | fn line_index(&self, file_id: FileId) -> Arc<LineIndex>; | 63 | fn line_index(&self, file_id: FileId) -> Arc<LineIndex>; |
68 | } | 64 | } |
69 | 65 | ||
70 | fn line_index(db: &impl ra_db::FilesDatabase, file_id: FileId) -> Arc<LineIndex> { | 66 | fn line_index(db: &impl ra_db::SourceDatabase, file_id: FileId) -> Arc<LineIndex> { |
71 | let text = db.file_text(file_id); | 67 | let text = db.file_text(file_id); |
72 | Arc::new(LineIndex::new(&*text)) | 68 | Arc::new(LineIndex::new(&*text)) |
73 | } | 69 | } |
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs index 718b4def5..cd2ebe471 100644 --- a/crates/ra_ide_api/src/extend_selection.rs +++ b/crates/ra_ide_api/src/extend_selection.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use ra_db::SyntaxDatabase; | 1 | use ra_db::SourceDatabase; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | SyntaxNode, AstNode, SourceFile, | 3 | SyntaxNode, AstNode, SourceFile, |
4 | ast, algo::find_covering_node, | 4 | ast, algo::find_covering_node, |
@@ -10,7 +10,7 @@ use crate::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { | 12 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { |
13 | let source_file = db.source_file(frange.file_id); | 13 | let source_file = db.parse(frange.file_id); |
14 | if let Some(range) = extend_selection_in_macro(db, &source_file, frange) { | 14 | if let Some(range) = extend_selection_in_macro(db, &source_file, frange) { |
15 | return range; | 15 | return range; |
16 | } | 16 | } |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index dc0c50918..2a20c20ee 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use ra_db::{FileId, SyntaxDatabase}; | 1 | use ra_db::{FileId, SourceDatabase}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | AstNode, ast, | 3 | AstNode, ast, |
4 | algo::find_node_at_offset, | 4 | algo::find_node_at_offset, |
@@ -11,7 +11,7 @@ pub(crate) fn goto_definition( | |||
11 | db: &RootDatabase, | 11 | db: &RootDatabase, |
12 | position: FilePosition, | 12 | position: FilePosition, |
13 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { | 13 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { |
14 | let file = db.source_file(position.file_id); | 14 | let file = db.parse(position.file_id); |
15 | let syntax = file.syntax(); | 15 | let syntax = file.syntax(); |
16 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | 16 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { |
17 | let navs = reference_definition(db, position.file_id, name_ref).to_vec(); | 17 | let navs = reference_definition(db, position.file_id, name_ref).to_vec(); |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 4d4bfbc4d..ff9ae2d9c 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use ra_db::{SyntaxDatabase}; | 1 | use ra_db::SourceDatabase; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | AstNode, SyntaxNode, TreeArc, ast, | 3 | AstNode, SyntaxNode, TreeArc, ast, |
4 | algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}}, | 4 | algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}}, |
@@ -7,7 +7,7 @@ use ra_syntax::{ | |||
7 | use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget}; | 7 | use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget}; |
8 | 8 | ||
9 | pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<String>> { | 9 | pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<String>> { |
10 | let file = db.source_file(position.file_id); | 10 | let file = db.parse(position.file_id); |
11 | let mut res = Vec::new(); | 11 | let mut res = Vec::new(); |
12 | 12 | ||
13 | let mut range = None; | 13 | let mut range = None; |
@@ -53,7 +53,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
53 | } | 53 | } |
54 | 54 | ||
55 | pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { | 55 | pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { |
56 | let file = db.source_file(frange.file_id); | 56 | let file = db.parse(frange.file_id); |
57 | let syntax = file.syntax(); | 57 | let syntax = file.syntax(); |
58 | let leaf_node = find_covering_node(syntax, frange.range); | 58 | let leaf_node = find_covering_node(syntax, frange.range); |
59 | // if we picked identifier, expand to pattern/expression | 59 | // if we picked identifier, expand to pattern/expression |
@@ -88,7 +88,7 @@ fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Option<String> { | |||
88 | 88 | ||
89 | impl NavigationTarget { | 89 | impl NavigationTarget { |
90 | fn node(&self, db: &RootDatabase) -> Option<TreeArc<SyntaxNode>> { | 90 | fn node(&self, db: &RootDatabase) -> Option<TreeArc<SyntaxNode>> { |
91 | let source_file = db.source_file(self.file_id()); | 91 | let source_file = db.parse(self.file_id()); |
92 | let source_file = source_file.syntax(); | 92 | let source_file = source_file.syntax(); |
93 | let node = source_file | 93 | let node = source_file |
94 | .descendants() | 94 | .descendants() |
diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index bd9e3f1e3..399433a01 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs | |||
@@ -4,7 +4,7 @@ use hir::{ | |||
4 | self, Problem, source_binder | 4 | self, Problem, source_binder |
5 | }; | 5 | }; |
6 | use ra_db::{ | 6 | use ra_db::{ |
7 | FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase, | 7 | SourceDatabase, SourceRoot, SourceRootId, |
8 | salsa::{Database, SweepStrategy}, | 8 | salsa::{Database, SweepStrategy}, |
9 | }; | 9 | }; |
10 | use ra_ide_api_light::{self, assists, LocalEdit, Severity}; | 10 | use ra_ide_api_light::{self, assists, LocalEdit, Severity}; |
@@ -76,9 +76,9 @@ impl db::RootDatabase { | |||
76 | /// syntax trees. However, if we actually do that, everything is recomputed | 76 | /// syntax trees. However, if we actually do that, everything is recomputed |
77 | /// for some reason. Needs investigation. | 77 | /// for some reason. Needs investigation. |
78 | pub(crate) fn collect_garbage(&mut self) { | 78 | pub(crate) fn collect_garbage(&mut self) { |
79 | self.query(ra_db::SourceFileQuery) | 79 | self.query(ra_db::ParseQuery) |
80 | .sweep(SweepStrategy::default().discard_values()); | 80 | .sweep(SweepStrategy::default().discard_values()); |
81 | self.query(hir::db::HirSourceFileQuery) | 81 | self.query(hir::db::HirParseQuery) |
82 | .sweep(SweepStrategy::default().discard_values()); | 82 | .sweep(SweepStrategy::default().discard_values()); |
83 | self.query(hir::db::FileItemsQuery) | 83 | self.query(hir::db::FileItemsQuery) |
84 | .sweep(SweepStrategy::default().discard_values()); | 84 | .sweep(SweepStrategy::default().discard_values()); |
@@ -102,7 +102,7 @@ impl db::RootDatabase { | |||
102 | } | 102 | } |
103 | 103 | ||
104 | pub(crate) fn find_all_refs(&self, position: FilePosition) -> Vec<(FileId, TextRange)> { | 104 | pub(crate) fn find_all_refs(&self, position: FilePosition) -> Vec<(FileId, TextRange)> { |
105 | let file = self.source_file(position.file_id); | 105 | let file = self.parse(position.file_id); |
106 | // Find the binding associated with the offset | 106 | // Find the binding associated with the offset |
107 | let (binding, descr) = match find_binding(self, &file, position) { | 107 | let (binding, descr) = match find_binding(self, &file, position) { |
108 | None => return Vec::new(), | 108 | None => return Vec::new(), |
@@ -150,7 +150,7 @@ impl db::RootDatabase { | |||
150 | } | 150 | } |
151 | 151 | ||
152 | pub(crate) fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { | 152 | pub(crate) fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { |
153 | let syntax = self.source_file(file_id); | 153 | let syntax = self.parse(file_id); |
154 | 154 | ||
155 | let mut res = ra_ide_api_light::diagnostics(&syntax) | 155 | let mut res = ra_ide_api_light::diagnostics(&syntax) |
156 | .into_iter() | 156 | .into_iter() |
@@ -214,7 +214,7 @@ impl db::RootDatabase { | |||
214 | } | 214 | } |
215 | 215 | ||
216 | pub(crate) fn assists(&self, frange: FileRange) -> Vec<SourceChange> { | 216 | pub(crate) fn assists(&self, frange: FileRange) -> Vec<SourceChange> { |
217 | let file = self.source_file(frange.file_id); | 217 | let file = self.parse(frange.file_id); |
218 | assists::assists(&file, frange.range) | 218 | assists::assists(&file, frange.range) |
219 | .into_iter() | 219 | .into_iter() |
220 | .map(|local_edit| SourceChange::from_local_edit(frange.file_id, local_edit)) | 220 | .map(|local_edit| SourceChange::from_local_edit(frange.file_id, local_edit)) |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index ffd026b04..43c8bea71 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -34,7 +34,7 @@ use std::{fmt, sync::Arc}; | |||
34 | use ra_syntax::{SourceFile, TreeArc, TextRange, TextUnit}; | 34 | use ra_syntax::{SourceFile, TreeArc, TextRange, TextUnit}; |
35 | use ra_text_edit::TextEdit; | 35 | use ra_text_edit::TextEdit; |
36 | use ra_db::{ | 36 | use ra_db::{ |
37 | SyntaxDatabase, FilesDatabase, BaseDatabase, | 37 | SourceDatabase, CheckCanceled, |
38 | salsa::{self, ParallelDatabase}, | 38 | salsa::{self, ParallelDatabase}, |
39 | }; | 39 | }; |
40 | use rayon::prelude::*; | 40 | use rayon::prelude::*; |
@@ -313,7 +313,7 @@ impl Analysis { | |||
313 | 313 | ||
314 | /// Gets the syntax tree of the file. | 314 | /// Gets the syntax tree of the file. |
315 | pub fn parse(&self, file_id: FileId) -> TreeArc<SourceFile> { | 315 | pub fn parse(&self, file_id: FileId) -> TreeArc<SourceFile> { |
316 | self.db.source_file(file_id).clone() | 316 | self.db.parse(file_id).clone() |
317 | } | 317 | } |
318 | 318 | ||
319 | /// Gets the file's `LineIndex`: data structure to convert between absolute | 319 | /// Gets the file's `LineIndex`: data structure to convert between absolute |
@@ -330,21 +330,21 @@ impl Analysis { | |||
330 | /// Returns position of the mathcing brace (all types of braces are | 330 | /// Returns position of the mathcing brace (all types of braces are |
331 | /// supported). | 331 | /// supported). |
332 | pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { | 332 | pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { |
333 | let file = self.db.source_file(position.file_id); | 333 | let file = self.db.parse(position.file_id); |
334 | ra_ide_api_light::matching_brace(&file, position.offset) | 334 | ra_ide_api_light::matching_brace(&file, position.offset) |
335 | } | 335 | } |
336 | 336 | ||
337 | /// Returns a syntax tree represented as `String`, for debug purposes. | 337 | /// Returns a syntax tree represented as `String`, for debug purposes. |
338 | // FIXME: use a better name here. | 338 | // FIXME: use a better name here. |
339 | pub fn syntax_tree(&self, file_id: FileId) -> String { | 339 | pub fn syntax_tree(&self, file_id: FileId) -> String { |
340 | let file = self.db.source_file(file_id); | 340 | let file = self.db.parse(file_id); |
341 | ra_ide_api_light::syntax_tree(&file) | 341 | ra_ide_api_light::syntax_tree(&file) |
342 | } | 342 | } |
343 | 343 | ||
344 | /// Returns an edit to remove all newlines in the range, cleaning up minor | 344 | /// Returns an edit to remove all newlines in the range, cleaning up minor |
345 | /// stuff like trailing commas. | 345 | /// stuff like trailing commas. |
346 | pub fn join_lines(&self, frange: FileRange) -> SourceChange { | 346 | pub fn join_lines(&self, frange: FileRange) -> SourceChange { |
347 | let file = self.db.source_file(frange.file_id); | 347 | let file = self.db.parse(frange.file_id); |
348 | SourceChange::from_local_edit( | 348 | SourceChange::from_local_edit( |
349 | frange.file_id, | 349 | frange.file_id, |
350 | ra_ide_api_light::join_lines(&file, frange.range), | 350 | ra_ide_api_light::join_lines(&file, frange.range), |
@@ -354,7 +354,7 @@ impl Analysis { | |||
354 | /// Returns an edit which should be applied when opening a new line, fixing | 354 | /// Returns an edit which should be applied when opening a new line, fixing |
355 | /// up minor stuff like continuing the comment. | 355 | /// up minor stuff like continuing the comment. |
356 | pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { | 356 | pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { |
357 | let file = self.db.source_file(position.file_id); | 357 | let file = self.db.parse(position.file_id); |
358 | let edit = ra_ide_api_light::on_enter(&file, position.offset)?; | 358 | let edit = ra_ide_api_light::on_enter(&file, position.offset)?; |
359 | Some(SourceChange::from_local_edit(position.file_id, edit)) | 359 | Some(SourceChange::from_local_edit(position.file_id, edit)) |
360 | } | 360 | } |
@@ -363,14 +363,14 @@ impl Analysis { | |||
363 | /// this works when adding `let =`. | 363 | /// this works when adding `let =`. |
364 | // FIXME: use a snippet completion instead of this hack here. | 364 | // FIXME: use a snippet completion instead of this hack here. |
365 | pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { | 365 | pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { |
366 | let file = self.db.source_file(position.file_id); | 366 | let file = self.db.parse(position.file_id); |
367 | let edit = ra_ide_api_light::on_eq_typed(&file, position.offset)?; | 367 | let edit = ra_ide_api_light::on_eq_typed(&file, position.offset)?; |
368 | Some(SourceChange::from_local_edit(position.file_id, edit)) | 368 | Some(SourceChange::from_local_edit(position.file_id, edit)) |
369 | } | 369 | } |
370 | 370 | ||
371 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. | 371 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. |
372 | pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> { | 372 | pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> { |
373 | let file = self.db.source_file(position.file_id); | 373 | let file = self.db.parse(position.file_id); |
374 | let edit = ra_ide_api_light::on_dot_typed(&file, position.offset)?; | 374 | let edit = ra_ide_api_light::on_dot_typed(&file, position.offset)?; |
375 | Some(SourceChange::from_local_edit(position.file_id, edit)) | 375 | Some(SourceChange::from_local_edit(position.file_id, edit)) |
376 | } | 376 | } |
@@ -378,13 +378,13 @@ impl Analysis { | |||
378 | /// Returns a tree representation of symbols in the file. Useful to draw a | 378 | /// Returns a tree representation of symbols in the file. Useful to draw a |
379 | /// file outline. | 379 | /// file outline. |
380 | pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { | 380 | pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { |
381 | let file = self.db.source_file(file_id); | 381 | let file = self.db.parse(file_id); |
382 | ra_ide_api_light::file_structure(&file) | 382 | ra_ide_api_light::file_structure(&file) |
383 | } | 383 | } |
384 | 384 | ||
385 | /// Returns the set of folding ranges. | 385 | /// Returns the set of folding ranges. |
386 | pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { | 386 | pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { |
387 | let file = self.db.source_file(file_id); | 387 | let file = self.db.parse(file_id); |
388 | ra_ide_api_light::folding_ranges(&file) | 388 | ra_ide_api_light::folding_ranges(&file) |
389 | } | 389 | } |
390 | 390 | ||
diff --git a/crates/ra_ide_api/src/rename.rs b/crates/ra_ide_api/src/rename.rs index 5b767addd..db5ccf969 100644 --- a/crates/ra_ide_api/src/rename.rs +++ b/crates/ra_ide_api/src/rename.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | SourceChange, | 17 | SourceChange, |
18 | SourceFileEdit, | 18 | SourceFileEdit, |
19 | }; | 19 | }; |
20 | use ra_db::{FilesDatabase, SyntaxDatabase}; | 20 | use ra_db::SourceDatabase; |
21 | use relative_path::RelativePath; | 21 | use relative_path::RelativePath; |
22 | 22 | ||
23 | pub(crate) fn rename( | 23 | pub(crate) fn rename( |
@@ -25,7 +25,7 @@ pub(crate) fn rename( | |||
25 | position: FilePosition, | 25 | position: FilePosition, |
26 | new_name: &str, | 26 | new_name: &str, |
27 | ) -> Option<SourceChange> { | 27 | ) -> Option<SourceChange> { |
28 | let source_file = db.source_file(position.file_id); | 28 | let source_file = db.parse(position.file_id); |
29 | let syntax = source_file.syntax(); | 29 | let syntax = source_file.syntax(); |
30 | 30 | ||
31 | if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) { | 31 | if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) { |
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs index 0f9f8deb3..dc8c40ea6 100644 --- a/crates/ra_ide_api/src/runnables.rs +++ b/crates/ra_ide_api/src/runnables.rs | |||
@@ -3,7 +3,7 @@ use ra_syntax::{ | |||
3 | TextRange, SyntaxNode, | 3 | TextRange, SyntaxNode, |
4 | ast::{self, AstNode, NameOwner, ModuleItemOwner}, | 4 | ast::{self, AstNode, NameOwner, ModuleItemOwner}, |
5 | }; | 5 | }; |
6 | use ra_db::SyntaxDatabase; | 6 | use ra_db::SourceDatabase; |
7 | 7 | ||
8 | use crate::{db::RootDatabase, FileId}; | 8 | use crate::{db::RootDatabase, FileId}; |
9 | 9 | ||
@@ -22,7 +22,7 @@ pub enum RunnableKind { | |||
22 | } | 22 | } |
23 | 23 | ||
24 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 24 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
25 | let source_file = db.source_file(file_id); | 25 | let source_file = db.parse(file_id); |
26 | source_file | 26 | source_file |
27 | .syntax() | 27 | .syntax() |
28 | .descendants() | 28 | .descendants() |
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs index 59159df98..e11eed223 100644 --- a/crates/ra_ide_api/src/status.rs +++ b/crates/ra_ide_api/src/status.rs | |||
@@ -6,7 +6,7 @@ use std::{ | |||
6 | 6 | ||
7 | use ra_syntax::{AstNode, TreeArc, SourceFile}; | 7 | use ra_syntax::{AstNode, TreeArc, SourceFile}; |
8 | use ra_db::{ | 8 | use ra_db::{ |
9 | SourceFileQuery, FileTextQuery, SourceRootId, | 9 | ParseQuery, FileTextQuery, SourceRootId, |
10 | salsa::{Database, debug::{DebugQueryTable, TableEntry}}, | 10 | salsa::{Database, debug::{DebugQueryTable, TableEntry}}, |
11 | }; | 11 | }; |
12 | 12 | ||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | 17 | ||
18 | pub(crate) fn status(db: &RootDatabase) -> String { | 18 | pub(crate) fn status(db: &RootDatabase) -> String { |
19 | let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); | 19 | let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); |
20 | let syntax_tree_stats = db.query(SourceFileQuery).entries::<SyntaxTreeStats>(); | 20 | let syntax_tree_stats = db.query(ParseQuery).entries::<SyntaxTreeStats>(); |
21 | let symbols_stats = db | 21 | let symbols_stats = db |
22 | .query(LibrarySymbolsQuery) | 22 | .query(LibrarySymbolsQuery) |
23 | .entries::<LibrarySymbolsStats>(); | 23 | .entries::<LibrarySymbolsStats>(); |
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index e073a349e..72c93f530 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -34,7 +34,7 @@ use ra_syntax::{ | |||
34 | ast::{self, NameOwner}, | 34 | ast::{self, NameOwner}, |
35 | }; | 35 | }; |
36 | use ra_db::{ | 36 | use ra_db::{ |
37 | SourceRootId, FilesDatabase, | 37 | SourceRootId, SourceDatabase, |
38 | salsa::{self, ParallelDatabase}, | 38 | salsa::{self, ParallelDatabase}, |
39 | }; | 39 | }; |
40 | use rayon::prelude::*; | 40 | use rayon::prelude::*; |
@@ -49,11 +49,19 @@ pub(crate) trait SymbolsDatabase: hir::db::HirDatabase { | |||
49 | fn file_symbols(&self, file_id: FileId) -> Arc<SymbolIndex>; | 49 | fn file_symbols(&self, file_id: FileId) -> Arc<SymbolIndex>; |
50 | #[salsa::input] | 50 | #[salsa::input] |
51 | fn library_symbols(&self, id: SourceRootId) -> Arc<SymbolIndex>; | 51 | fn library_symbols(&self, id: SourceRootId) -> Arc<SymbolIndex>; |
52 | /// The set of "local" (that is, from the current workspace) roots. | ||
53 | /// Files in local roots are assumed to change frequently. | ||
54 | #[salsa::input] | ||
55 | fn local_roots(&self) -> Arc<Vec<SourceRootId>>; | ||
56 | /// The set of roots for crates.io libraries. | ||
57 | /// Files in libraries are assumed to never change. | ||
58 | #[salsa::input] | ||
59 | fn library_roots(&self) -> Arc<Vec<SourceRootId>>; | ||
52 | } | 60 | } |
53 | 61 | ||
54 | fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> { | 62 | fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> { |
55 | db.check_canceled(); | 63 | db.check_canceled(); |
56 | let source_file = db.source_file(file_id); | 64 | let source_file = db.parse(file_id); |
57 | let mut symbols = source_file | 65 | let mut symbols = source_file |
58 | .syntax() | 66 | .syntax() |
59 | .descendants() | 67 | .descendants() |
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index a4d3ad005..26bde495b 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use ra_syntax::{ast, AstNode,}; | 1 | use ra_syntax::{ast, AstNode,}; |
2 | use ra_db::SyntaxDatabase; | 2 | use ra_db::SourceDatabase; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | FileId, HighlightedRange, | 5 | FileId, HighlightedRange, |
@@ -7,7 +7,7 @@ use crate::{ | |||
7 | }; | 7 | }; |
8 | 8 | ||
9 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { | 9 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { |
10 | let source_file = db.source_file(file_id); | 10 | let source_file = db.parse(file_id); |
11 | let mut res = ra_ide_api_light::highlight(source_file.syntax()); | 11 | let mut res = ra_ide_api_light::highlight(source_file.syntax()); |
12 | for macro_call in source_file | 12 | for macro_call in source_file |
13 | .syntax() | 13 | .syntax() |
diff --git a/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap b/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap index b96398950..270f75a56 100644 --- a/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap +++ b/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap | |||
@@ -1,8 +1,8 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-24T18:04:00.090162+00:00" | 2 | created: "2019-01-26T07:11:02.463391362+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: structure | 4 | expression: structure |
5 | source: "crates\\ra_ide_api_light\\src\\structure.rs" | 5 | source: crates/ra_ide_api_light/src/structure.rs |
6 | --- | 6 | --- |
7 | [ | 7 | [ |
8 | StructureNode { | 8 | StructureNode { |
@@ -78,6 +78,26 @@ source: "crates\\ra_ide_api_light\\src\\structure.rs" | |||
78 | detail: None | 78 | detail: None |
79 | }, | 79 | }, |
80 | StructureNode { | 80 | StructureNode { |
81 | parent: Some( | ||
82 | 6 | ||
83 | ), | ||
84 | label: "X", | ||
85 | navigation_range: [169; 170), | ||
86 | node_range: [169; 170), | ||
87 | kind: ENUM_VARIANT, | ||
88 | detail: None | ||
89 | }, | ||
90 | StructureNode { | ||
91 | parent: Some( | ||
92 | 6 | ||
93 | ), | ||
94 | label: "Y", | ||
95 | navigation_range: [172; 173), | ||
96 | node_range: [172; 178), | ||
97 | kind: ENUM_VARIANT, | ||
98 | detail: None | ||
99 | }, | ||
100 | StructureNode { | ||
81 | parent: None, | 101 | parent: None, |
82 | label: "T", | 102 | label: "T", |
83 | navigation_range: [186; 187), | 103 | navigation_range: [186; 187), |
diff --git a/crates/ra_ide_api_light/src/structure.rs b/crates/ra_ide_api_light/src/structure.rs index e3713c217..4e080ed03 100644 --- a/crates/ra_ide_api_light/src/structure.rs +++ b/crates/ra_ide_api_light/src/structure.rs | |||
@@ -103,6 +103,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
103 | .visit(decl::<ast::StructDef>) | 103 | .visit(decl::<ast::StructDef>) |
104 | .visit(|nfd: &ast::NamedFieldDef| decl_with_type_ref(nfd, nfd.type_ref())) | 104 | .visit(|nfd: &ast::NamedFieldDef| decl_with_type_ref(nfd, nfd.type_ref())) |
105 | .visit(decl::<ast::EnumDef>) | 105 | .visit(decl::<ast::EnumDef>) |
106 | .visit(decl::<ast::EnumVariant>) | ||
106 | .visit(decl::<ast::TraitDef>) | 107 | .visit(decl::<ast::TraitDef>) |
107 | .visit(decl::<ast::Module>) | 108 | .visit(decl::<ast::Module>) |
108 | .visit(|td: &ast::TypeDef| decl_with_type_ref(td, td.type_ref())) | 109 | .visit(|td: &ast::TypeDef| decl_with_type_ref(td, td.type_ref())) |
diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs index 21d89d83b..adc189a29 100644 --- a/crates/ra_syntax/src/grammar/types.rs +++ b/crates/ra_syntax/src/grammar/types.rs | |||
@@ -29,7 +29,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { | |||
29 | DYN_KW => dyn_trait_type(p), | 29 | DYN_KW => dyn_trait_type(p), |
30 | // Some path types are not allowed to have bounds (no plus) | 30 | // Some path types are not allowed to have bounds (no plus) |
31 | L_ANGLE => path_type_(p, allow_bounds), | 31 | L_ANGLE => path_type_(p, allow_bounds), |
32 | _ if paths::is_path_start(p) => path_type_(p, allow_bounds), | 32 | _ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds), |
33 | _ => { | 33 | _ => { |
34 | p.err_recover("expected type", TYPE_RECOVERY_SET); | 34 | p.err_recover("expected type", TYPE_RECOVERY_SET); |
35 | } | 35 | } |
@@ -243,6 +243,28 @@ pub(super) fn path_type(p: &mut Parser) { | |||
243 | path_type_(p, true) | 243 | path_type_(p, true) |
244 | } | 244 | } |
245 | 245 | ||
246 | // test macro_call_type | ||
247 | // type A = foo!(); | ||
248 | // type B = crate::foo!(); | ||
249 | fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { | ||
250 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); | ||
251 | let m = p.start(); | ||
252 | paths::type_path(p); | ||
253 | |||
254 | let kind = if p.at(EXCL) { | ||
255 | items::macro_call_after_excl(p); | ||
256 | MACRO_CALL | ||
257 | } else { | ||
258 | PATH_TYPE | ||
259 | }; | ||
260 | |||
261 | if allow_bounds && p.eat(PLUS) { | ||
262 | type_params::bounds_without_colon(p); | ||
263 | } | ||
264 | |||
265 | m.complete(p, kind); | ||
266 | } | ||
267 | |||
246 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { | 268 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { |
247 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); | 269 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); |
248 | let m = p.start(); | 270 | let m = p.start(); |
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.rs new file mode 100644 index 000000000..edb470c89 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | type A = foo!(); | ||
2 | type B = crate::foo!(); | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.txt new file mode 100644 index 000000000..b2d95451c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | SOURCE_FILE@[0; 41) | ||
2 | TYPE_DEF@[0; 16) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | MACRO_CALL@[9; 15) | ||
11 | PATH@[9; 12) | ||
12 | PATH_SEGMENT@[9; 12) | ||
13 | NAME_REF@[9; 12) | ||
14 | IDENT@[9; 12) "foo" | ||
15 | EXCL@[12; 13) | ||
16 | TOKEN_TREE@[13; 15) | ||
17 | L_PAREN@[13; 14) | ||
18 | R_PAREN@[14; 15) | ||
19 | SEMI@[15; 16) | ||
20 | WHITESPACE@[16; 17) | ||
21 | TYPE_DEF@[17; 40) | ||
22 | TYPE_KW@[17; 21) | ||
23 | WHITESPACE@[21; 22) | ||
24 | NAME@[22; 23) | ||
25 | IDENT@[22; 23) "B" | ||
26 | WHITESPACE@[23; 24) | ||
27 | EQ@[24; 25) | ||
28 | WHITESPACE@[25; 26) | ||
29 | MACRO_CALL@[26; 39) | ||
30 | PATH@[26; 36) | ||
31 | PATH@[26; 31) | ||
32 | PATH_SEGMENT@[26; 31) | ||
33 | CRATE_KW@[26; 31) | ||
34 | COLONCOLON@[31; 33) | ||
35 | PATH_SEGMENT@[33; 36) | ||
36 | NAME_REF@[33; 36) | ||
37 | IDENT@[33; 36) "foo" | ||
38 | EXCL@[36; 37) | ||
39 | TOKEN_TREE@[37; 39) | ||
40 | L_PAREN@[37; 38) | ||
41 | R_PAREN@[38; 39) | ||
42 | SEMI@[39; 40) | ||
43 | WHITESPACE@[40; 41) | ||
diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml index e637063c9..383381d2a 100644 --- a/crates/ra_vfs/Cargo.toml +++ b/crates/ra_vfs/Cargo.toml | |||
@@ -10,9 +10,13 @@ relative-path = "0.4.0" | |||
10 | rustc-hash = "1.0" | 10 | rustc-hash = "1.0" |
11 | crossbeam-channel = "0.3.5" | 11 | crossbeam-channel = "0.3.5" |
12 | log = "0.4.6" | 12 | log = "0.4.6" |
13 | notify = "4.0.7" | ||
14 | drop_bomb = "0.1.0" | ||
15 | parking_lot = "0.7.0" | ||
13 | 16 | ||
14 | thread_worker = { path = "../thread_worker" } | 17 | thread_worker = { path = "../thread_worker" } |
15 | ra_arena = { path = "../ra_arena" } | 18 | ra_arena = { path = "../ra_arena" } |
16 | 19 | ||
17 | [dev-dependencies] | 20 | [dev-dependencies] |
18 | tempfile = "3" | 21 | tempfile = "3" |
22 | flexi_logger = "0.10.0" | ||
diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index 80328ad18..7ca1e9835 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs | |||
@@ -1,55 +1,109 @@ | |||
1 | use std::{ | 1 | use std::{fs, sync::Arc, thread}; |
2 | fmt, | ||
3 | fs, | ||
4 | path::{Path, PathBuf}, | ||
5 | }; | ||
6 | 2 | ||
7 | use walkdir::{DirEntry, WalkDir}; | 3 | use crossbeam_channel::{Receiver, Sender}; |
8 | use thread_worker::{WorkerHandle}; | ||
9 | use relative_path::RelativePathBuf; | 4 | use relative_path::RelativePathBuf; |
5 | use thread_worker::WorkerHandle; | ||
6 | use walkdir::WalkDir; | ||
10 | 7 | ||
11 | use crate::{VfsRoot, has_rs_extension}; | 8 | mod watcher; |
9 | use watcher::Watcher; | ||
12 | 10 | ||
13 | pub(crate) struct Task { | 11 | use crate::{RootFilter, Roots, VfsRoot}; |
14 | pub(crate) root: VfsRoot, | 12 | |
15 | pub(crate) path: PathBuf, | 13 | pub(crate) enum Task { |
16 | pub(crate) filter: Box<Fn(&DirEntry) -> bool + Send>, | 14 | AddRoot { |
15 | root: VfsRoot, | ||
16 | filter: Arc<RootFilter>, | ||
17 | }, | ||
17 | } | 18 | } |
18 | 19 | ||
19 | pub struct TaskResult { | 20 | #[derive(Debug)] |
20 | pub(crate) root: VfsRoot, | 21 | pub enum TaskResult { |
21 | pub(crate) files: Vec<(RelativePathBuf, String)>, | 22 | BulkLoadRoot { |
23 | root: VfsRoot, | ||
24 | files: Vec<(RelativePathBuf, String)>, | ||
25 | }, | ||
26 | AddSingleFile { | ||
27 | root: VfsRoot, | ||
28 | path: RelativePathBuf, | ||
29 | text: String, | ||
30 | }, | ||
31 | ChangeSingleFile { | ||
32 | root: VfsRoot, | ||
33 | path: RelativePathBuf, | ||
34 | text: String, | ||
35 | }, | ||
36 | RemoveSingleFile { | ||
37 | root: VfsRoot, | ||
38 | path: RelativePathBuf, | ||
39 | }, | ||
22 | } | 40 | } |
23 | 41 | ||
24 | impl fmt::Debug for TaskResult { | 42 | pub(crate) struct Worker { |
25 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 43 | worker: thread_worker::Worker<Task, TaskResult>, |
26 | f.write_str("TaskResult { ... }") | 44 | worker_handle: WorkerHandle, |
27 | } | ||
28 | } | 45 | } |
29 | 46 | ||
30 | pub(crate) type Worker = thread_worker::Worker<Task, TaskResult>; | 47 | impl Worker { |
48 | pub(crate) fn start(roots: Arc<Roots>) -> Worker { | ||
49 | let (worker, worker_handle) = | ||
50 | thread_worker::spawn("vfs", 128, move |input_receiver, output_sender| { | ||
51 | let mut watcher = match Watcher::start(roots, output_sender.clone()) { | ||
52 | Ok(w) => Some(w), | ||
53 | Err(e) => { | ||
54 | log::error!("could not start watcher: {}", e); | ||
55 | None | ||
56 | } | ||
57 | }; | ||
58 | let res = input_receiver | ||
59 | .into_iter() | ||
60 | .filter_map(|t| handle_task(t, &mut watcher)) | ||
61 | .try_for_each(|it| output_sender.send(it)); | ||
62 | if let Some(watcher) = watcher { | ||
63 | let _ = watcher.shutdown(); | ||
64 | } | ||
65 | res.unwrap() | ||
66 | }); | ||
67 | Worker { | ||
68 | worker, | ||
69 | worker_handle, | ||
70 | } | ||
71 | } | ||
72 | |||
73 | pub(crate) fn sender(&self) -> &Sender<Task> { | ||
74 | &self.worker.inp | ||
75 | } | ||
76 | |||
77 | pub(crate) fn receiver(&self) -> &Receiver<TaskResult> { | ||
78 | &self.worker.out | ||
79 | } | ||
31 | 80 | ||
32 | pub(crate) fn start() -> (Worker, WorkerHandle) { | 81 | pub(crate) fn shutdown(self) -> thread::Result<()> { |
33 | thread_worker::spawn("vfs", 128, |input_receiver, output_sender| { | 82 | let _ = self.worker.shutdown(); |
34 | input_receiver | 83 | self.worker_handle.shutdown() |
35 | .into_iter() | 84 | } |
36 | .map(handle_task) | ||
37 | .try_for_each(|it| output_sender.send(it)) | ||
38 | .unwrap() | ||
39 | }) | ||
40 | } | 85 | } |
41 | 86 | ||
42 | fn handle_task(task: Task) -> TaskResult { | 87 | fn handle_task(task: Task, watcher: &mut Option<Watcher>) -> Option<TaskResult> { |
43 | let Task { root, path, filter } = task; | 88 | match task { |
44 | log::debug!("loading {} ...", path.as_path().display()); | 89 | Task::AddRoot { root, filter } => { |
45 | let files = load_root(path.as_path(), &*filter); | 90 | if let Some(watcher) = watcher { |
46 | log::debug!("... loaded {}", path.as_path().display()); | 91 | watcher.watch_root(&filter) |
47 | TaskResult { root, files } | 92 | } |
93 | log::debug!("loading {} ...", filter.root.as_path().display()); | ||
94 | let files = load_root(filter.as_ref()); | ||
95 | log::debug!("... loaded {}", filter.root.as_path().display()); | ||
96 | Some(TaskResult::BulkLoadRoot { root, files }) | ||
97 | } | ||
98 | } | ||
48 | } | 99 | } |
49 | 100 | ||
50 | fn load_root(root: &Path, filter: &dyn Fn(&DirEntry) -> bool) -> Vec<(RelativePathBuf, String)> { | 101 | fn load_root(filter: &RootFilter) -> Vec<(RelativePathBuf, String)> { |
51 | let mut res = Vec::new(); | 102 | let mut res = Vec::new(); |
52 | for entry in WalkDir::new(root).into_iter().filter_entry(filter) { | 103 | for entry in WalkDir::new(&filter.root) |
104 | .into_iter() | ||
105 | .filter_entry(filter.entry_filter()) | ||
106 | { | ||
53 | let entry = match entry { | 107 | let entry = match entry { |
54 | Ok(entry) => entry, | 108 | Ok(entry) => entry, |
55 | Err(e) => { | 109 | Err(e) => { |
@@ -61,9 +115,6 @@ fn load_root(root: &Path, filter: &dyn Fn(&DirEntry) -> bool) -> Vec<(RelativePa | |||
61 | continue; | 115 | continue; |
62 | } | 116 | } |
63 | let path = entry.path(); | 117 | let path = entry.path(); |
64 | if !has_rs_extension(path) { | ||
65 | continue; | ||
66 | } | ||
67 | let text = match fs::read_to_string(path) { | 118 | let text = match fs::read_to_string(path) { |
68 | Ok(text) => text, | 119 | Ok(text) => text, |
69 | Err(e) => { | 120 | Err(e) => { |
@@ -71,7 +122,7 @@ fn load_root(root: &Path, filter: &dyn Fn(&DirEntry) -> bool) -> Vec<(RelativePa | |||
71 | continue; | 122 | continue; |
72 | } | 123 | } |
73 | }; | 124 | }; |
74 | let path = RelativePathBuf::from_path(path.strip_prefix(root).unwrap()).unwrap(); | 125 | let path = RelativePathBuf::from_path(path.strip_prefix(&filter.root).unwrap()).unwrap(); |
75 | res.push((path.to_owned(), text)) | 126 | res.push((path.to_owned(), text)) |
76 | } | 127 | } |
77 | res | 128 | res |
diff --git a/crates/ra_vfs/src/io/watcher.rs b/crates/ra_vfs/src/io/watcher.rs new file mode 100644 index 000000000..ff6775f59 --- /dev/null +++ b/crates/ra_vfs/src/io/watcher.rs | |||
@@ -0,0 +1,200 @@ | |||
1 | use crate::{io, RootFilter, Roots, VfsRoot}; | ||
2 | use crossbeam_channel::Sender; | ||
3 | use drop_bomb::DropBomb; | ||
4 | use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher}; | ||
5 | use parking_lot::Mutex; | ||
6 | use std::{ | ||
7 | fs, | ||
8 | path::{Path, PathBuf}, | ||
9 | sync::{mpsc, Arc}, | ||
10 | thread, | ||
11 | time::Duration, | ||
12 | }; | ||
13 | use walkdir::WalkDir; | ||
14 | |||
15 | #[derive(Debug)] | ||
16 | enum ChangeKind { | ||
17 | Create, | ||
18 | Write, | ||
19 | Remove, | ||
20 | } | ||
21 | |||
22 | const WATCHER_DELAY: Duration = Duration::from_millis(250); | ||
23 | |||
24 | pub(crate) struct Watcher { | ||
25 | thread: thread::JoinHandle<()>, | ||
26 | bomb: DropBomb, | ||
27 | watcher: Arc<Mutex<Option<RecommendedWatcher>>>, | ||
28 | } | ||
29 | |||
30 | impl Watcher { | ||
31 | pub(crate) fn start( | ||
32 | roots: Arc<Roots>, | ||
33 | output_sender: Sender<io::TaskResult>, | ||
34 | ) -> Result<Watcher, Box<std::error::Error>> { | ||
35 | let (input_sender, input_receiver) = mpsc::channel(); | ||
36 | let watcher = Arc::new(Mutex::new(Some(notify::watcher( | ||
37 | input_sender, | ||
38 | WATCHER_DELAY, | ||
39 | )?))); | ||
40 | let sender = output_sender.clone(); | ||
41 | let watcher_clone = watcher.clone(); | ||
42 | let thread = thread::spawn(move || { | ||
43 | let worker = WatcherWorker { | ||
44 | roots, | ||
45 | watcher: watcher_clone, | ||
46 | sender, | ||
47 | }; | ||
48 | input_receiver | ||
49 | .into_iter() | ||
50 | // forward relevant events only | ||
51 | .try_for_each(|change| worker.handle_debounced_event(change)) | ||
52 | .unwrap() | ||
53 | }); | ||
54 | Ok(Watcher { | ||
55 | thread, | ||
56 | watcher, | ||
57 | bomb: DropBomb::new(format!("Watcher was not shutdown")), | ||
58 | }) | ||
59 | } | ||
60 | |||
61 | pub fn watch_root(&mut self, filter: &RootFilter) { | ||
62 | for res in WalkDir::new(&filter.root) | ||
63 | .into_iter() | ||
64 | .filter_entry(filter.entry_filter()) | ||
65 | { | ||
66 | match res { | ||
67 | Ok(entry) => { | ||
68 | if entry.file_type().is_dir() { | ||
69 | watch_one(self.watcher.as_ref(), entry.path()); | ||
70 | } | ||
71 | } | ||
72 | Err(e) => log::warn!("watcher error: {}", e), | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | |||
77 | pub fn shutdown(mut self) -> thread::Result<()> { | ||
78 | self.bomb.defuse(); | ||
79 | drop(self.watcher.lock().take()); | ||
80 | let res = self.thread.join(); | ||
81 | match &res { | ||
82 | Ok(()) => log::info!("... Watcher terminated with ok"), | ||
83 | Err(_) => log::error!("... Watcher terminated with err"), | ||
84 | } | ||
85 | res | ||
86 | } | ||
87 | } | ||
88 | |||
89 | struct WatcherWorker { | ||
90 | watcher: Arc<Mutex<Option<RecommendedWatcher>>>, | ||
91 | roots: Arc<Roots>, | ||
92 | sender: Sender<io::TaskResult>, | ||
93 | } | ||
94 | |||
95 | impl WatcherWorker { | ||
96 | fn handle_debounced_event(&self, ev: DebouncedEvent) -> Result<(), Box<std::error::Error>> { | ||
97 | match ev { | ||
98 | DebouncedEvent::NoticeWrite(_) | ||
99 | | DebouncedEvent::NoticeRemove(_) | ||
100 | | DebouncedEvent::Chmod(_) => { | ||
101 | // ignore | ||
102 | } | ||
103 | DebouncedEvent::Rescan => { | ||
104 | // TODO rescan all roots | ||
105 | } | ||
106 | DebouncedEvent::Create(path) => { | ||
107 | self.handle_change(path, ChangeKind::Create); | ||
108 | } | ||
109 | DebouncedEvent::Write(path) => { | ||
110 | self.handle_change(path, ChangeKind::Write); | ||
111 | } | ||
112 | DebouncedEvent::Remove(path) => { | ||
113 | self.handle_change(path, ChangeKind::Remove); | ||
114 | } | ||
115 | DebouncedEvent::Rename(src, dst) => { | ||
116 | self.handle_change(src, ChangeKind::Remove); | ||
117 | self.handle_change(dst, ChangeKind::Create); | ||
118 | } | ||
119 | DebouncedEvent::Error(err, path) => { | ||
120 | // TODO should we reload the file contents? | ||
121 | log::warn!("watcher error \"{}\", {:?}", err, path); | ||
122 | } | ||
123 | } | ||
124 | Ok(()) | ||
125 | } | ||
126 | |||
127 | fn handle_change(&self, path: PathBuf, kind: ChangeKind) { | ||
128 | if let Err(e) = self.try_handle_change(path, kind) { | ||
129 | log::warn!("watcher error: {}", e) | ||
130 | } | ||
131 | } | ||
132 | |||
133 | fn try_handle_change( | ||
134 | &self, | ||
135 | path: PathBuf, | ||
136 | kind: ChangeKind, | ||
137 | ) -> Result<(), Box<std::error::Error>> { | ||
138 | let (root, rel_path) = match self.roots.find(&path) { | ||
139 | Some(x) => x, | ||
140 | None => return Ok(()), | ||
141 | }; | ||
142 | match kind { | ||
143 | ChangeKind::Create => { | ||
144 | if path.is_dir() { | ||
145 | self.watch_recursive(&path, root); | ||
146 | } else { | ||
147 | let text = fs::read_to_string(&path)?; | ||
148 | self.sender.send(io::TaskResult::AddSingleFile { | ||
149 | root, | ||
150 | path: rel_path, | ||
151 | text, | ||
152 | })? | ||
153 | } | ||
154 | } | ||
155 | ChangeKind::Write => { | ||
156 | let text = fs::read_to_string(&path)?; | ||
157 | self.sender.send(io::TaskResult::ChangeSingleFile { | ||
158 | root, | ||
159 | path: rel_path, | ||
160 | text, | ||
161 | })? | ||
162 | } | ||
163 | ChangeKind::Remove => self.sender.send(io::TaskResult::RemoveSingleFile { | ||
164 | root, | ||
165 | path: rel_path, | ||
166 | })?, | ||
167 | } | ||
168 | Ok(()) | ||
169 | } | ||
170 | |||
171 | fn watch_recursive(&self, dir: &Path, root: VfsRoot) { | ||
172 | let filter = &self.roots[root]; | ||
173 | for res in WalkDir::new(dir) | ||
174 | .into_iter() | ||
175 | .filter_entry(filter.entry_filter()) | ||
176 | { | ||
177 | match res { | ||
178 | Ok(entry) => { | ||
179 | if entry.file_type().is_dir() { | ||
180 | watch_one(self.watcher.as_ref(), entry.path()); | ||
181 | } else { | ||
182 | // emit only for files otherwise we will cause watch_recursive to be called again with a dir that we are already watching | ||
183 | // emit as create because we haven't seen it yet | ||
184 | self.handle_change(entry.path().to_path_buf(), ChangeKind::Create); | ||
185 | } | ||
186 | } | ||
187 | Err(e) => log::warn!("watcher error: {}", e), | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | |||
193 | fn watch_one(watcher: &Mutex<Option<RecommendedWatcher>>, dir: &Path) { | ||
194 | if let Some(watcher) = watcher.lock().as_mut() { | ||
195 | match watcher.watch(dir, RecursiveMode::NonRecursive) { | ||
196 | Ok(()) => log::debug!("watching \"{}\"", dir.display()), | ||
197 | Err(e) => log::warn!("could not watch \"{}\": {}", dir.display(), e), | ||
198 | } | ||
199 | } | ||
200 | } | ||
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index cdea18d73..70a13f765 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs | |||
@@ -16,52 +16,77 @@ | |||
16 | mod io; | 16 | mod io; |
17 | 17 | ||
18 | use std::{ | 18 | use std::{ |
19 | fmt, | ||
20 | mem, | ||
21 | thread, | ||
22 | cmp::Reverse, | 19 | cmp::Reverse, |
20 | fmt, fs, mem, | ||
21 | ops::{Deref, DerefMut}, | ||
23 | path::{Path, PathBuf}, | 22 | path::{Path, PathBuf}, |
24 | ffi::OsStr, | ||
25 | sync::Arc, | 23 | sync::Arc, |
26 | fs, | 24 | thread, |
27 | }; | 25 | }; |
28 | 26 | ||
29 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
30 | use relative_path::RelativePathBuf; | ||
31 | use crossbeam_channel::Receiver; | 27 | use crossbeam_channel::Receiver; |
28 | use ra_arena::{impl_arena_id, Arena, RawId}; | ||
29 | use relative_path::{Component, RelativePath, RelativePathBuf}; | ||
30 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
32 | use walkdir::DirEntry; | 31 | use walkdir::DirEntry; |
33 | use thread_worker::WorkerHandle; | ||
34 | use ra_arena::{Arena, RawId, impl_arena_id}; | ||
35 | 32 | ||
36 | pub use crate::io::TaskResult as VfsTask; | 33 | pub use crate::io::TaskResult as VfsTask; |
34 | use io::{TaskResult, Worker}; | ||
37 | 35 | ||
38 | /// `RootFilter` is a predicate that checks if a file can belong to a root. If | 36 | /// `RootFilter` is a predicate that checks if a file can belong to a root. If |
39 | /// several filters match a file (nested dirs), the most nested one wins. | 37 | /// several filters match a file (nested dirs), the most nested one wins. |
40 | struct RootFilter { | 38 | pub(crate) struct RootFilter { |
41 | root: PathBuf, | 39 | root: PathBuf, |
42 | file_filter: fn(&Path) -> bool, | 40 | filter: fn(&Path, &RelativePath) -> bool, |
41 | excluded_dirs: Vec<PathBuf>, | ||
43 | } | 42 | } |
44 | 43 | ||
45 | impl RootFilter { | 44 | impl RootFilter { |
46 | fn new(root: PathBuf) -> RootFilter { | 45 | fn new(root: PathBuf, excluded_dirs: Vec<PathBuf>) -> RootFilter { |
47 | RootFilter { | 46 | RootFilter { |
48 | root, | 47 | root, |
49 | file_filter: has_rs_extension, | 48 | filter: default_filter, |
49 | excluded_dirs, | ||
50 | } | 50 | } |
51 | } | 51 | } |
52 | /// Check if this root can contain `path`. NB: even if this returns | 52 | /// Check if this root can contain `path`. NB: even if this returns |
53 | /// true, the `path` might actually be conained in some nested root. | 53 | /// true, the `path` might actually be conained in some nested root. |
54 | fn can_contain(&self, path: &Path) -> Option<RelativePathBuf> { | 54 | pub(crate) fn can_contain(&self, path: &Path) -> Option<RelativePathBuf> { |
55 | if !(self.file_filter)(path) { | 55 | let rel_path = path.strip_prefix(&self.root).ok()?; |
56 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
57 | if !(self.filter)(path, rel_path.as_relative_path()) { | ||
56 | return None; | 58 | return None; |
57 | } | 59 | } |
58 | let path = path.strip_prefix(&self.root).ok()?; | 60 | Some(rel_path) |
59 | RelativePathBuf::from_path(path).ok() | 61 | } |
62 | |||
63 | pub(crate) fn entry_filter<'a>(&'a self) -> impl FnMut(&DirEntry) -> bool + 'a { | ||
64 | move |entry: &DirEntry| { | ||
65 | if entry.file_type().is_dir() && self.excluded_dirs.iter().any(|it| it == entry.path()) | ||
66 | { | ||
67 | // do not walk nested roots | ||
68 | false | ||
69 | } else { | ||
70 | self.can_contain(entry.path()).is_some() | ||
71 | } | ||
72 | } | ||
60 | } | 73 | } |
61 | } | 74 | } |
62 | 75 | ||
63 | fn has_rs_extension(p: &Path) -> bool { | 76 | pub(crate) fn default_filter(path: &Path, rel_path: &RelativePath) -> bool { |
64 | p.extension() == Some(OsStr::new("rs")) | 77 | if path.is_dir() { |
78 | for (i, c) in rel_path.components().enumerate() { | ||
79 | if let Component::Normal(c) = c { | ||
80 | // TODO hardcoded for now | ||
81 | if (i == 0 && c == "target") || c == ".git" || c == "node_modules" { | ||
82 | return false; | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | true | ||
87 | } else { | ||
88 | rel_path.extension() == Some("rs") | ||
89 | } | ||
65 | } | 90 | } |
66 | 91 | ||
67 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 92 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
@@ -75,16 +100,58 @@ impl_arena_id!(VfsFile); | |||
75 | struct VfsFileData { | 100 | struct VfsFileData { |
76 | root: VfsRoot, | 101 | root: VfsRoot, |
77 | path: RelativePathBuf, | 102 | path: RelativePathBuf, |
103 | is_overlayed: bool, | ||
78 | text: Arc<String>, | 104 | text: Arc<String>, |
79 | } | 105 | } |
80 | 106 | ||
107 | pub(crate) struct Roots { | ||
108 | roots: Arena<VfsRoot, Arc<RootFilter>>, | ||
109 | } | ||
110 | |||
111 | impl Roots { | ||
112 | pub(crate) fn new(mut paths: Vec<PathBuf>) -> Roots { | ||
113 | let mut roots = Arena::default(); | ||
114 | // A hack to make nesting work. | ||
115 | paths.sort_by_key(|it| Reverse(it.as_os_str().len())); | ||
116 | for (i, path) in paths.iter().enumerate() { | ||
117 | let nested_roots = paths[..i] | ||
118 | .iter() | ||
119 | .filter(|it| it.starts_with(path)) | ||
120 | .map(|it| it.clone()) | ||
121 | .collect::<Vec<_>>(); | ||
122 | |||
123 | let root_filter = Arc::new(RootFilter::new(path.clone(), nested_roots)); | ||
124 | |||
125 | roots.alloc(root_filter.clone()); | ||
126 | } | ||
127 | Roots { roots } | ||
128 | } | ||
129 | pub(crate) fn find(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf)> { | ||
130 | self.roots | ||
131 | .iter() | ||
132 | .find_map(|(root, data)| data.can_contain(path).map(|it| (root, it))) | ||
133 | } | ||
134 | } | ||
135 | |||
136 | impl Deref for Roots { | ||
137 | type Target = Arena<VfsRoot, Arc<RootFilter>>; | ||
138 | fn deref(&self) -> &Self::Target { | ||
139 | &self.roots | ||
140 | } | ||
141 | } | ||
142 | |||
143 | impl DerefMut for Roots { | ||
144 | fn deref_mut(&mut self) -> &mut Self::Target { | ||
145 | &mut self.roots | ||
146 | } | ||
147 | } | ||
148 | |||
81 | pub struct Vfs { | 149 | pub struct Vfs { |
82 | roots: Arena<VfsRoot, RootFilter>, | 150 | roots: Arc<Roots>, |
83 | files: Arena<VfsFile, VfsFileData>, | 151 | files: Arena<VfsFile, VfsFileData>, |
84 | root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>, | 152 | root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>, |
85 | pending_changes: Vec<VfsChange>, | 153 | pending_changes: Vec<VfsChange>, |
86 | worker: io::Worker, | 154 | worker: Worker, |
87 | worker_handle: WorkerHandle, | ||
88 | } | 155 | } |
89 | 156 | ||
90 | impl fmt::Debug for Vfs { | 157 | impl fmt::Debug for Vfs { |
@@ -94,44 +161,30 @@ impl fmt::Debug for Vfs { | |||
94 | } | 161 | } |
95 | 162 | ||
96 | impl Vfs { | 163 | impl Vfs { |
97 | pub fn new(mut roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) { | 164 | pub fn new(roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) { |
98 | let (worker, worker_handle) = io::start(); | 165 | let roots = Arc::new(Roots::new(roots)); |
99 | 166 | let worker = io::Worker::start(roots.clone()); | |
100 | let mut res = Vfs { | 167 | let mut root2files = FxHashMap::default(); |
101 | roots: Arena::default(), | 168 | |
169 | for (root, filter) in roots.iter() { | ||
170 | root2files.insert(root, Default::default()); | ||
171 | worker | ||
172 | .sender() | ||
173 | .send(io::Task::AddRoot { | ||
174 | root, | ||
175 | filter: filter.clone(), | ||
176 | }) | ||
177 | .unwrap(); | ||
178 | } | ||
179 | let res = Vfs { | ||
180 | roots, | ||
102 | files: Arena::default(), | 181 | files: Arena::default(), |
103 | root2files: FxHashMap::default(), | 182 | root2files, |
104 | worker, | 183 | worker, |
105 | worker_handle, | ||
106 | pending_changes: Vec::new(), | 184 | pending_changes: Vec::new(), |
107 | }; | 185 | }; |
108 | 186 | let vfs_roots = res.roots.iter().map(|(id, _)| id).collect(); | |
109 | // A hack to make nesting work. | 187 | (res, vfs_roots) |
110 | roots.sort_by_key(|it| Reverse(it.as_os_str().len())); | ||
111 | for (i, path) in roots.iter().enumerate() { | ||
112 | let root = res.roots.alloc(RootFilter::new(path.clone())); | ||
113 | res.root2files.insert(root, Default::default()); | ||
114 | let nested = roots[..i] | ||
115 | .iter() | ||
116 | .filter(|it| it.starts_with(path)) | ||
117 | .map(|it| it.clone()) | ||
118 | .collect::<Vec<_>>(); | ||
119 | let filter = move |entry: &DirEntry| { | ||
120 | if entry.file_type().is_file() { | ||
121 | has_rs_extension(entry.path()) | ||
122 | } else { | ||
123 | nested.iter().all(|it| it != entry.path()) | ||
124 | } | ||
125 | }; | ||
126 | let task = io::Task { | ||
127 | root, | ||
128 | path: path.clone(), | ||
129 | filter: Box::new(filter), | ||
130 | }; | ||
131 | res.worker.inp.send(task).unwrap(); | ||
132 | } | ||
133 | let roots = res.roots.iter().map(|(id, _)| id).collect(); | ||
134 | (res, roots) | ||
135 | } | 188 | } |
136 | 189 | ||
137 | pub fn root2path(&self, root: VfsRoot) -> PathBuf { | 190 | pub fn root2path(&self, root: VfsRoot) -> PathBuf { |
@@ -165,7 +218,7 @@ impl Vfs { | |||
165 | } else { | 218 | } else { |
166 | let text = fs::read_to_string(path).unwrap_or_default(); | 219 | let text = fs::read_to_string(path).unwrap_or_default(); |
167 | let text = Arc::new(text); | 220 | let text = Arc::new(text); |
168 | let file = self.add_file(root, rel_path.clone(), Arc::clone(&text)); | 221 | let file = self.add_file(root, rel_path.clone(), Arc::clone(&text), false); |
169 | let change = VfsChange::AddFile { | 222 | let change = VfsChange::AddFile { |
170 | file, | 223 | file, |
171 | text, | 224 | text, |
@@ -180,85 +233,132 @@ impl Vfs { | |||
180 | } | 233 | } |
181 | 234 | ||
182 | pub fn task_receiver(&self) -> &Receiver<io::TaskResult> { | 235 | pub fn task_receiver(&self) -> &Receiver<io::TaskResult> { |
183 | &self.worker.out | 236 | self.worker.receiver() |
184 | } | 237 | } |
185 | 238 | ||
186 | pub fn handle_task(&mut self, task: io::TaskResult) { | 239 | pub fn handle_task(&mut self, task: io::TaskResult) { |
187 | let mut files = Vec::new(); | 240 | match task { |
188 | // While we were scanning the root in the backgound, a file might have | 241 | TaskResult::BulkLoadRoot { root, files } => { |
189 | // been open in the editor, so we need to account for that. | 242 | let mut cur_files = Vec::new(); |
190 | let exising = self.root2files[&task.root] | 243 | // While we were scanning the root in the backgound, a file might have |
191 | .iter() | 244 | // been open in the editor, so we need to account for that. |
192 | .map(|&file| (self.files[file].path.clone(), file)) | 245 | let exising = self.root2files[&root] |
193 | .collect::<FxHashMap<_, _>>(); | 246 | .iter() |
194 | for (path, text) in task.files { | 247 | .map(|&file| (self.files[file].path.clone(), file)) |
195 | if let Some(&file) = exising.get(&path) { | 248 | .collect::<FxHashMap<_, _>>(); |
196 | let text = Arc::clone(&self.files[file].text); | 249 | for (path, text) in files { |
197 | files.push((file, path, text)); | 250 | if let Some(&file) = exising.get(&path) { |
198 | continue; | 251 | let text = Arc::clone(&self.files[file].text); |
252 | cur_files.push((file, path, text)); | ||
253 | continue; | ||
254 | } | ||
255 | let text = Arc::new(text); | ||
256 | let file = self.add_file(root, path.clone(), Arc::clone(&text), false); | ||
257 | cur_files.push((file, path, text)); | ||
258 | } | ||
259 | |||
260 | let change = VfsChange::AddRoot { | ||
261 | root, | ||
262 | files: cur_files, | ||
263 | }; | ||
264 | self.pending_changes.push(change); | ||
265 | } | ||
266 | TaskResult::AddSingleFile { root, path, text } => { | ||
267 | if self.find_file(root, &path).is_none() { | ||
268 | self.do_add_file(root, path, text, false); | ||
269 | } | ||
270 | } | ||
271 | TaskResult::ChangeSingleFile { root, path, text } => { | ||
272 | if let Some(file) = self.find_file(root, &path) { | ||
273 | self.do_change_file(file, text, false); | ||
274 | } else { | ||
275 | self.do_add_file(root, path, text, false); | ||
276 | } | ||
277 | } | ||
278 | TaskResult::RemoveSingleFile { root, path } => { | ||
279 | if let Some(file) = self.find_file(root, &path) { | ||
280 | self.do_remove_file(root, path, file, false); | ||
281 | } | ||
199 | } | 282 | } |
200 | let text = Arc::new(text); | ||
201 | let file = self.add_file(task.root, path.clone(), Arc::clone(&text)); | ||
202 | files.push((file, path, text)); | ||
203 | } | 283 | } |
284 | } | ||
204 | 285 | ||
205 | let change = VfsChange::AddRoot { | 286 | fn do_add_file( |
206 | root: task.root, | 287 | &mut self, |
207 | files, | 288 | root: VfsRoot, |
208 | }; | 289 | path: RelativePathBuf, |
209 | self.pending_changes.push(change); | 290 | text: String, |
291 | is_overlay: bool, | ||
292 | ) -> Option<VfsFile> { | ||
293 | let text = Arc::new(text); | ||
294 | let file = self.add_file(root, path.clone(), text.clone(), is_overlay); | ||
295 | self.pending_changes.push(VfsChange::AddFile { | ||
296 | file, | ||
297 | root, | ||
298 | path, | ||
299 | text, | ||
300 | }); | ||
301 | Some(file) | ||
302 | } | ||
303 | |||
304 | fn do_change_file(&mut self, file: VfsFile, text: String, is_overlay: bool) { | ||
305 | if !is_overlay && self.files[file].is_overlayed { | ||
306 | return; | ||
307 | } | ||
308 | let text = Arc::new(text); | ||
309 | self.change_file(file, text.clone(), is_overlay); | ||
310 | self.pending_changes | ||
311 | .push(VfsChange::ChangeFile { file, text }); | ||
312 | } | ||
313 | |||
314 | fn do_remove_file( | ||
315 | &mut self, | ||
316 | root: VfsRoot, | ||
317 | path: RelativePathBuf, | ||
318 | file: VfsFile, | ||
319 | is_overlay: bool, | ||
320 | ) { | ||
321 | if !is_overlay && self.files[file].is_overlayed { | ||
322 | return; | ||
323 | } | ||
324 | self.remove_file(file); | ||
325 | self.pending_changes | ||
326 | .push(VfsChange::RemoveFile { root, path, file }); | ||
210 | } | 327 | } |
211 | 328 | ||
212 | pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option<VfsFile> { | 329 | pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option<VfsFile> { |
213 | let mut res = None; | 330 | if let Some((root, rel_path, file)) = self.find_root(path) { |
214 | if let Some((root, path, file)) = self.find_root(path) { | 331 | if let Some(file) = file { |
215 | let text = Arc::new(text); | 332 | self.do_change_file(file, text, true); |
216 | let change = if let Some(file) = file { | 333 | Some(file) |
217 | res = Some(file); | ||
218 | self.change_file(file, Arc::clone(&text)); | ||
219 | VfsChange::ChangeFile { file, text } | ||
220 | } else { | 334 | } else { |
221 | let file = self.add_file(root, path.clone(), Arc::clone(&text)); | 335 | self.do_add_file(root, rel_path, text, true) |
222 | res = Some(file); | 336 | } |
223 | VfsChange::AddFile { | 337 | } else { |
224 | file, | 338 | None |
225 | text, | ||
226 | root, | ||
227 | path, | ||
228 | } | ||
229 | }; | ||
230 | self.pending_changes.push(change); | ||
231 | } | 339 | } |
232 | res | ||
233 | } | 340 | } |
234 | 341 | ||
235 | pub fn change_file_overlay(&mut self, path: &Path, new_text: String) { | 342 | pub fn change_file_overlay(&mut self, path: &Path, new_text: String) { |
236 | if let Some((_root, _path, file)) = self.find_root(path) { | 343 | if let Some((_root, _path, file)) = self.find_root(path) { |
237 | let file = file.expect("can't change a file which wasn't added"); | 344 | let file = file.expect("can't change a file which wasn't added"); |
238 | let text = Arc::new(new_text); | 345 | self.do_change_file(file, new_text, true); |
239 | self.change_file(file, Arc::clone(&text)); | ||
240 | let change = VfsChange::ChangeFile { file, text }; | ||
241 | self.pending_changes.push(change); | ||
242 | } | 346 | } |
243 | } | 347 | } |
244 | 348 | ||
245 | pub fn remove_file_overlay(&mut self, path: &Path) -> Option<VfsFile> { | 349 | pub fn remove_file_overlay(&mut self, path: &Path) -> Option<VfsFile> { |
246 | let mut res = None; | ||
247 | if let Some((root, path, file)) = self.find_root(path) { | 350 | if let Some((root, path, file)) = self.find_root(path) { |
248 | let file = file.expect("can't remove a file which wasn't added"); | 351 | let file = file.expect("can't remove a file which wasn't added"); |
249 | res = Some(file); | ||
250 | let full_path = path.to_path(&self.roots[root].root); | 352 | let full_path = path.to_path(&self.roots[root].root); |
251 | let change = if let Ok(text) = fs::read_to_string(&full_path) { | 353 | if let Ok(text) = fs::read_to_string(&full_path) { |
252 | let text = Arc::new(text); | 354 | self.do_change_file(file, text, true); |
253 | self.change_file(file, Arc::clone(&text)); | ||
254 | VfsChange::ChangeFile { file, text } | ||
255 | } else { | 355 | } else { |
256 | self.remove_file(file); | 356 | self.do_remove_file(root, path, file, true); |
257 | VfsChange::RemoveFile { root, file, path } | 357 | } |
258 | }; | 358 | Some(file) |
259 | self.pending_changes.push(change); | 359 | } else { |
360 | None | ||
260 | } | 361 | } |
261 | res | ||
262 | } | 362 | } |
263 | 363 | ||
264 | pub fn commit_changes(&mut self) -> Vec<VfsChange> { | 364 | pub fn commit_changes(&mut self) -> Vec<VfsChange> { |
@@ -267,19 +367,31 @@ impl Vfs { | |||
267 | 367 | ||
268 | /// Sutdown the VFS and terminate the background watching thread. | 368 | /// Sutdown the VFS and terminate the background watching thread. |
269 | pub fn shutdown(self) -> thread::Result<()> { | 369 | pub fn shutdown(self) -> thread::Result<()> { |
270 | let _ = self.worker.shutdown(); | 370 | self.worker.shutdown() |
271 | self.worker_handle.shutdown() | ||
272 | } | 371 | } |
273 | 372 | ||
274 | fn add_file(&mut self, root: VfsRoot, path: RelativePathBuf, text: Arc<String>) -> VfsFile { | 373 | fn add_file( |
275 | let data = VfsFileData { root, path, text }; | 374 | &mut self, |
375 | root: VfsRoot, | ||
376 | path: RelativePathBuf, | ||
377 | text: Arc<String>, | ||
378 | is_overlayed: bool, | ||
379 | ) -> VfsFile { | ||
380 | let data = VfsFileData { | ||
381 | root, | ||
382 | path, | ||
383 | text, | ||
384 | is_overlayed, | ||
385 | }; | ||
276 | let file = self.files.alloc(data); | 386 | let file = self.files.alloc(data); |
277 | self.root2files.get_mut(&root).unwrap().insert(file); | 387 | self.root2files.get_mut(&root).unwrap().insert(file); |
278 | file | 388 | file |
279 | } | 389 | } |
280 | 390 | ||
281 | fn change_file(&mut self, file: VfsFile, new_text: Arc<String>) { | 391 | fn change_file(&mut self, file: VfsFile, new_text: Arc<String>, is_overlayed: bool) { |
282 | self.files[file].text = new_text; | 392 | let mut file_data = &mut self.files[file]; |
393 | file_data.text = new_text; | ||
394 | file_data.is_overlayed = is_overlayed; | ||
283 | } | 395 | } |
284 | 396 | ||
285 | fn remove_file(&mut self, file: VfsFile) { | 397 | fn remove_file(&mut self, file: VfsFile) { |
@@ -292,15 +404,16 @@ impl Vfs { | |||
292 | } | 404 | } |
293 | 405 | ||
294 | fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> { | 406 | fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option<VfsFile>)> { |
295 | let (root, path) = self | 407 | let (root, path) = self.roots.find(&path)?; |
296 | .roots | 408 | let file = self.find_file(root, &path); |
297 | .iter() | 409 | Some((root, path, file)) |
298 | .find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))?; | 410 | } |
299 | let file = self.root2files[&root] | 411 | |
412 | fn find_file(&self, root: VfsRoot, path: &RelativePath) -> Option<VfsFile> { | ||
413 | self.root2files[&root] | ||
300 | .iter() | 414 | .iter() |
301 | .map(|&it| it) | 415 | .map(|&it| it) |
302 | .find(|&file| self.files[file].path == path); | 416 | .find(|&file| self.files[file].path == path) |
303 | Some((root, path, file)) | ||
304 | } | 417 | } |
305 | } | 418 | } |
306 | 419 | ||
diff --git a/crates/ra_vfs/tests/vfs.rs b/crates/ra_vfs/tests/vfs.rs index f56fc4603..545e1dbdd 100644 --- a/crates/ra_vfs/tests/vfs.rs +++ b/crates/ra_vfs/tests/vfs.rs | |||
@@ -1,24 +1,47 @@ | |||
1 | use std::{ | 1 | use std::{collections::HashSet, fs, time::Duration}; |
2 | fs, | ||
3 | collections::HashSet, | ||
4 | }; | ||
5 | 2 | ||
3 | // use flexi_logger::Logger; | ||
4 | use crossbeam_channel::RecvTimeoutError; | ||
5 | use ra_vfs::{Vfs, VfsChange}; | ||
6 | use tempfile::tempdir; | 6 | use tempfile::tempdir; |
7 | 7 | ||
8 | use ra_vfs::{Vfs, VfsChange}; | 8 | fn process_tasks(vfs: &mut Vfs, num_tasks: u32) { |
9 | for _ in 0..num_tasks { | ||
10 | let task = vfs | ||
11 | .task_receiver() | ||
12 | .recv_timeout(Duration::from_secs(3)) | ||
13 | .unwrap(); | ||
14 | log::debug!("{:?}", task); | ||
15 | vfs.handle_task(task); | ||
16 | } | ||
17 | } | ||
18 | |||
19 | macro_rules! assert_match { | ||
20 | ($x:expr, $pat:pat) => { | ||
21 | assert_match!($x, $pat, ()) | ||
22 | }; | ||
23 | ($x:expr, $pat:pat, $assert:expr) => { | ||
24 | match $x { | ||
25 | $pat => $assert, | ||
26 | x => assert!(false, "Expected {}, got {:?}", stringify!($pat), x), | ||
27 | }; | ||
28 | }; | ||
29 | } | ||
9 | 30 | ||
10 | #[test] | 31 | #[test] |
11 | fn test_vfs_works() -> std::io::Result<()> { | 32 | fn test_vfs_works() -> std::io::Result<()> { |
33 | // Logger::with_str("vfs=debug,ra_vfs=debug").start().unwrap(); | ||
34 | |||
12 | let files = [ | 35 | let files = [ |
13 | ("a/foo.rs", "hello"), | 36 | ("a/foo.rs", "hello"), |
14 | ("a/bar.rs", "world"), | 37 | ("a/bar.rs", "world"), |
15 | ("a/b/baz.rs", "nested hello"), | 38 | ("a/b/baz.rs", "nested hello"), |
16 | ]; | 39 | ]; |
17 | 40 | ||
18 | let dir = tempdir()?; | 41 | let dir = tempdir().unwrap(); |
19 | for (path, text) in files.iter() { | 42 | for (path, text) in files.iter() { |
20 | let file_path = dir.path().join(path); | 43 | let file_path = dir.path().join(path); |
21 | fs::create_dir_all(file_path.parent().unwrap())?; | 44 | fs::create_dir_all(file_path.parent().unwrap()).unwrap(); |
22 | fs::write(file_path, text)? | 45 | fs::write(file_path, text)? |
23 | } | 46 | } |
24 | 47 | ||
@@ -26,10 +49,7 @@ fn test_vfs_works() -> std::io::Result<()> { | |||
26 | let b_root = dir.path().join("a/b"); | 49 | let b_root = dir.path().join("a/b"); |
27 | 50 | ||
28 | let (mut vfs, _) = Vfs::new(vec![a_root, b_root]); | 51 | let (mut vfs, _) = Vfs::new(vec![a_root, b_root]); |
29 | for _ in 0..2 { | 52 | process_tasks(&mut vfs, 2); |
30 | let task = vfs.task_receiver().recv().unwrap(); | ||
31 | vfs.handle_task(task); | ||
32 | } | ||
33 | { | 53 | { |
34 | let files = vfs | 54 | let files = vfs |
35 | .commit_changes() | 55 | .commit_changes() |
@@ -58,44 +78,114 @@ fn test_vfs_works() -> std::io::Result<()> { | |||
58 | assert_eq!(files, expected_files); | 78 | assert_eq!(files, expected_files); |
59 | } | 79 | } |
60 | 80 | ||
61 | vfs.add_file_overlay(&dir.path().join("a/b/baz.rs"), "quux".to_string()); | 81 | fs::write(&dir.path().join("a/b/baz.rs"), "quux").unwrap(); |
62 | let change = vfs.commit_changes().pop().unwrap(); | 82 | process_tasks(&mut vfs, 1); |
63 | match change { | 83 | assert_match!( |
64 | VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "quux"), | 84 | vfs.commit_changes().as_slice(), |
65 | _ => panic!("unexpected change"), | 85 | [VfsChange::ChangeFile { text, .. }], |
66 | } | 86 | assert_eq!(text.as_str(), "quux") |
87 | ); | ||
67 | 88 | ||
68 | vfs.change_file_overlay(&dir.path().join("a/b/baz.rs"), "m".to_string()); | 89 | vfs.add_file_overlay(&dir.path().join("a/b/baz.rs"), "m".to_string()); |
69 | let change = vfs.commit_changes().pop().unwrap(); | 90 | assert_match!( |
70 | match change { | 91 | vfs.commit_changes().as_slice(), |
71 | VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "m"), | 92 | [VfsChange::ChangeFile { text, .. }], |
72 | _ => panic!("unexpected change"), | 93 | assert_eq!(text.as_str(), "m") |
73 | } | 94 | ); |
74 | 95 | ||
96 | // changing file on disk while overlayed doesn't generate a VfsChange | ||
97 | fs::write(&dir.path().join("a/b/baz.rs"), "corge").unwrap(); | ||
98 | process_tasks(&mut vfs, 1); | ||
99 | assert_match!(vfs.commit_changes().as_slice(), []); | ||
100 | |||
101 | // removing overlay restores data on disk | ||
75 | vfs.remove_file_overlay(&dir.path().join("a/b/baz.rs")); | 102 | vfs.remove_file_overlay(&dir.path().join("a/b/baz.rs")); |
76 | let change = vfs.commit_changes().pop().unwrap(); | 103 | assert_match!( |
77 | match change { | 104 | vfs.commit_changes().as_slice(), |
78 | VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "nested hello"), | 105 | [VfsChange::ChangeFile { text, .. }], |
79 | _ => panic!("unexpected change"), | 106 | assert_eq!(text.as_str(), "corge") |
80 | } | 107 | ); |
81 | 108 | ||
82 | vfs.add_file_overlay(&dir.path().join("a/b/spam.rs"), "spam".to_string()); | 109 | vfs.add_file_overlay(&dir.path().join("a/b/spam.rs"), "spam".to_string()); |
83 | let change = vfs.commit_changes().pop().unwrap(); | 110 | assert_match!( |
84 | match change { | 111 | vfs.commit_changes().as_slice(), |
85 | VfsChange::AddFile { text, path, .. } => { | 112 | [VfsChange::AddFile { text, path, .. }], |
86 | assert_eq!(&*text, "spam"); | 113 | { |
114 | assert_eq!(text.as_str(), "spam"); | ||
87 | assert_eq!(path, "spam.rs"); | 115 | assert_eq!(path, "spam.rs"); |
88 | } | 116 | } |
89 | _ => panic!("unexpected change"), | 117 | ); |
90 | } | ||
91 | 118 | ||
92 | vfs.remove_file_overlay(&dir.path().join("a/b/spam.rs")); | 119 | vfs.remove_file_overlay(&dir.path().join("a/b/spam.rs")); |
93 | let change = vfs.commit_changes().pop().unwrap(); | 120 | assert_match!( |
94 | match change { | 121 | vfs.commit_changes().as_slice(), |
95 | VfsChange::RemoveFile { .. } => (), | 122 | [VfsChange::RemoveFile { path, .. }], |
96 | _ => panic!("unexpected change"), | 123 | assert_eq!(path, "spam.rs") |
124 | ); | ||
125 | |||
126 | fs::create_dir_all(dir.path().join("a/sub1/sub2")).unwrap(); | ||
127 | fs::write(dir.path().join("a/sub1/sub2/new.rs"), "new hello").unwrap(); | ||
128 | process_tasks(&mut vfs, 1); | ||
129 | assert_match!( | ||
130 | vfs.commit_changes().as_slice(), | ||
131 | [VfsChange::AddFile { text, path, .. }], | ||
132 | { | ||
133 | assert_eq!(text.as_str(), "new hello"); | ||
134 | assert_eq!(path, "sub1/sub2/new.rs"); | ||
135 | } | ||
136 | ); | ||
137 | |||
138 | fs::rename( | ||
139 | &dir.path().join("a/sub1/sub2/new.rs"), | ||
140 | &dir.path().join("a/sub1/sub2/new1.rs"), | ||
141 | ) | ||
142 | .unwrap(); | ||
143 | process_tasks(&mut vfs, 2); | ||
144 | assert_match!( | ||
145 | vfs.commit_changes().as_slice(), | ||
146 | [VfsChange::RemoveFile { | ||
147 | path: removed_path, .. | ||
148 | }, VfsChange::AddFile { | ||
149 | text, | ||
150 | path: added_path, | ||
151 | .. | ||
152 | }], | ||
153 | { | ||
154 | assert_eq!(removed_path, "sub1/sub2/new.rs"); | ||
155 | assert_eq!(added_path, "sub1/sub2/new1.rs"); | ||
156 | assert_eq!(text.as_str(), "new hello"); | ||
157 | } | ||
158 | ); | ||
159 | |||
160 | fs::remove_file(&dir.path().join("a/sub1/sub2/new1.rs")).unwrap(); | ||
161 | process_tasks(&mut vfs, 1); | ||
162 | assert_match!( | ||
163 | vfs.commit_changes().as_slice(), | ||
164 | [VfsChange::RemoveFile { path, .. }], | ||
165 | assert_eq!(path, "sub1/sub2/new1.rs") | ||
166 | ); | ||
167 | |||
168 | { | ||
169 | vfs.add_file_overlay(&dir.path().join("a/memfile.rs"), "memfile".to_string()); | ||
170 | assert_match!( | ||
171 | vfs.commit_changes().as_slice(), | ||
172 | [VfsChange::AddFile { text, .. }], | ||
173 | assert_eq!(text.as_str(), "memfile") | ||
174 | ); | ||
175 | fs::write(&dir.path().join("a/memfile.rs"), "ignore me").unwrap(); | ||
176 | process_tasks(&mut vfs, 1); | ||
177 | assert_match!(vfs.commit_changes().as_slice(), []); | ||
97 | } | 178 | } |
98 | 179 | ||
180 | // should be ignored | ||
181 | fs::create_dir_all(dir.path().join("a/target")).unwrap(); | ||
182 | fs::write(&dir.path().join("a/target/new.rs"), "ignore me").unwrap(); | ||
183 | |||
184 | assert_match!( | ||
185 | vfs.task_receiver().recv_timeout(Duration::from_millis(300)), // slightly more than watcher debounce delay | ||
186 | Err(RecvTimeoutError::Timeout) | ||
187 | ); | ||
188 | |||
99 | vfs.shutdown().unwrap(); | 189 | vfs.shutdown().unwrap(); |
100 | Ok(()) | 190 | Ok(()) |
101 | } | 191 | } |