diff options
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/algo.rs | 14 | ||||
-rw-r--r-- | crates/syntax/src/ast/generated/nodes.rs | 80 | ||||
-rw-r--r-- | crates/syntax/src/ast/make.rs | 10 | ||||
-rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 57 | ||||
-rw-r--r-- | crates/syntax/src/display.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/parsing/lexer.rs | 8 | ||||
-rw-r--r-- | crates/syntax/src/parsing/reparsing.rs | 61 | ||||
-rw-r--r-- | crates/syntax/src/validation.rs | 8 |
8 files changed, 162 insertions, 78 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 5696c014f..827ae78f9 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | 19 | ||
20 | /// Returns ancestors of the node at the offset, sorted by length. This should | 20 | /// Returns ancestors of the node at the offset, sorted by length. This should |
21 | /// do the right thing at an edge, e.g. when searching for expressions at `{ | 21 | /// do the right thing at an edge, e.g. when searching for expressions at `{ |
22 | /// <|>foo }` we will get the name reference instead of the whole block, which | 22 | /// $0foo }` we will get the name reference instead of the whole block, which |
23 | /// we would get if we just did `find_token_at_offset(...).flat_map(|t| | 23 | /// we would get if we just did `find_token_at_offset(...).flat_map(|t| |
24 | /// t.parent().ancestors())`. | 24 | /// t.parent().ancestors())`. |
25 | pub fn ancestors_at_offset( | 25 | pub fn ancestors_at_offset( |
@@ -45,7 +45,7 @@ pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextSize) -> | |||
45 | } | 45 | } |
46 | 46 | ||
47 | pub fn find_node_at_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { | 47 | pub fn find_node_at_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { |
48 | find_covering_element(syntax, range).ancestors().find_map(N::cast) | 48 | syntax.covering_element(range).ancestors().find_map(N::cast) |
49 | } | 49 | } |
50 | 50 | ||
51 | /// Skip to next non `trivia` token | 51 | /// Skip to next non `trivia` token |
@@ -74,10 +74,6 @@ pub fn non_trivia_sibling(element: SyntaxElement, direction: Direction) -> Optio | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | pub fn find_covering_element(root: &SyntaxNode, range: TextRange) -> SyntaxElement { | ||
78 | root.covering_element(range) | ||
79 | } | ||
80 | |||
81 | pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNode> { | 77 | pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNode> { |
82 | if u == v { | 78 | if u == v { |
83 | return Some(u.clone()); | 79 | return Some(u.clone()); |
@@ -88,8 +84,8 @@ pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNod | |||
88 | let keep = u_depth.min(v_depth); | 84 | let keep = u_depth.min(v_depth); |
89 | 85 | ||
90 | let u_candidates = u.ancestors().skip(u_depth - keep); | 86 | let u_candidates = u.ancestors().skip(u_depth - keep); |
91 | let v_canidates = v.ancestors().skip(v_depth - keep); | 87 | let v_candidates = v.ancestors().skip(v_depth - keep); |
92 | let (res, _) = u_candidates.zip(v_canidates).find(|(x, y)| x == y)?; | 88 | let (res, _) = u_candidates.zip(v_candidates).find(|(x, y)| x == y)?; |
93 | Some(res) | 89 | Some(res) |
94 | } | 90 | } |
95 | 91 | ||
@@ -883,7 +879,7 @@ use crate::AstNode; | |||
883 | 879 | ||
884 | replacements: | 880 | replacements: |
885 | 881 | ||
886 | Line 2: Node(NAME_REF@5..14) -> crate | 882 | Line 2: Token(IDENT@5..14 "text_edit") -> crate |
887 | Line 2: Token([email protected] "TextEdit") -> AstNode | 883 | Line 2: Token([email protected] "TextEdit") -> AstNode |
888 | Line 2: Token([email protected] "\n\n") -> "\n" | 884 | Line 2: Token([email protected] "\n\n") -> "\n" |
889 | 885 | ||
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 92ed2ee9d..5baa54a3f 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs | |||
@@ -11,6 +11,7 @@ pub struct Name { | |||
11 | } | 11 | } |
12 | impl Name { | 12 | impl Name { |
13 | pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } | 13 | pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } |
14 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
14 | } | 15 | } |
15 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 16 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
16 | pub struct NameRef { | 17 | pub struct NameRef { |
@@ -18,6 +19,9 @@ pub struct NameRef { | |||
18 | } | 19 | } |
19 | impl NameRef { | 20 | impl NameRef { |
20 | pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } | 21 | pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } |
22 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
23 | pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) } | ||
24 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } | ||
21 | } | 25 | } |
22 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 26 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
23 | pub struct Lifetime { | 27 | pub struct Lifetime { |
@@ -42,9 +46,6 @@ pub struct PathSegment { | |||
42 | pub(crate) syntax: SyntaxNode, | 46 | pub(crate) syntax: SyntaxNode, |
43 | } | 47 | } |
44 | impl PathSegment { | 48 | impl PathSegment { |
45 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } | ||
46 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
47 | pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) } | ||
48 | pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) } | 49 | pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) } |
49 | pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) } | 50 | pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) } |
50 | pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) } | 51 | pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) } |
@@ -238,7 +239,6 @@ impl ExternCrate { | |||
238 | pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) } | 239 | pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) } |
239 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } | 240 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } |
240 | pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) } | 241 | pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) } |
241 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
242 | pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) } | 242 | pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) } |
243 | pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) } | 243 | pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) } |
244 | } | 244 | } |
@@ -406,9 +406,6 @@ pub struct Visibility { | |||
406 | impl Visibility { | 406 | impl Visibility { |
407 | pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) } | 407 | pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) } |
408 | pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } | 408 | pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } |
409 | pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) } | ||
410 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
411 | pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) } | ||
412 | pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) } | 409 | pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) } |
413 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } | 410 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } |
414 | pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } | 411 | pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } |
@@ -492,11 +489,11 @@ pub struct SelfParam { | |||
492 | pub(crate) syntax: SyntaxNode, | 489 | pub(crate) syntax: SyntaxNode, |
493 | } | 490 | } |
494 | impl ast::AttrsOwner for SelfParam {} | 491 | impl ast::AttrsOwner for SelfParam {} |
492 | impl ast::NameOwner for SelfParam {} | ||
495 | impl SelfParam { | 493 | impl SelfParam { |
496 | pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } | 494 | pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } |
497 | pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) } | 495 | pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) } |
498 | pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } | 496 | pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } |
499 | pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } | ||
500 | pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) } | 497 | pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) } |
501 | pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } | 498 | pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } |
502 | } | 499 | } |
@@ -931,6 +928,15 @@ impl WhileExpr { | |||
931 | pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) } | 928 | pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) } |
932 | } | 929 | } |
933 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 930 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
931 | pub struct YieldExpr { | ||
932 | pub(crate) syntax: SyntaxNode, | ||
933 | } | ||
934 | impl ast::AttrsOwner for YieldExpr {} | ||
935 | impl YieldExpr { | ||
936 | pub fn yield_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![yield]) } | ||
937 | pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } | ||
938 | } | ||
939 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
934 | pub struct Label { | 940 | pub struct Label { |
935 | pub(crate) syntax: SyntaxNode, | 941 | pub(crate) syntax: SyntaxNode, |
936 | } | 942 | } |
@@ -1066,6 +1072,13 @@ impl InferType { | |||
1066 | pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) } | 1072 | pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) } |
1067 | } | 1073 | } |
1068 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1074 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1075 | pub struct MacroType { | ||
1076 | pub(crate) syntax: SyntaxNode, | ||
1077 | } | ||
1078 | impl MacroType { | ||
1079 | pub fn macro_call(&self) -> Option<MacroCall> { support::child(&self.syntax) } | ||
1080 | } | ||
1081 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1069 | pub struct NeverType { | 1082 | pub struct NeverType { |
1070 | pub(crate) syntax: SyntaxNode, | 1083 | pub(crate) syntax: SyntaxNode, |
1071 | } | 1084 | } |
@@ -1294,6 +1307,7 @@ pub enum Type { | |||
1294 | ForType(ForType), | 1307 | ForType(ForType), |
1295 | ImplTraitType(ImplTraitType), | 1308 | ImplTraitType(ImplTraitType), |
1296 | InferType(InferType), | 1309 | InferType(InferType), |
1310 | MacroType(MacroType), | ||
1297 | NeverType(NeverType), | 1311 | NeverType(NeverType), |
1298 | ParenType(ParenType), | 1312 | ParenType(ParenType), |
1299 | PathType(PathType), | 1313 | PathType(PathType), |
@@ -1334,6 +1348,7 @@ pub enum Expr { | |||
1334 | TryExpr(TryExpr), | 1348 | TryExpr(TryExpr), |
1335 | TupleExpr(TupleExpr), | 1349 | TupleExpr(TupleExpr), |
1336 | WhileExpr(WhileExpr), | 1350 | WhileExpr(WhileExpr), |
1351 | YieldExpr(YieldExpr), | ||
1337 | } | 1352 | } |
1338 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1353 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1339 | pub enum Item { | 1354 | pub enum Item { |
@@ -2386,6 +2401,17 @@ impl AstNode for WhileExpr { | |||
2386 | } | 2401 | } |
2387 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 2402 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
2388 | } | 2403 | } |
2404 | impl AstNode for YieldExpr { | ||
2405 | fn can_cast(kind: SyntaxKind) -> bool { kind == YIELD_EXPR } | ||
2406 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
2407 | if Self::can_cast(syntax.kind()) { | ||
2408 | Some(Self { syntax }) | ||
2409 | } else { | ||
2410 | None | ||
2411 | } | ||
2412 | } | ||
2413 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2414 | } | ||
2389 | impl AstNode for Label { | 2415 | impl AstNode for Label { |
2390 | fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL } | 2416 | fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL } |
2391 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 2417 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -2540,6 +2566,17 @@ impl AstNode for InferType { | |||
2540 | } | 2566 | } |
2541 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 2567 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
2542 | } | 2568 | } |
2569 | impl AstNode for MacroType { | ||
2570 | fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_TYPE } | ||
2571 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
2572 | if Self::can_cast(syntax.kind()) { | ||
2573 | Some(Self { syntax }) | ||
2574 | } else { | ||
2575 | None | ||
2576 | } | ||
2577 | } | ||
2578 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2579 | } | ||
2543 | impl AstNode for NeverType { | 2580 | impl AstNode for NeverType { |
2544 | fn can_cast(kind: SyntaxKind) -> bool { kind == NEVER_TYPE } | 2581 | fn can_cast(kind: SyntaxKind) -> bool { kind == NEVER_TYPE } |
2545 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 2582 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -2871,6 +2908,9 @@ impl From<ImplTraitType> for Type { | |||
2871 | impl From<InferType> for Type { | 2908 | impl From<InferType> for Type { |
2872 | fn from(node: InferType) -> Type { Type::InferType(node) } | 2909 | fn from(node: InferType) -> Type { Type::InferType(node) } |
2873 | } | 2910 | } |
2911 | impl From<MacroType> for Type { | ||
2912 | fn from(node: MacroType) -> Type { Type::MacroType(node) } | ||
2913 | } | ||
2874 | impl From<NeverType> for Type { | 2914 | impl From<NeverType> for Type { |
2875 | fn from(node: NeverType) -> Type { Type::NeverType(node) } | 2915 | fn from(node: NeverType) -> Type { Type::NeverType(node) } |
2876 | } | 2916 | } |
@@ -2896,8 +2936,8 @@ impl AstNode for Type { | |||
2896 | fn can_cast(kind: SyntaxKind) -> bool { | 2936 | fn can_cast(kind: SyntaxKind) -> bool { |
2897 | match kind { | 2937 | match kind { |
2898 | ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE | 2938 | ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE |
2899 | | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE | SLICE_TYPE | 2939 | | MACRO_TYPE | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE |
2900 | | TUPLE_TYPE => true, | 2940 | | SLICE_TYPE | TUPLE_TYPE => true, |
2901 | _ => false, | 2941 | _ => false, |
2902 | } | 2942 | } |
2903 | } | 2943 | } |
@@ -2909,6 +2949,7 @@ impl AstNode for Type { | |||
2909 | FOR_TYPE => Type::ForType(ForType { syntax }), | 2949 | FOR_TYPE => Type::ForType(ForType { syntax }), |
2910 | IMPL_TRAIT_TYPE => Type::ImplTraitType(ImplTraitType { syntax }), | 2950 | IMPL_TRAIT_TYPE => Type::ImplTraitType(ImplTraitType { syntax }), |
2911 | INFER_TYPE => Type::InferType(InferType { syntax }), | 2951 | INFER_TYPE => Type::InferType(InferType { syntax }), |
2952 | MACRO_TYPE => Type::MacroType(MacroType { syntax }), | ||
2912 | NEVER_TYPE => Type::NeverType(NeverType { syntax }), | 2953 | NEVER_TYPE => Type::NeverType(NeverType { syntax }), |
2913 | PAREN_TYPE => Type::ParenType(ParenType { syntax }), | 2954 | PAREN_TYPE => Type::ParenType(ParenType { syntax }), |
2914 | PATH_TYPE => Type::PathType(PathType { syntax }), | 2955 | PATH_TYPE => Type::PathType(PathType { syntax }), |
@@ -2928,6 +2969,7 @@ impl AstNode for Type { | |||
2928 | Type::ForType(it) => &it.syntax, | 2969 | Type::ForType(it) => &it.syntax, |
2929 | Type::ImplTraitType(it) => &it.syntax, | 2970 | Type::ImplTraitType(it) => &it.syntax, |
2930 | Type::InferType(it) => &it.syntax, | 2971 | Type::InferType(it) => &it.syntax, |
2972 | Type::MacroType(it) => &it.syntax, | ||
2931 | Type::NeverType(it) => &it.syntax, | 2973 | Type::NeverType(it) => &it.syntax, |
2932 | Type::ParenType(it) => &it.syntax, | 2974 | Type::ParenType(it) => &it.syntax, |
2933 | Type::PathType(it) => &it.syntax, | 2975 | Type::PathType(it) => &it.syntax, |
@@ -3028,6 +3070,9 @@ impl From<TupleExpr> for Expr { | |||
3028 | impl From<WhileExpr> for Expr { | 3070 | impl From<WhileExpr> for Expr { |
3029 | fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) } | 3071 | fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) } |
3030 | } | 3072 | } |
3073 | impl From<YieldExpr> for Expr { | ||
3074 | fn from(node: YieldExpr) -> Expr { Expr::YieldExpr(node) } | ||
3075 | } | ||
3031 | impl AstNode for Expr { | 3076 | impl AstNode for Expr { |
3032 | fn can_cast(kind: SyntaxKind) -> bool { | 3077 | fn can_cast(kind: SyntaxKind) -> bool { |
3033 | match kind { | 3078 | match kind { |
@@ -3035,7 +3080,8 @@ impl AstNode for Expr { | |||
3035 | | CAST_EXPR | CLOSURE_EXPR | CONTINUE_EXPR | EFFECT_EXPR | FIELD_EXPR | FOR_EXPR | 3080 | | CAST_EXPR | CLOSURE_EXPR | CONTINUE_EXPR | EFFECT_EXPR | FIELD_EXPR | FOR_EXPR |
3036 | | IF_EXPR | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_CALL | MATCH_EXPR | 3081 | | IF_EXPR | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_CALL | MATCH_EXPR |
3037 | | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR | 3082 | | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR |
3038 | | RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR => true, | 3083 | | RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR |
3084 | | YIELD_EXPR => true, | ||
3039 | _ => false, | 3085 | _ => false, |
3040 | } | 3086 | } |
3041 | } | 3087 | } |
@@ -3071,6 +3117,7 @@ impl AstNode for Expr { | |||
3071 | TRY_EXPR => Expr::TryExpr(TryExpr { syntax }), | 3117 | TRY_EXPR => Expr::TryExpr(TryExpr { syntax }), |
3072 | TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }), | 3118 | TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }), |
3073 | WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }), | 3119 | WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }), |
3120 | YIELD_EXPR => Expr::YieldExpr(YieldExpr { syntax }), | ||
3074 | _ => return None, | 3121 | _ => return None, |
3075 | }; | 3122 | }; |
3076 | Some(res) | 3123 | Some(res) |
@@ -3107,6 +3154,7 @@ impl AstNode for Expr { | |||
3107 | Expr::TryExpr(it) => &it.syntax, | 3154 | Expr::TryExpr(it) => &it.syntax, |
3108 | Expr::TupleExpr(it) => &it.syntax, | 3155 | Expr::TupleExpr(it) => &it.syntax, |
3109 | Expr::WhileExpr(it) => &it.syntax, | 3156 | Expr::WhileExpr(it) => &it.syntax, |
3157 | Expr::YieldExpr(it) => &it.syntax, | ||
3110 | } | 3158 | } |
3111 | } | 3159 | } |
3112 | } | 3160 | } |
@@ -3983,6 +4031,11 @@ impl std::fmt::Display for WhileExpr { | |||
3983 | std::fmt::Display::fmt(self.syntax(), f) | 4031 | std::fmt::Display::fmt(self.syntax(), f) |
3984 | } | 4032 | } |
3985 | } | 4033 | } |
4034 | impl std::fmt::Display for YieldExpr { | ||
4035 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
4036 | std::fmt::Display::fmt(self.syntax(), f) | ||
4037 | } | ||
4038 | } | ||
3986 | impl std::fmt::Display for Label { | 4039 | impl std::fmt::Display for Label { |
3987 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 4040 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
3988 | std::fmt::Display::fmt(self.syntax(), f) | 4041 | std::fmt::Display::fmt(self.syntax(), f) |
@@ -4053,6 +4106,11 @@ impl std::fmt::Display for InferType { | |||
4053 | std::fmt::Display::fmt(self.syntax(), f) | 4106 | std::fmt::Display::fmt(self.syntax(), f) |
4054 | } | 4107 | } |
4055 | } | 4108 | } |
4109 | impl std::fmt::Display for MacroType { | ||
4110 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
4111 | std::fmt::Display::fmt(self.syntax(), f) | ||
4112 | } | ||
4113 | } | ||
4056 | impl std::fmt::Display for NeverType { | 4114 | impl std::fmt::Display for NeverType { |
4057 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 4115 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
4058 | std::fmt::Display::fmt(self.syntax(), f) | 4116 | std::fmt::Display::fmt(self.syntax(), f) |
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index cafa4c198..9ffc3ae11 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -108,8 +108,12 @@ pub fn use_tree_list(use_trees: impl IntoIterator<Item = ast::UseTree>) -> ast:: | |||
108 | ast_from_text(&format!("use {{{}}};", use_trees)) | 108 | ast_from_text(&format!("use {{{}}};", use_trees)) |
109 | } | 109 | } |
110 | 110 | ||
111 | pub fn use_(use_tree: ast::UseTree) -> ast::Use { | 111 | pub fn use_(visibility: Option<ast::Visibility>, use_tree: ast::UseTree) -> ast::Use { |
112 | ast_from_text(&format!("use {};", use_tree)) | 112 | let visibility = match visibility { |
113 | None => String::new(), | ||
114 | Some(it) => format!("{} ", it), | ||
115 | }; | ||
116 | ast_from_text(&format!("{}use {};", visibility, use_tree)) | ||
113 | } | 117 | } |
114 | 118 | ||
115 | pub fn record_expr_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordExprField { | 119 | pub fn record_expr_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordExprField { |
@@ -241,7 +245,7 @@ pub fn wildcard_pat() -> ast::WildcardPat { | |||
241 | } | 245 | } |
242 | } | 246 | } |
243 | 247 | ||
244 | /// Creates a tuple of patterns from an interator of patterns. | 248 | /// Creates a tuple of patterns from an iterator of patterns. |
245 | /// | 249 | /// |
246 | /// Invariant: `pats` must be length > 1 | 250 | /// Invariant: `pats` must be length > 1 |
247 | /// | 251 | /// |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 2aa472fb4..738c92a5b 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -133,7 +133,7 @@ impl ast::Attr { | |||
133 | first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind); | 133 | first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind); |
134 | 134 | ||
135 | match (first_token_kind, second_token_kind) { | 135 | match (first_token_kind, second_token_kind) { |
136 | (Some(SyntaxKind::POUND), Some(T![!])) => AttrKind::Inner, | 136 | (Some(T![#]), Some(T![!])) => AttrKind::Inner, |
137 | _ => AttrKind::Outer, | 137 | _ => AttrKind::Outer, |
138 | } | 138 | } |
139 | } | 139 | } |
@@ -156,14 +156,28 @@ impl ast::PathSegment { | |||
156 | .expect("segments are always nested in paths") | 156 | .expect("segments are always nested in paths") |
157 | } | 157 | } |
158 | 158 | ||
159 | pub fn crate_token(&self) -> Option<SyntaxToken> { | ||
160 | self.name_ref().and_then(|it| it.crate_token()) | ||
161 | } | ||
162 | |||
163 | pub fn self_token(&self) -> Option<SyntaxToken> { | ||
164 | self.name_ref().and_then(|it| it.self_token()) | ||
165 | } | ||
166 | |||
167 | pub fn super_token(&self) -> Option<SyntaxToken> { | ||
168 | self.name_ref().and_then(|it| it.super_token()) | ||
169 | } | ||
170 | |||
159 | pub fn kind(&self) -> Option<PathSegmentKind> { | 171 | pub fn kind(&self) -> Option<PathSegmentKind> { |
160 | let res = if let Some(name_ref) = self.name_ref() { | 172 | let res = if let Some(name_ref) = self.name_ref() { |
161 | PathSegmentKind::Name(name_ref) | 173 | match name_ref.syntax().first_token().map(|it| it.kind()) { |
174 | Some(T![self]) => PathSegmentKind::SelfKw, | ||
175 | Some(T![super]) => PathSegmentKind::SuperKw, | ||
176 | Some(T![crate]) => PathSegmentKind::CrateKw, | ||
177 | _ => PathSegmentKind::Name(name_ref), | ||
178 | } | ||
162 | } else { | 179 | } else { |
163 | match self.syntax().first_child_or_token()?.kind() { | 180 | match self.syntax().first_child_or_token()?.kind() { |
164 | T![self] => PathSegmentKind::SelfKw, | ||
165 | T![super] => PathSegmentKind::SuperKw, | ||
166 | T![crate] => PathSegmentKind::CrateKw, | ||
167 | T![<] => { | 181 | T![<] => { |
168 | // <T> or <T as Trait> | 182 | // <T> or <T as Trait> |
169 | // T is any TypeRef, Trait has to be a PathType | 183 | // T is any TypeRef, Trait has to be a PathType |
@@ -184,6 +198,13 @@ impl ast::Path { | |||
184 | pub fn parent_path(&self) -> Option<ast::Path> { | 198 | pub fn parent_path(&self) -> Option<ast::Path> { |
185 | self.syntax().parent().and_then(ast::Path::cast) | 199 | self.syntax().parent().and_then(ast::Path::cast) |
186 | } | 200 | } |
201 | |||
202 | pub fn as_single_segment(&self) -> Option<ast::PathSegment> { | ||
203 | match self.qualifier() { | ||
204 | Some(_) => None, | ||
205 | None => self.segment(), | ||
206 | } | ||
207 | } | ||
187 | } | 208 | } |
188 | 209 | ||
189 | impl ast::UseTreeList { | 210 | impl ast::UseTreeList { |
@@ -434,16 +455,22 @@ pub enum VisibilityKind { | |||
434 | 455 | ||
435 | impl ast::Visibility { | 456 | impl ast::Visibility { |
436 | pub fn kind(&self) -> VisibilityKind { | 457 | pub fn kind(&self) -> VisibilityKind { |
437 | if let Some(path) = support::children(self.syntax()).next() { | 458 | match self.path() { |
438 | VisibilityKind::In(path) | 459 | Some(path) => { |
439 | } else if self.crate_token().is_some() { | 460 | if let Some(segment) = |
440 | VisibilityKind::PubCrate | 461 | path.as_single_segment().filter(|it| it.coloncolon_token().is_none()) |
441 | } else if self.super_token().is_some() { | 462 | { |
442 | VisibilityKind::PubSuper | 463 | if segment.crate_token().is_some() { |
443 | } else if self.self_token().is_some() { | 464 | return VisibilityKind::PubCrate; |
444 | VisibilityKind::PubSelf | 465 | } else if segment.super_token().is_some() { |
445 | } else { | 466 | return VisibilityKind::PubSuper; |
446 | VisibilityKind::Pub | 467 | } else if segment.self_token().is_some() { |
468 | return VisibilityKind::PubSelf; | ||
469 | } | ||
470 | } | ||
471 | VisibilityKind::In(path) | ||
472 | } | ||
473 | None => VisibilityKind::Pub, | ||
447 | } | 474 | } |
448 | } | 475 | } |
449 | } | 476 | } |
diff --git a/crates/syntax/src/display.rs b/crates/syntax/src/display.rs index 391647fc6..cd956d950 100644 --- a/crates/syntax/src/display.rs +++ b/crates/syntax/src/display.rs | |||
@@ -80,7 +80,7 @@ pub fn macro_label(node: &ast::Macro) -> String { | |||
80 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); | 80 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); |
81 | match node { | 81 | match node { |
82 | ast::Macro::MacroRules(node) => { | 82 | ast::Macro::MacroRules(node) => { |
83 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; | 83 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export] " } else { "" }; |
84 | format!("{}macro_rules! {}", vis, name) | 84 | format!("{}macro_rules! {}", vis, name) |
85 | } | 85 | } |
86 | ast::Macro::MacroDef(node) => { | 86 | ast::Macro::MacroDef(node) => { |
diff --git a/crates/syntax/src/parsing/lexer.rs b/crates/syntax/src/parsing/lexer.rs index 0cbba73c5..7c8d0a4c4 100644 --- a/crates/syntax/src/parsing/lexer.rs +++ b/crates/syntax/src/parsing/lexer.rs | |||
@@ -24,7 +24,7 @@ pub struct Token { | |||
24 | /// Beware that it checks for shebang first and its length contributes to resulting | 24 | /// Beware that it checks for shebang first and its length contributes to resulting |
25 | /// tokens offsets. | 25 | /// tokens offsets. |
26 | pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) { | 26 | pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) { |
27 | // non-empty string is a precondtion of `rustc_lexer::strip_shebang()`. | 27 | // non-empty string is a precondition of `rustc_lexer::strip_shebang()`. |
28 | if text.is_empty() { | 28 | if text.is_empty() { |
29 | return Default::default(); | 29 | return Default::default(); |
30 | } | 30 | } |
@@ -76,7 +76,7 @@ pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxEr | |||
76 | } | 76 | } |
77 | 77 | ||
78 | /// The same as `lex_single_syntax_kind()` but returns only `SyntaxKind` and | 78 | /// The same as `lex_single_syntax_kind()` but returns only `SyntaxKind` and |
79 | /// returns `None` if any tokenization error occured. | 79 | /// returns `None` if any tokenization error occurred. |
80 | /// | 80 | /// |
81 | /// Beware that unescape errors are not checked at tokenization time. | 81 | /// Beware that unescape errors are not checked at tokenization time. |
82 | pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> { | 82 | pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> { |
@@ -96,7 +96,7 @@ pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> { | |||
96 | /// | 96 | /// |
97 | /// Beware that unescape errors are not checked at tokenization time. | 97 | /// Beware that unescape errors are not checked at tokenization time. |
98 | fn lex_first_token(text: &str) -> Option<(Token, Option<SyntaxError>)> { | 98 | fn lex_first_token(text: &str) -> Option<(Token, Option<SyntaxError>)> { |
99 | // non-empty string is a precondtion of `rustc_lexer::first_token()`. | 99 | // non-empty string is a precondition of `rustc_lexer::first_token()`. |
100 | if text.is_empty() { | 100 | if text.is_empty() { |
101 | return None; | 101 | return None; |
102 | } | 102 | } |
@@ -117,7 +117,7 @@ fn rustc_token_kind_to_syntax_kind( | |||
117 | token_text: &str, | 117 | token_text: &str, |
118 | ) -> (SyntaxKind, Option<&'static str>) { | 118 | ) -> (SyntaxKind, Option<&'static str>) { |
119 | // A note on an intended tradeoff: | 119 | // A note on an intended tradeoff: |
120 | // We drop some useful infromation here (see patterns with double dots `..`) | 120 | // We drop some useful information here (see patterns with double dots `..`) |
121 | // Storing that info in `SyntaxKind` is not possible due to its layout requirements of | 121 | // Storing that info in `SyntaxKind` is not possible due to its layout requirements of |
122 | // being `u16` that come from `rowan::SyntaxKind`. | 122 | // being `u16` that come from `rowan::SyntaxKind`. |
123 | 123 | ||
diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs index 190f5f67a..76f01084c 100644 --- a/crates/syntax/src/parsing/reparsing.rs +++ b/crates/syntax/src/parsing/reparsing.rs | |||
@@ -10,7 +10,6 @@ use parser::Reparser; | |||
10 | use text_edit::Indel; | 10 | use text_edit::Indel; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | algo, | ||
14 | parsing::{ | 13 | parsing::{ |
15 | lexer::{lex_single_syntax_kind, tokenize, Token}, | 14 | lexer::{lex_single_syntax_kind, tokenize, Token}, |
16 | text_token_source::TextTokenSource, | 15 | text_token_source::TextTokenSource, |
@@ -41,7 +40,7 @@ fn reparse_token<'node>( | |||
41 | root: &'node SyntaxNode, | 40 | root: &'node SyntaxNode, |
42 | edit: &Indel, | 41 | edit: &Indel, |
43 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { | 42 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { |
44 | let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); | 43 | let prev_token = root.covering_element(edit.delete).as_token()?.clone(); |
45 | let prev_token_kind = prev_token.kind(); | 44 | let prev_token_kind = prev_token.kind(); |
46 | match prev_token_kind { | 45 | match prev_token_kind { |
47 | WHITESPACE | COMMENT | IDENT | STRING => { | 46 | WHITESPACE | COMMENT | IDENT | STRING => { |
@@ -124,7 +123,7 @@ fn is_contextual_kw(text: &str) -> bool { | |||
124 | } | 123 | } |
125 | 124 | ||
126 | fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(SyntaxNode, Reparser)> { | 125 | fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(SyntaxNode, Reparser)> { |
127 | let node = algo::find_covering_element(node, range); | 126 | let node = node.covering_element(range); |
128 | 127 | ||
129 | let mut ancestors = match node { | 128 | let mut ancestors = match node { |
130 | NodeOrToken::Token(it) => it.parent().ancestors(), | 129 | NodeOrToken::Token(it) => it.parent().ancestors(), |
@@ -223,7 +222,7 @@ mod tests { | |||
223 | do_check( | 222 | do_check( |
224 | r" | 223 | r" |
225 | fn foo() { | 224 | fn foo() { |
226 | let x = foo + <|>bar<|> | 225 | let x = foo + $0bar$0 |
227 | } | 226 | } |
228 | ", | 227 | ", |
229 | "baz", | 228 | "baz", |
@@ -232,7 +231,7 @@ fn foo() { | |||
232 | do_check( | 231 | do_check( |
233 | r" | 232 | r" |
234 | fn foo() { | 233 | fn foo() { |
235 | let x = foo<|> + bar<|> | 234 | let x = foo$0 + bar$0 |
236 | } | 235 | } |
237 | ", | 236 | ", |
238 | "baz", | 237 | "baz", |
@@ -241,7 +240,7 @@ fn foo() { | |||
241 | do_check( | 240 | do_check( |
242 | r" | 241 | r" |
243 | struct Foo { | 242 | struct Foo { |
244 | f: foo<|><|> | 243 | f: foo$0$0 |
245 | } | 244 | } |
246 | ", | 245 | ", |
247 | ",\n g: (),", | 246 | ",\n g: (),", |
@@ -252,7 +251,7 @@ struct Foo { | |||
252 | fn foo { | 251 | fn foo { |
253 | let; | 252 | let; |
254 | 1 + 1; | 253 | 1 + 1; |
255 | <|>92<|>; | 254 | $092$0; |
256 | } | 255 | } |
257 | ", | 256 | ", |
258 | "62", | 257 | "62", |
@@ -261,7 +260,7 @@ fn foo { | |||
261 | do_check( | 260 | do_check( |
262 | r" | 261 | r" |
263 | mod foo { | 262 | mod foo { |
264 | fn <|><|> | 263 | fn $0$0 |
265 | } | 264 | } |
266 | ", | 265 | ", |
267 | "bar", | 266 | "bar", |
@@ -271,7 +270,7 @@ mod foo { | |||
271 | do_check( | 270 | do_check( |
272 | r" | 271 | r" |
273 | trait Foo { | 272 | trait Foo { |
274 | type <|>Foo<|>; | 273 | type $0Foo$0; |
275 | } | 274 | } |
276 | ", | 275 | ", |
277 | "Output", | 276 | "Output", |
@@ -280,17 +279,17 @@ trait Foo { | |||
280 | do_check( | 279 | do_check( |
281 | r" | 280 | r" |
282 | impl IntoIterator<Item=i32> for Foo { | 281 | impl IntoIterator<Item=i32> for Foo { |
283 | f<|><|> | 282 | f$0$0 |
284 | } | 283 | } |
285 | ", | 284 | ", |
286 | "n next(", | 285 | "n next(", |
287 | 9, | 286 | 9, |
288 | ); | 287 | ); |
289 | do_check(r"use a::b::{foo,<|>,bar<|>};", "baz", 10); | 288 | do_check(r"use a::b::{foo,$0,bar$0};", "baz", 10); |
290 | do_check( | 289 | do_check( |
291 | r" | 290 | r" |
292 | pub enum A { | 291 | pub enum A { |
293 | Foo<|><|> | 292 | Foo$0$0 |
294 | } | 293 | } |
295 | ", | 294 | ", |
296 | "\nBar;\n", | 295 | "\nBar;\n", |
@@ -298,7 +297,7 @@ pub enum A { | |||
298 | ); | 297 | ); |
299 | do_check( | 298 | do_check( |
300 | r" | 299 | r" |
301 | foo!{a, b<|><|> d} | 300 | foo!{a, b$0$0 d} |
302 | ", | 301 | ", |
303 | ", c[3]", | 302 | ", c[3]", |
304 | 8, | 303 | 8, |
@@ -306,7 +305,7 @@ foo!{a, b<|><|> d} | |||
306 | do_check( | 305 | do_check( |
307 | r" | 306 | r" |
308 | fn foo() { | 307 | fn foo() { |
309 | vec![<|><|>] | 308 | vec![$0$0] |
310 | } | 309 | } |
311 | ", | 310 | ", |
312 | "123", | 311 | "123", |
@@ -315,7 +314,7 @@ fn foo() { | |||
315 | do_check( | 314 | do_check( |
316 | r" | 315 | r" |
317 | extern { | 316 | extern { |
318 | fn<|>;<|> | 317 | fn$0;$0 |
319 | } | 318 | } |
320 | ", | 319 | ", |
321 | " exit(code: c_int)", | 320 | " exit(code: c_int)", |
@@ -326,7 +325,7 @@ extern { | |||
326 | #[test] | 325 | #[test] |
327 | fn reparse_token_tests() { | 326 | fn reparse_token_tests() { |
328 | do_check( | 327 | do_check( |
329 | r"<|><|> | 328 | r"$0$0 |
330 | fn foo() -> i32 { 1 } | 329 | fn foo() -> i32 { 1 } |
331 | ", | 330 | ", |
332 | "\n\n\n \n", | 331 | "\n\n\n \n", |
@@ -334,49 +333,49 @@ fn foo() -> i32 { 1 } | |||
334 | ); | 333 | ); |
335 | do_check( | 334 | do_check( |
336 | r" | 335 | r" |
337 | fn foo() -> <|><|> {} | 336 | fn foo() -> $0$0 {} |
338 | ", | 337 | ", |
339 | " \n", | 338 | " \n", |
340 | 2, | 339 | 2, |
341 | ); | 340 | ); |
342 | do_check( | 341 | do_check( |
343 | r" | 342 | r" |
344 | fn <|>foo<|>() -> i32 { 1 } | 343 | fn $0foo$0() -> i32 { 1 } |
345 | ", | 344 | ", |
346 | "bar", | 345 | "bar", |
347 | 3, | 346 | 3, |
348 | ); | 347 | ); |
349 | do_check( | 348 | do_check( |
350 | r" | 349 | r" |
351 | fn foo<|><|>foo() { } | 350 | fn foo$0$0foo() { } |
352 | ", | 351 | ", |
353 | "bar", | 352 | "bar", |
354 | 6, | 353 | 6, |
355 | ); | 354 | ); |
356 | do_check( | 355 | do_check( |
357 | r" | 356 | r" |
358 | fn foo /* <|><|> */ () {} | 357 | fn foo /* $0$0 */ () {} |
359 | ", | 358 | ", |
360 | "some comment", | 359 | "some comment", |
361 | 6, | 360 | 6, |
362 | ); | 361 | ); |
363 | do_check( | 362 | do_check( |
364 | r" | 363 | r" |
365 | fn baz <|><|> () {} | 364 | fn baz $0$0 () {} |
366 | ", | 365 | ", |
367 | " \t\t\n\n", | 366 | " \t\t\n\n", |
368 | 2, | 367 | 2, |
369 | ); | 368 | ); |
370 | do_check( | 369 | do_check( |
371 | r" | 370 | r" |
372 | fn baz <|><|> () {} | 371 | fn baz $0$0 () {} |
373 | ", | 372 | ", |
374 | " \t\t\n\n", | 373 | " \t\t\n\n", |
375 | 2, | 374 | 2, |
376 | ); | 375 | ); |
377 | do_check( | 376 | do_check( |
378 | r" | 377 | r" |
379 | /// foo <|><|>omment | 378 | /// foo $0$0omment |
380 | mod { } | 379 | mod { } |
381 | ", | 380 | ", |
382 | "c", | 381 | "c", |
@@ -384,28 +383,28 @@ mod { } | |||
384 | ); | 383 | ); |
385 | do_check( | 384 | do_check( |
386 | r#" | 385 | r#" |
387 | fn -> &str { "Hello<|><|>" } | 386 | fn -> &str { "Hello$0$0" } |
388 | "#, | 387 | "#, |
389 | ", world", | 388 | ", world", |
390 | 7, | 389 | 7, |
391 | ); | 390 | ); |
392 | do_check( | 391 | do_check( |
393 | r#" | 392 | r#" |
394 | fn -> &str { // "Hello<|><|>" | 393 | fn -> &str { // "Hello$0$0" |
395 | "#, | 394 | "#, |
396 | ", world", | 395 | ", world", |
397 | 10, | 396 | 10, |
398 | ); | 397 | ); |
399 | do_check( | 398 | do_check( |
400 | r##" | 399 | r##" |
401 | fn -> &str { r#"Hello<|><|>"# | 400 | fn -> &str { r#"Hello$0$0"# |
402 | "##, | 401 | "##, |
403 | ", world", | 402 | ", world", |
404 | 10, | 403 | 10, |
405 | ); | 404 | ); |
406 | do_check( | 405 | do_check( |
407 | r" | 406 | r" |
408 | #[derive(<|>Copy<|>)] | 407 | #[derive($0Copy$0)] |
409 | enum Foo { | 408 | enum Foo { |
410 | 409 | ||
411 | } | 410 | } |
@@ -417,12 +416,12 @@ enum Foo { | |||
417 | 416 | ||
418 | #[test] | 417 | #[test] |
419 | fn reparse_str_token_with_error_unchanged() { | 418 | fn reparse_str_token_with_error_unchanged() { |
420 | do_check(r#""<|>Unclosed<|> string literal"#, "Still unclosed", 24); | 419 | do_check(r#""$0Unclosed$0 string literal"#, "Still unclosed", 24); |
421 | } | 420 | } |
422 | 421 | ||
423 | #[test] | 422 | #[test] |
424 | fn reparse_str_token_with_error_fixed() { | 423 | fn reparse_str_token_with_error_fixed() { |
425 | do_check(r#""unterinated<|><|>"#, "\"", 12); | 424 | do_check(r#""unterinated$0$0"#, "\"", 12); |
426 | } | 425 | } |
427 | 426 | ||
428 | #[test] | 427 | #[test] |
@@ -430,7 +429,7 @@ enum Foo { | |||
430 | do_check( | 429 | do_check( |
431 | r#"fn main() { | 430 | r#"fn main() { |
432 | if {} | 431 | if {} |
433 | 32 + 4<|><|> | 432 | 32 + 4$0$0 |
434 | return | 433 | return |
435 | if {} | 434 | if {} |
436 | }"#, | 435 | }"#, |
@@ -444,7 +443,7 @@ enum Foo { | |||
444 | do_check( | 443 | do_check( |
445 | r#"fn main() { | 444 | r#"fn main() { |
446 | if {} | 445 | if {} |
447 | 32 + 4<|><|> | 446 | 32 + 4$0$0 |
448 | return | 447 | return |
449 | if {} | 448 | if {} |
450 | }"#, | 449 | }"#, |
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 2ddaeb176..7901580ee 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs | |||
@@ -173,7 +173,7 @@ pub(crate) fn validate_block_structure(root: &SyntaxNode) { | |||
173 | assert_eq!( | 173 | assert_eq!( |
174 | node.parent(), | 174 | node.parent(), |
175 | pair.parent(), | 175 | pair.parent(), |
176 | "\nunpaired curleys:\n{}\n{:#?}\n", | 176 | "\nunpaired curlys:\n{}\n{:#?}\n", |
177 | root.text(), | 177 | root.text(), |
178 | root, | 178 | root, |
179 | ); | 179 | ); |
@@ -256,7 +256,7 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro | |||
256 | )); | 256 | )); |
257 | } | 257 | } |
258 | } else if let Some(token) = segment.super_token() { | 258 | } else if let Some(token) = segment.super_token() { |
259 | if !all_supers(&path) { | 259 | if segment.coloncolon_token().is_some() || !all_supers(&path) { |
260 | errors.push(SyntaxError::new( | 260 | errors.push(SyntaxError::new( |
261 | "The `super` keyword may only be preceded by other `super`s", | 261 | "The `super` keyword may only be preceded by other `super`s", |
262 | token.text_range(), | 262 | token.text_range(), |
@@ -344,9 +344,9 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> { | |||
344 | 344 | ||
345 | if tbl.bounds().count() > 1 { | 345 | if tbl.bounds().count() > 1 { |
346 | let dyn_token = ty.dyn_token()?; | 346 | let dyn_token = ty.dyn_token()?; |
347 | let potential_parentheses = | 347 | let potential_parenthesis = |
348 | algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; | 348 | algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; |
349 | let kind = potential_parentheses.kind(); | 349 | let kind = potential_parenthesis.kind(); |
350 | if !matches!(kind, T!['('] | T![<] | T![=]) { | 350 | if !matches!(kind, T!['('] | T![<] | T![=]) { |
351 | return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); | 351 | return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); |
352 | } | 352 | } |