aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax/src')
-rw-r--r--crates/syntax/src/algo.rs14
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs80
-rw-r--r--crates/syntax/src/ast/make.rs10
-rw-r--r--crates/syntax/src/ast/node_ext.rs57
-rw-r--r--crates/syntax/src/display.rs2
-rw-r--r--crates/syntax/src/parsing/lexer.rs8
-rw-r--r--crates/syntax/src/parsing/reparsing.rs61
-rw-r--r--crates/syntax/src/validation.rs8
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())`.
25pub fn ancestors_at_offset( 25pub fn ancestors_at_offset(
@@ -45,7 +45,7 @@ pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextSize) ->
45} 45}
46 46
47pub fn find_node_at_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { 47pub 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
77pub fn find_covering_element(root: &SyntaxNode, range: TextRange) -> SyntaxElement {
78 root.covering_element(range)
79}
80
81pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNode> { 77pub 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}
12impl Name { 12impl 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)]
16pub struct NameRef { 17pub struct NameRef {
@@ -18,6 +19,9 @@ pub struct NameRef {
18} 19}
19impl NameRef { 20impl 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)]
23pub struct Lifetime { 27pub struct Lifetime {
@@ -42,9 +46,6 @@ pub struct PathSegment {
42 pub(crate) syntax: SyntaxNode, 46 pub(crate) syntax: SyntaxNode,
43} 47}
44impl PathSegment { 48impl 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 {
406impl Visibility { 406impl 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}
494impl ast::AttrsOwner for SelfParam {} 491impl ast::AttrsOwner for SelfParam {}
492impl ast::NameOwner for SelfParam {}
495impl SelfParam { 493impl 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)]
931pub struct YieldExpr {
932 pub(crate) syntax: SyntaxNode,
933}
934impl ast::AttrsOwner for YieldExpr {}
935impl 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)]
934pub struct Label { 940pub 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)]
1075pub struct MacroType {
1076 pub(crate) syntax: SyntaxNode,
1077}
1078impl MacroType {
1079 pub fn macro_call(&self) -> Option<MacroCall> { support::child(&self.syntax) }
1080}
1081#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1069pub struct NeverType { 1082pub 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)]
1339pub enum Item { 1354pub 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}
2404impl 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}
2389impl AstNode for Label { 2415impl 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}
2569impl 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}
2543impl AstNode for NeverType { 2580impl 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 {
2871impl From<InferType> for Type { 2908impl From<InferType> for Type {
2872 fn from(node: InferType) -> Type { Type::InferType(node) } 2909 fn from(node: InferType) -> Type { Type::InferType(node) }
2873} 2910}
2911impl From<MacroType> for Type {
2912 fn from(node: MacroType) -> Type { Type::MacroType(node) }
2913}
2874impl From<NeverType> for Type { 2914impl 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 {
3028impl From<WhileExpr> for Expr { 3070impl From<WhileExpr> for Expr {
3029 fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) } 3071 fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) }
3030} 3072}
3073impl From<YieldExpr> for Expr {
3074 fn from(node: YieldExpr) -> Expr { Expr::YieldExpr(node) }
3075}
3031impl AstNode for Expr { 3076impl 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}
4034impl 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}
3986impl std::fmt::Display for Label { 4039impl 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}
4109impl 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}
4056impl std::fmt::Display for NeverType { 4114impl 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
111pub fn use_(use_tree: ast::UseTree) -> ast::Use { 111pub 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
115pub fn record_expr_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordExprField { 119pub 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
189impl ast::UseTreeList { 210impl ast::UseTreeList {
@@ -434,16 +455,22 @@ pub enum VisibilityKind {
434 455
435impl ast::Visibility { 456impl 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.
26pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) { 26pub 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.
82pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> { 82pub 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.
98fn lex_first_token(text: &str) -> Option<(Token, Option<SyntaxError>)> { 98fn 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;
10use text_edit::Indel; 10use text_edit::Indel;
11 11
12use crate::{ 12use 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
126fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(SyntaxNode, Reparser)> { 125fn 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"
225fn foo() { 224fn 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"
234fn foo() { 233fn 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"
243struct Foo { 242struct 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 {
252fn foo { 251fn 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"
263mod foo { 262mod 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"
273trait Foo { 272trait 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"
282impl IntoIterator<Item=i32> for Foo { 281impl 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"
292pub enum A { 291pub 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"
301foo!{a, b<|><|> d} 300foo!{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"
308fn foo() { 307fn 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"
317extern { 316extern {
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
330fn foo() -> i32 { 1 } 329fn 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"
337fn foo() -> <|><|> {} 336fn 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"
344fn <|>foo<|>() -> i32 { 1 } 343fn $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"
351fn foo<|><|>foo() { } 350fn 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"
358fn foo /* <|><|> */ () {} 357fn 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"
365fn baz <|><|> () {} 364fn 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"
372fn baz <|><|> () {} 371fn 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
380mod { } 379mod { }
381", 380",
382 "c", 381 "c",
@@ -384,28 +383,28 @@ mod { }
384 ); 383 );
385 do_check( 384 do_check(
386 r#" 385 r#"
387fn -> &str { "Hello<|><|>" } 386fn -> &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#"
394fn -> &str { // "Hello<|><|>" 393fn -> &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##"
401fn -> &str { r#"Hello<|><|>"# 400fn -> &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)]
409enum Foo { 408enum 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 }