diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-14 20:58:20 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-14 20:58:20 +0000 |
commit | e8e82ce032f8678929b015e6f70ac060bb2cf94c (patch) | |
tree | 9fb158e9f7115bb70cf2b8623b70710c55497ed4 /crates/ra_syntax | |
parent | 784ff638e549a27503b719e5c2f0009b40d25364 (diff) | |
parent | 37ba237e6686d94783d1f025d23823ad7c0cb0c8 (diff) |
Merge #485
485: Add type inference for a bunch of primitives r=flodiebold a=marcusklaas
This PR adds inference for `&str`, `&[u8]`, `char`, `bool`, floats and integers. For floats and integers it uses type variables to infer the exact type, i.e. `u32`, from context when it's not annotated explicitly.
I'm not quite happy with the implementation yet, but I think it mostly works now.
Co-authored-by: Marcus Klaas de Vries <[email protected]>
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 46 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 220 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 23 | ||||
-rw-r--r-- | crates/ra_syntax/src/lexer/strings.rs | 15 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 5 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow.rs | 12 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow/syntax_text.rs | 11 |
7 files changed, 315 insertions, 17 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 8bf439b60..211ba31e5 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -609,6 +609,52 @@ impl SelfParam { | |||
609 | } | 609 | } |
610 | } | 610 | } |
611 | 611 | ||
612 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
613 | pub enum LiteralFlavor { | ||
614 | String, | ||
615 | ByteString, | ||
616 | Char, | ||
617 | Byte, | ||
618 | IntNumber { suffix: Option<SmolStr> }, | ||
619 | FloatNumber { suffix: Option<SmolStr> }, | ||
620 | Bool, | ||
621 | } | ||
622 | |||
623 | impl LiteralExpr { | ||
624 | pub fn flavor(&self) -> LiteralFlavor { | ||
625 | let syntax = self.syntax(); | ||
626 | match syntax.kind() { | ||
627 | INT_NUMBER => { | ||
628 | let allowed_suffix_list = [ | ||
629 | "isize", "i128", "i64", "i32", "i16", "i8", "usize", "u128", "u64", "u32", | ||
630 | "u16", "u8", | ||
631 | ]; | ||
632 | let text = syntax.text().to_string(); | ||
633 | let suffix = allowed_suffix_list | ||
634 | .iter() | ||
635 | .find(|&s| text.ends_with(s)) | ||
636 | .map(|&suf| SmolStr::new(suf)); | ||
637 | LiteralFlavor::IntNumber { suffix: suffix } | ||
638 | } | ||
639 | FLOAT_NUMBER => { | ||
640 | let allowed_suffix_list = ["f64", "f32"]; | ||
641 | let text = syntax.text().to_string(); | ||
642 | let suffix = allowed_suffix_list | ||
643 | .iter() | ||
644 | .find(|&s| text.ends_with(s)) | ||
645 | .map(|&suf| SmolStr::new(suf)); | ||
646 | LiteralFlavor::FloatNumber { suffix: suffix } | ||
647 | } | ||
648 | STRING | RAW_STRING => LiteralFlavor::String, | ||
649 | TRUE_KW | FALSE_KW => LiteralFlavor::Bool, | ||
650 | BYTE_STRING | RAW_BYTE_STRING => LiteralFlavor::ByteString, | ||
651 | CHAR => LiteralFlavor::Char, | ||
652 | BYTE => LiteralFlavor::Byte, | ||
653 | _ => unreachable!(), | ||
654 | } | ||
655 | } | ||
656 | } | ||
657 | |||
612 | #[test] | 658 | #[test] |
613 | fn test_doc_comment_of_items() { | 659 | fn test_doc_comment_of_items() { |
614 | let file = SourceFile::parse( | 660 | let file = SourceFile::parse( |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 94842a514..3471d5226 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -793,6 +793,31 @@ impl AstNode for ExternCrateItem { | |||
793 | 793 | ||
794 | impl ExternCrateItem {} | 794 | impl ExternCrateItem {} |
795 | 795 | ||
796 | // FalseKw | ||
797 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
798 | #[repr(transparent)] | ||
799 | pub struct FalseKw { | ||
800 | pub(crate) syntax: SyntaxNode, | ||
801 | } | ||
802 | unsafe impl TransparentNewType for FalseKw { | ||
803 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
804 | } | ||
805 | |||
806 | impl AstNode for FalseKw { | ||
807 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
808 | match syntax.kind() { | ||
809 | FALSE_KW => Some(FalseKw::from_repr(syntax.into_repr())), | ||
810 | _ => None, | ||
811 | } | ||
812 | } | ||
813 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
814 | fn to_owned(&self) -> TreeArc<FalseKw> { TreeArc::cast(self.syntax.to_owned()) } | ||
815 | } | ||
816 | |||
817 | |||
818 | impl ast::AstToken for FalseKw {} | ||
819 | impl FalseKw {} | ||
820 | |||
796 | // FieldExpr | 821 | // FieldExpr |
797 | #[derive(Debug, PartialEq, Eq, Hash)] | 822 | #[derive(Debug, PartialEq, Eq, Hash)] |
798 | #[repr(transparent)] | 823 | #[repr(transparent)] |
@@ -849,6 +874,31 @@ impl AstNode for FieldPatList { | |||
849 | 874 | ||
850 | impl FieldPatList {} | 875 | impl FieldPatList {} |
851 | 876 | ||
877 | // FloatNumber | ||
878 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
879 | #[repr(transparent)] | ||
880 | pub struct FloatNumber { | ||
881 | pub(crate) syntax: SyntaxNode, | ||
882 | } | ||
883 | unsafe impl TransparentNewType for FloatNumber { | ||
884 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
885 | } | ||
886 | |||
887 | impl AstNode for FloatNumber { | ||
888 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
889 | match syntax.kind() { | ||
890 | FLOAT_NUMBER => Some(FloatNumber::from_repr(syntax.into_repr())), | ||
891 | _ => None, | ||
892 | } | ||
893 | } | ||
894 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
895 | fn to_owned(&self) -> TreeArc<FloatNumber> { TreeArc::cast(self.syntax.to_owned()) } | ||
896 | } | ||
897 | |||
898 | |||
899 | impl ast::AstToken for FloatNumber {} | ||
900 | impl FloatNumber {} | ||
901 | |||
852 | // FnDef | 902 | // FnDef |
853 | #[derive(Debug, PartialEq, Eq, Hash)] | 903 | #[derive(Debug, PartialEq, Eq, Hash)] |
854 | #[repr(transparent)] | 904 | #[repr(transparent)] |
@@ -1130,6 +1180,31 @@ impl AstNode for IndexExpr { | |||
1130 | 1180 | ||
1131 | impl IndexExpr {} | 1181 | impl IndexExpr {} |
1132 | 1182 | ||
1183 | // IntNumber | ||
1184 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
1185 | #[repr(transparent)] | ||
1186 | pub struct IntNumber { | ||
1187 | pub(crate) syntax: SyntaxNode, | ||
1188 | } | ||
1189 | unsafe impl TransparentNewType for IntNumber { | ||
1190 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
1191 | } | ||
1192 | |||
1193 | impl AstNode for IntNumber { | ||
1194 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
1195 | match syntax.kind() { | ||
1196 | INT_NUMBER => Some(IntNumber::from_repr(syntax.into_repr())), | ||
1197 | _ => None, | ||
1198 | } | ||
1199 | } | ||
1200 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1201 | fn to_owned(&self) -> TreeArc<IntNumber> { TreeArc::cast(self.syntax.to_owned()) } | ||
1202 | } | ||
1203 | |||
1204 | |||
1205 | impl ast::AstToken for IntNumber {} | ||
1206 | impl IntNumber {} | ||
1207 | |||
1133 | // ItemList | 1208 | // ItemList |
1134 | #[derive(Debug, PartialEq, Eq, Hash)] | 1209 | #[derive(Debug, PartialEq, Eq, Hash)] |
1135 | #[repr(transparent)] | 1210 | #[repr(transparent)] |
@@ -1327,7 +1402,75 @@ impl AstNode for Literal { | |||
1327 | } | 1402 | } |
1328 | 1403 | ||
1329 | 1404 | ||
1330 | impl Literal {} | 1405 | impl Literal { |
1406 | pub fn literal_expr(&self) -> Option<&LiteralExpr> { | ||
1407 | super::child_opt(self) | ||
1408 | } | ||
1409 | } | ||
1410 | |||
1411 | // LiteralExpr | ||
1412 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
1413 | #[repr(transparent)] | ||
1414 | pub struct LiteralExpr { | ||
1415 | pub(crate) syntax: SyntaxNode, | ||
1416 | } | ||
1417 | unsafe impl TransparentNewType for LiteralExpr { | ||
1418 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
1419 | } | ||
1420 | |||
1421 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
1422 | pub enum LiteralExprKind<'a> { | ||
1423 | String(&'a String), | ||
1424 | ByteString(&'a ByteString), | ||
1425 | RawString(&'a RawString), | ||
1426 | RawByteString(&'a RawByteString), | ||
1427 | Char(&'a Char), | ||
1428 | Byte(&'a Byte), | ||
1429 | IntNumber(&'a IntNumber), | ||
1430 | FloatNumber(&'a FloatNumber), | ||
1431 | TrueKw(&'a TrueKw), | ||
1432 | FalseKw(&'a FalseKw), | ||
1433 | } | ||
1434 | |||
1435 | impl AstNode for LiteralExpr { | ||
1436 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
1437 | match syntax.kind() { | ||
1438 | | STRING | ||
1439 | | BYTE_STRING | ||
1440 | | RAW_STRING | ||
1441 | | RAW_BYTE_STRING | ||
1442 | | CHAR | ||
1443 | | BYTE | ||
1444 | | INT_NUMBER | ||
1445 | | FLOAT_NUMBER | ||
1446 | | TRUE_KW | ||
1447 | | FALSE_KW => Some(LiteralExpr::from_repr(syntax.into_repr())), | ||
1448 | _ => None, | ||
1449 | } | ||
1450 | } | ||
1451 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1452 | fn to_owned(&self) -> TreeArc<LiteralExpr> { TreeArc::cast(self.syntax.to_owned()) } | ||
1453 | } | ||
1454 | |||
1455 | impl LiteralExpr { | ||
1456 | pub fn kind(&self) -> LiteralExprKind { | ||
1457 | match self.syntax.kind() { | ||
1458 | STRING => LiteralExprKind::String(String::cast(&self.syntax).unwrap()), | ||
1459 | BYTE_STRING => LiteralExprKind::ByteString(ByteString::cast(&self.syntax).unwrap()), | ||
1460 | RAW_STRING => LiteralExprKind::RawString(RawString::cast(&self.syntax).unwrap()), | ||
1461 | RAW_BYTE_STRING => LiteralExprKind::RawByteString(RawByteString::cast(&self.syntax).unwrap()), | ||
1462 | CHAR => LiteralExprKind::Char(Char::cast(&self.syntax).unwrap()), | ||
1463 | BYTE => LiteralExprKind::Byte(Byte::cast(&self.syntax).unwrap()), | ||
1464 | INT_NUMBER => LiteralExprKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()), | ||
1465 | FLOAT_NUMBER => LiteralExprKind::FloatNumber(FloatNumber::cast(&self.syntax).unwrap()), | ||
1466 | TRUE_KW => LiteralExprKind::TrueKw(TrueKw::cast(&self.syntax).unwrap()), | ||
1467 | FALSE_KW => LiteralExprKind::FalseKw(FalseKw::cast(&self.syntax).unwrap()), | ||
1468 | _ => unreachable!(), | ||
1469 | } | ||
1470 | } | ||
1471 | } | ||
1472 | |||
1473 | impl LiteralExpr {} | ||
1331 | 1474 | ||
1332 | // LoopExpr | 1475 | // LoopExpr |
1333 | #[derive(Debug, PartialEq, Eq, Hash)] | 1476 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -2406,6 +2549,56 @@ impl AstNode for RangePat { | |||
2406 | 2549 | ||
2407 | impl RangePat {} | 2550 | impl RangePat {} |
2408 | 2551 | ||
2552 | // RawByteString | ||
2553 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
2554 | #[repr(transparent)] | ||
2555 | pub struct RawByteString { | ||
2556 | pub(crate) syntax: SyntaxNode, | ||
2557 | } | ||
2558 | unsafe impl TransparentNewType for RawByteString { | ||
2559 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
2560 | } | ||
2561 | |||
2562 | impl AstNode for RawByteString { | ||
2563 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
2564 | match syntax.kind() { | ||
2565 | RAW_BYTE_STRING => Some(RawByteString::from_repr(syntax.into_repr())), | ||
2566 | _ => None, | ||
2567 | } | ||
2568 | } | ||
2569 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2570 | fn to_owned(&self) -> TreeArc<RawByteString> { TreeArc::cast(self.syntax.to_owned()) } | ||
2571 | } | ||
2572 | |||
2573 | |||
2574 | impl ast::AstToken for RawByteString {} | ||
2575 | impl RawByteString {} | ||
2576 | |||
2577 | // RawString | ||
2578 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
2579 | #[repr(transparent)] | ||
2580 | pub struct RawString { | ||
2581 | pub(crate) syntax: SyntaxNode, | ||
2582 | } | ||
2583 | unsafe impl TransparentNewType for RawString { | ||
2584 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
2585 | } | ||
2586 | |||
2587 | impl AstNode for RawString { | ||
2588 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
2589 | match syntax.kind() { | ||
2590 | RAW_STRING => Some(RawString::from_repr(syntax.into_repr())), | ||
2591 | _ => None, | ||
2592 | } | ||
2593 | } | ||
2594 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2595 | fn to_owned(&self) -> TreeArc<RawString> { TreeArc::cast(self.syntax.to_owned()) } | ||
2596 | } | ||
2597 | |||
2598 | |||
2599 | impl ast::AstToken for RawString {} | ||
2600 | impl RawString {} | ||
2601 | |||
2409 | // RefExpr | 2602 | // RefExpr |
2410 | #[derive(Debug, PartialEq, Eq, Hash)] | 2603 | #[derive(Debug, PartialEq, Eq, Hash)] |
2411 | #[repr(transparent)] | 2604 | #[repr(transparent)] |
@@ -2919,6 +3112,31 @@ impl ast::AttrsOwner for TraitDef {} | |||
2919 | impl ast::DocCommentsOwner for TraitDef {} | 3112 | impl ast::DocCommentsOwner for TraitDef {} |
2920 | impl TraitDef {} | 3113 | impl TraitDef {} |
2921 | 3114 | ||
3115 | // TrueKw | ||
3116 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3117 | #[repr(transparent)] | ||
3118 | pub struct TrueKw { | ||
3119 | pub(crate) syntax: SyntaxNode, | ||
3120 | } | ||
3121 | unsafe impl TransparentNewType for TrueKw { | ||
3122 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
3123 | } | ||
3124 | |||
3125 | impl AstNode for TrueKw { | ||
3126 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3127 | match syntax.kind() { | ||
3128 | TRUE_KW => Some(TrueKw::from_repr(syntax.into_repr())), | ||
3129 | _ => None, | ||
3130 | } | ||
3131 | } | ||
3132 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3133 | fn to_owned(&self) -> TreeArc<TrueKw> { TreeArc::cast(self.syntax.to_owned()) } | ||
3134 | } | ||
3135 | |||
3136 | |||
3137 | impl ast::AstToken for TrueKw {} | ||
3138 | impl TrueKw {} | ||
3139 | |||
2922 | // TryExpr | 3140 | // TryExpr |
2923 | #[derive(Debug, PartialEq, Eq, Hash)] | 3141 | #[derive(Debug, PartialEq, Eq, Hash)] |
2924 | #[repr(transparent)] | 3142 | #[repr(transparent)] |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index dfd88bd10..bd8c5b411 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -426,11 +426,32 @@ Grammar( | |||
426 | "PrefixExpr": (options: ["Expr"]), | 426 | "PrefixExpr": (options: ["Expr"]), |
427 | "RangeExpr": (), | 427 | "RangeExpr": (), |
428 | "BinExpr": (), | 428 | "BinExpr": (), |
429 | |||
430 | "IntNumber": ( traits: ["AstToken"] ), | ||
431 | "FloatNumber": ( traits: ["AstToken"] ), | ||
429 | "String": ( traits: ["AstToken"] ), | 432 | "String": ( traits: ["AstToken"] ), |
433 | "RawString": ( traits: ["AstToken"] ), | ||
430 | "Byte": ( traits: ["AstToken"] ), | 434 | "Byte": ( traits: ["AstToken"] ), |
435 | "RawByteString": ( traits: ["AstToken"] ), | ||
431 | "ByteString": ( traits: ["AstToken"] ), | 436 | "ByteString": ( traits: ["AstToken"] ), |
432 | "Char": ( traits: ["AstToken"] ), | 437 | "Char": ( traits: ["AstToken"] ), |
433 | "Literal": (), | 438 | "TrueKw": ( traits: ["AstToken"] ), |
439 | "FalseKw": ( traits: ["AstToken"] ), | ||
440 | "LiteralExpr": ( | ||
441 | enum: [ | ||
442 | "String", | ||
443 | "ByteString", | ||
444 | "RawString", | ||
445 | "RawByteString", | ||
446 | "Char", | ||
447 | "Byte", | ||
448 | "IntNumber", | ||
449 | "FloatNumber", | ||
450 | "TrueKw", | ||
451 | "FalseKw", | ||
452 | ] | ||
453 | ), | ||
454 | "Literal": (options: ["LiteralExpr"]), | ||
434 | 455 | ||
435 | "Expr": ( | 456 | "Expr": ( |
436 | enum: [ | 457 | enum: [ |
diff --git a/crates/ra_syntax/src/lexer/strings.rs b/crates/ra_syntax/src/lexer/strings.rs index 5090feae6..0865b7f3b 100644 --- a/crates/ra_syntax/src/lexer/strings.rs +++ b/crates/ra_syntax/src/lexer/strings.rs | |||
@@ -49,7 +49,7 @@ pub(crate) fn scan_byte_char_or_string(ptr: &mut Ptr) -> SyntaxKind { | |||
49 | BYTE_STRING | 49 | BYTE_STRING |
50 | } | 50 | } |
51 | 'r' => { | 51 | 'r' => { |
52 | scan_raw_byte_string(ptr); | 52 | scan_raw_string(ptr); |
53 | RAW_BYTE_STRING | 53 | RAW_BYTE_STRING |
54 | } | 54 | } |
55 | _ => unreachable!(), | 55 | _ => unreachable!(), |
@@ -108,16 +108,3 @@ fn scan_byte(ptr: &mut Ptr) { | |||
108 | fn scan_byte_string(ptr: &mut Ptr) { | 108 | fn scan_byte_string(ptr: &mut Ptr) { |
109 | scan_string(ptr) | 109 | scan_string(ptr) |
110 | } | 110 | } |
111 | |||
112 | fn scan_raw_byte_string(ptr: &mut Ptr) { | ||
113 | if !ptr.at('"') { | ||
114 | return; | ||
115 | } | ||
116 | ptr.bump(); | ||
117 | |||
118 | while let Some(c) = ptr.bump() { | ||
119 | if c == '"' { | ||
120 | return; | ||
121 | } | ||
122 | } | ||
123 | } | ||
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 2a095817a..bc311cbbc 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -59,24 +59,29 @@ impl SourceFile { | |||
59 | assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); | 59 | assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); |
60 | TreeArc::cast(root) | 60 | TreeArc::cast(root) |
61 | } | 61 | } |
62 | |||
62 | pub fn parse(text: &str) -> TreeArc<SourceFile> { | 63 | pub fn parse(text: &str) -> TreeArc<SourceFile> { |
63 | let tokens = tokenize(&text); | 64 | let tokens = tokenize(&text); |
64 | let (green, errors) = | 65 | let (green, errors) = |
65 | parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root); | 66 | parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root); |
66 | SourceFile::new(green, errors) | 67 | SourceFile::new(green, errors) |
67 | } | 68 | } |
69 | |||
68 | pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { | 70 | pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { |
69 | self.incremental_reparse(edit) | 71 | self.incremental_reparse(edit) |
70 | .unwrap_or_else(|| self.full_reparse(edit)) | 72 | .unwrap_or_else(|| self.full_reparse(edit)) |
71 | } | 73 | } |
74 | |||
72 | pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> { | 75 | pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> { |
73 | reparsing::incremental_reparse(self.syntax(), edit, self.errors()) | 76 | reparsing::incremental_reparse(self.syntax(), edit, self.errors()) |
74 | .map(|(green_node, errors)| SourceFile::new(green_node, errors)) | 77 | .map(|(green_node, errors)| SourceFile::new(green_node, errors)) |
75 | } | 78 | } |
79 | |||
76 | fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { | 80 | fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { |
77 | let text = edit.apply(self.syntax().text().to_string()); | 81 | let text = edit.apply(self.syntax().text().to_string()); |
78 | SourceFile::parse(&text) | 82 | SourceFile::parse(&text) |
79 | } | 83 | } |
84 | |||
80 | pub fn errors(&self) -> Vec<SyntaxError> { | 85 | pub fn errors(&self) -> Vec<SyntaxError> { |
81 | let mut errors = self.syntax.root_data().clone(); | 86 | let mut errors = self.syntax.root_data().clone(); |
82 | errors.extend(validation::validate(self)); | 87 | errors.extend(validation::validate(self)); |
diff --git a/crates/ra_syntax/src/yellow.rs b/crates/ra_syntax/src/yellow.rs index 93621d08a..9b93945cc 100644 --- a/crates/ra_syntax/src/yellow.rs +++ b/crates/ra_syntax/src/yellow.rs | |||
@@ -128,40 +128,52 @@ impl SyntaxNode { | |||
128 | pub(crate) fn root_data(&self) -> &Vec<SyntaxError> { | 128 | pub(crate) fn root_data(&self) -> &Vec<SyntaxError> { |
129 | self.0.root_data() | 129 | self.0.root_data() |
130 | } | 130 | } |
131 | |||
131 | pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { | 132 | pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { |
132 | self.0.replace_self(replacement) | 133 | self.0.replace_self(replacement) |
133 | } | 134 | } |
135 | |||
134 | pub fn to_owned(&self) -> TreeArc<SyntaxNode> { | 136 | pub fn to_owned(&self) -> TreeArc<SyntaxNode> { |
135 | let ptr = TreeArc(self.0.to_owned()); | 137 | let ptr = TreeArc(self.0.to_owned()); |
136 | TreeArc::cast(ptr) | 138 | TreeArc::cast(ptr) |
137 | } | 139 | } |
140 | |||
138 | pub fn kind(&self) -> SyntaxKind { | 141 | pub fn kind(&self) -> SyntaxKind { |
139 | self.0.kind() | 142 | self.0.kind() |
140 | } | 143 | } |
144 | |||
141 | pub fn range(&self) -> TextRange { | 145 | pub fn range(&self) -> TextRange { |
142 | self.0.range() | 146 | self.0.range() |
143 | } | 147 | } |
148 | |||
144 | pub fn text(&self) -> SyntaxText { | 149 | pub fn text(&self) -> SyntaxText { |
145 | SyntaxText::new(self) | 150 | SyntaxText::new(self) |
146 | } | 151 | } |
152 | |||
147 | pub fn is_leaf(&self) -> bool { | 153 | pub fn is_leaf(&self) -> bool { |
148 | self.0.is_leaf() | 154 | self.0.is_leaf() |
149 | } | 155 | } |
156 | |||
150 | pub fn parent(&self) -> Option<&SyntaxNode> { | 157 | pub fn parent(&self) -> Option<&SyntaxNode> { |
151 | self.0.parent().map(SyntaxNode::from_repr) | 158 | self.0.parent().map(SyntaxNode::from_repr) |
152 | } | 159 | } |
160 | |||
153 | pub fn first_child(&self) -> Option<&SyntaxNode> { | 161 | pub fn first_child(&self) -> Option<&SyntaxNode> { |
154 | self.0.first_child().map(SyntaxNode::from_repr) | 162 | self.0.first_child().map(SyntaxNode::from_repr) |
155 | } | 163 | } |
164 | |||
156 | pub fn last_child(&self) -> Option<&SyntaxNode> { | 165 | pub fn last_child(&self) -> Option<&SyntaxNode> { |
157 | self.0.last_child().map(SyntaxNode::from_repr) | 166 | self.0.last_child().map(SyntaxNode::from_repr) |
158 | } | 167 | } |
168 | |||
159 | pub fn next_sibling(&self) -> Option<&SyntaxNode> { | 169 | pub fn next_sibling(&self) -> Option<&SyntaxNode> { |
160 | self.0.next_sibling().map(SyntaxNode::from_repr) | 170 | self.0.next_sibling().map(SyntaxNode::from_repr) |
161 | } | 171 | } |
172 | |||
162 | pub fn prev_sibling(&self) -> Option<&SyntaxNode> { | 173 | pub fn prev_sibling(&self) -> Option<&SyntaxNode> { |
163 | self.0.prev_sibling().map(SyntaxNode::from_repr) | 174 | self.0.prev_sibling().map(SyntaxNode::from_repr) |
164 | } | 175 | } |
176 | |||
165 | pub fn children(&self) -> SyntaxNodeChildren { | 177 | pub fn children(&self) -> SyntaxNodeChildren { |
166 | SyntaxNodeChildren(self.0.children()) | 178 | SyntaxNodeChildren(self.0.children()) |
167 | } | 179 | } |
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs index 08dbe57a2..378cd1b2e 100644 --- a/crates/ra_syntax/src/yellow/syntax_text.rs +++ b/crates/ra_syntax/src/yellow/syntax_text.rs | |||
@@ -15,6 +15,7 @@ impl<'a> SyntaxText<'a> { | |||
15 | range: node.range(), | 15 | range: node.range(), |
16 | } | 16 | } |
17 | } | 17 | } |
18 | |||
18 | pub fn chunks(&self) -> impl Iterator<Item = &'a str> { | 19 | pub fn chunks(&self) -> impl Iterator<Item = &'a str> { |
19 | let range = self.range; | 20 | let range = self.range; |
20 | self.node.descendants().filter_map(move |node| { | 21 | self.node.descendants().filter_map(move |node| { |
@@ -24,15 +25,19 @@ impl<'a> SyntaxText<'a> { | |||
24 | Some(&text[range]) | 25 | Some(&text[range]) |
25 | }) | 26 | }) |
26 | } | 27 | } |
28 | |||
27 | pub fn push_to(&self, buf: &mut String) { | 29 | pub fn push_to(&self, buf: &mut String) { |
28 | self.chunks().for_each(|it| buf.push_str(it)); | 30 | self.chunks().for_each(|it| buf.push_str(it)); |
29 | } | 31 | } |
32 | |||
30 | pub fn to_string(&self) -> String { | 33 | pub fn to_string(&self) -> String { |
31 | self.chunks().collect() | 34 | self.chunks().collect() |
32 | } | 35 | } |
36 | |||
33 | pub fn contains(&self, c: char) -> bool { | 37 | pub fn contains(&self, c: char) -> bool { |
34 | self.chunks().any(|it| it.contains(c)) | 38 | self.chunks().any(|it| it.contains(c)) |
35 | } | 39 | } |
40 | |||
36 | pub fn find(&self, c: char) -> Option<TextUnit> { | 41 | pub fn find(&self, c: char) -> Option<TextUnit> { |
37 | let mut acc: TextUnit = 0.into(); | 42 | let mut acc: TextUnit = 0.into(); |
38 | for chunk in self.chunks() { | 43 | for chunk in self.chunks() { |
@@ -44,9 +49,11 @@ impl<'a> SyntaxText<'a> { | |||
44 | } | 49 | } |
45 | None | 50 | None |
46 | } | 51 | } |
52 | |||
47 | pub fn len(&self) -> TextUnit { | 53 | pub fn len(&self) -> TextUnit { |
48 | self.range.len() | 54 | self.range.len() |
49 | } | 55 | } |
56 | |||
50 | pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> { | 57 | pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> { |
51 | let range = range.restrict(self.range).unwrap_or_else(|| { | 58 | let range = range.restrict(self.range).unwrap_or_else(|| { |
52 | panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) | 59 | panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) |
@@ -56,8 +63,10 @@ impl<'a> SyntaxText<'a> { | |||
56 | range, | 63 | range, |
57 | } | 64 | } |
58 | } | 65 | } |
59 | pub fn char_at(&self, offset: TextUnit) -> Option<char> { | 66 | |
67 | pub fn char_at(&self, offset: impl Into<TextUnit>) -> Option<char> { | ||
60 | let mut start: TextUnit = 0.into(); | 68 | let mut start: TextUnit = 0.into(); |
69 | let offset = offset.into(); | ||
61 | for chunk in self.chunks() { | 70 | for chunk in self.chunks() { |
62 | let end = start + TextUnit::of_str(chunk); | 71 | let end = start + TextUnit::of_str(chunk); |
63 | if start <= offset && offset < end { | 72 | if start <= offset && offset < end { |