aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast.rs36
-rw-r--r--crates/ra_syntax/src/ast/generated.rs47
-rw-r--r--crates/ra_syntax/src/grammar.ron15
-rw-r--r--crates/ra_syntax/src/lib.rs2
-rw-r--r--crates/ra_syntax/src/validation/byte.rs4
-rw-r--r--crates/ra_syntax/src/validation/char.rs13
-rw-r--r--crates/ra_syntax/src/yellow/syntax_text.rs6
7 files changed, 113 insertions, 10 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 8fb6b6408..e968c9728 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -30,6 +30,12 @@ pub trait NameOwner<'a>: AstNode<'a> {
30 } 30 }
31} 31}
32 32
33pub trait VisibilityOwner<'a>: AstNode<'a> {
34 fn visibility(self) -> Option<Visibility<'a>> {
35 child_opt(self)
36 }
37}
38
33pub trait LoopBodyOwner<'a>: AstNode<'a> { 39pub trait LoopBodyOwner<'a>: AstNode<'a> {
34 fn loop_body(self) -> Option<Block<'a>> { 40 fn loop_body(self) -> Option<Block<'a>> {
35 child_opt(self) 41 child_opt(self)
@@ -48,10 +54,40 @@ pub trait FnDefOwner<'a>: AstNode<'a> {
48 } 54 }
49} 55}
50 56
57// ModuleItem
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum ItemOrMacro<'a> {
60 Item(ModuleItem<'a>),
61 Macro(MacroCall<'a>),
62}
63
64impl<'a> AstNode<'a> for ItemOrMacro<'a> {
65 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
66 let res = if let Some(item) = ModuleItem::cast(syntax) {
67 ItemOrMacro::Item(item)
68 } else if let Some(macro_call) = MacroCall::cast(syntax) {
69 ItemOrMacro::Macro(macro_call)
70 } else {
71 return None;
72 };
73 Some(res)
74 }
75 fn syntax(self) -> SyntaxNodeRef<'a> {
76 match self {
77 ItemOrMacro::Item(it) => it.syntax(),
78 ItemOrMacro::Macro(it) => it.syntax(),
79 }
80 }
81}
82
51pub trait ModuleItemOwner<'a>: AstNode<'a> { 83pub trait ModuleItemOwner<'a>: AstNode<'a> {
52 fn items(self) -> AstChildren<'a, ModuleItem<'a>> { 84 fn items(self) -> AstChildren<'a, ModuleItem<'a>> {
53 children(self) 85 children(self)
54 } 86 }
87
88 fn items_with_macros(self) -> AstChildren<'a, ItemOrMacro<'a>> {
89 children(self)
90 }
55} 91}
56 92
57pub trait TypeParamsOwner<'a>: AstNode<'a> { 93pub trait TypeParamsOwner<'a>: AstNode<'a> {
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index c5ac90a62..c619fc130 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -695,6 +695,7 @@ impl<R: TreeRoot<RaTypes>> ConstDefNode<R> {
695} 695}
696 696
697 697
698impl<'a> ast::VisibilityOwner<'a> for ConstDef<'a> {}
698impl<'a> ast::NameOwner<'a> for ConstDef<'a> {} 699impl<'a> ast::NameOwner<'a> for ConstDef<'a> {}
699impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {} 700impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {}
700impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {} 701impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {}
@@ -810,6 +811,7 @@ impl<R: TreeRoot<RaTypes>> EnumDefNode<R> {
810} 811}
811 812
812 813
814impl<'a> ast::VisibilityOwner<'a> for EnumDef<'a> {}
813impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} 815impl<'a> ast::NameOwner<'a> for EnumDef<'a> {}
814impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} 816impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {}
815impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} 817impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {}
@@ -1213,6 +1215,7 @@ impl<R: TreeRoot<RaTypes>> FnDefNode<R> {
1213} 1215}
1214 1216
1215 1217
1218impl<'a> ast::VisibilityOwner<'a> for FnDef<'a> {}
1216impl<'a> ast::NameOwner<'a> for FnDef<'a> {} 1219impl<'a> ast::NameOwner<'a> for FnDef<'a> {}
1217impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {} 1220impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {}
1218impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {} 1221impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {}
@@ -2136,6 +2139,7 @@ impl<R: TreeRoot<RaTypes>> ModuleNode<R> {
2136} 2139}
2137 2140
2138 2141
2142impl<'a> ast::VisibilityOwner<'a> for Module<'a> {}
2139impl<'a> ast::NameOwner<'a> for Module<'a> {} 2143impl<'a> ast::NameOwner<'a> for Module<'a> {}
2140impl<'a> ast::AttrsOwner<'a> for Module<'a> {} 2144impl<'a> ast::AttrsOwner<'a> for Module<'a> {}
2141impl<'a> ast::DocCommentsOwner<'a> for Module<'a> {} 2145impl<'a> ast::DocCommentsOwner<'a> for Module<'a> {}
@@ -2351,6 +2355,7 @@ impl<R: TreeRoot<RaTypes>> NamedFieldDefNode<R> {
2351} 2355}
2352 2356
2353 2357
2358impl<'a> ast::VisibilityOwner<'a> for NamedFieldDef<'a> {}
2354impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} 2359impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {}
2355impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} 2360impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {}
2356impl<'a> NamedFieldDef<'a> { 2361impl<'a> NamedFieldDef<'a> {
@@ -3082,6 +3087,7 @@ impl<R: TreeRoot<RaTypes>> PosFieldNode<R> {
3082} 3087}
3083 3088
3084 3089
3090impl<'a> ast::VisibilityOwner<'a> for PosField<'a> {}
3085impl<'a> ast::AttrsOwner<'a> for PosField<'a> {} 3091impl<'a> ast::AttrsOwner<'a> for PosField<'a> {}
3086impl<'a> PosField<'a> { 3092impl<'a> PosField<'a> {
3087 pub fn type_ref(self) -> Option<TypeRef<'a>> { 3093 pub fn type_ref(self) -> Option<TypeRef<'a>> {
@@ -3639,6 +3645,7 @@ impl<R: TreeRoot<RaTypes>> StaticDefNode<R> {
3639} 3645}
3640 3646
3641 3647
3648impl<'a> ast::VisibilityOwner<'a> for StaticDef<'a> {}
3642impl<'a> ast::NameOwner<'a> for StaticDef<'a> {} 3649impl<'a> ast::NameOwner<'a> for StaticDef<'a> {}
3643impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {} 3650impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {}
3644impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {} 3651impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {}
@@ -3742,6 +3749,7 @@ impl<R: TreeRoot<RaTypes>> StructDefNode<R> {
3742} 3749}
3743 3750
3744 3751
3752impl<'a> ast::VisibilityOwner<'a> for StructDef<'a> {}
3745impl<'a> ast::NameOwner<'a> for StructDef<'a> {} 3753impl<'a> ast::NameOwner<'a> for StructDef<'a> {}
3746impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} 3754impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {}
3747impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} 3755impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {}
@@ -3902,6 +3910,7 @@ impl<R: TreeRoot<RaTypes>> TraitDefNode<R> {
3902} 3910}
3903 3911
3904 3912
3913impl<'a> ast::VisibilityOwner<'a> for TraitDef<'a> {}
3905impl<'a> ast::NameOwner<'a> for TraitDef<'a> {} 3914impl<'a> ast::NameOwner<'a> for TraitDef<'a> {}
3906impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {} 3915impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {}
3907impl<'a> ast::DocCommentsOwner<'a> for TraitDef<'a> {} 3916impl<'a> ast::DocCommentsOwner<'a> for TraitDef<'a> {}
@@ -4135,6 +4144,7 @@ impl<R: TreeRoot<RaTypes>> TypeDefNode<R> {
4135} 4144}
4136 4145
4137 4146
4147impl<'a> ast::VisibilityOwner<'a> for TypeDef<'a> {}
4138impl<'a> ast::NameOwner<'a> for TypeDef<'a> {} 4148impl<'a> ast::NameOwner<'a> for TypeDef<'a> {}
4139impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {} 4149impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {}
4140impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {} 4150impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {}
@@ -4409,6 +4419,43 @@ impl<'a> UseTreeList<'a> {
4409 } 4419 }
4410} 4420}
4411 4421
4422// Visibility
4423#[derive(Debug, Clone, Copy,)]
4424pub struct VisibilityNode<R: TreeRoot<RaTypes> = OwnedRoot> {
4425 pub(crate) syntax: SyntaxNode<R>,
4426}
4427pub type Visibility<'a> = VisibilityNode<RefRoot<'a>>;
4428
4429impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<VisibilityNode<R1>> for VisibilityNode<R2> {
4430 fn eq(&self, other: &VisibilityNode<R1>) -> bool { self.syntax == other.syntax }
4431}
4432impl<R: TreeRoot<RaTypes>> Eq for VisibilityNode<R> {}
4433impl<R: TreeRoot<RaTypes>> Hash for VisibilityNode<R> {
4434 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
4435}
4436
4437impl<'a> AstNode<'a> for Visibility<'a> {
4438 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
4439 match syntax.kind() {
4440 VISIBILITY => Some(Visibility { syntax }),
4441 _ => None,
4442 }
4443 }
4444 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
4445}
4446
4447impl<R: TreeRoot<RaTypes>> VisibilityNode<R> {
4448 pub fn borrowed(&self) -> Visibility {
4449 VisibilityNode { syntax: self.syntax.borrowed() }
4450 }
4451 pub fn owned(&self) -> VisibilityNode {
4452 VisibilityNode { syntax: self.syntax.owned() }
4453 }
4454}
4455
4456
4457impl<'a> Visibility<'a> {}
4458
4412// WhereClause 4459// WhereClause
4413#[derive(Debug, Clone, Copy,)] 4460#[derive(Debug, Clone, Copy,)]
4414pub struct WhereClauseNode<R: TreeRoot<RaTypes> = OwnedRoot> { 4461pub struct WhereClauseNode<R: TreeRoot<RaTypes> = OwnedRoot> {
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index aab4839a9..2abb9da61 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -247,6 +247,7 @@ Grammar(
247 ), 247 ),
248 "FnDef": ( 248 "FnDef": (
249 traits: [ 249 traits: [
250 "VisibilityOwner",
250 "NameOwner", 251 "NameOwner",
251 "TypeParamsOwner", 252 "TypeParamsOwner",
252 "AttrsOwner", 253 "AttrsOwner",
@@ -257,6 +258,7 @@ Grammar(
257 "RetType": (options: ["TypeRef"]), 258 "RetType": (options: ["TypeRef"]),
258 "StructDef": ( 259 "StructDef": (
259 traits: [ 260 traits: [
261 "VisibilityOwner",
260 "NameOwner", 262 "NameOwner",
261 "TypeParamsOwner", 263 "TypeParamsOwner",
262 "AttrsOwner", 264 "AttrsOwner",
@@ -264,10 +266,11 @@ Grammar(
264 ] 266 ]
265 ), 267 ),
266 "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]), 268 "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]),
267 "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"], options: ["TypeRef"] ), 269 "NamedFieldDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner"], options: ["TypeRef"] ),
268 "PosFieldList": (collections: [["fields", "PosField"]]), 270 "PosFieldList": (collections: [["fields", "PosField"]]),
269 "PosField": ( traits: ["AttrsOwner"], options: ["TypeRef"]), 271 "PosField": ( traits: ["VisibilityOwner", "AttrsOwner"], options: ["TypeRef"]),
270 "EnumDef": ( traits: [ 272 "EnumDef": ( traits: [
273 "VisibilityOwner",
271 "NameOwner", 274 "NameOwner",
272 "TypeParamsOwner", 275 "TypeParamsOwner",
273 "AttrsOwner", 276 "AttrsOwner",
@@ -275,27 +278,30 @@ Grammar(
275 ], options: [["variant_list", "EnumVariantList"]] ), 278 ], options: [["variant_list", "EnumVariantList"]] ),
276 "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ), 279 "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ),
277 "EnumVariant": ( traits: ["NameOwner"], options: ["Expr"] ), 280 "EnumVariant": ( traits: ["NameOwner"], options: ["Expr"] ),
278 "TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ), 281 "TraitDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner"] ),
279 "Module": ( 282 "Module": (
280 traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ], 283 traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner" ],
281 options: [ "ItemList" ] 284 options: [ "ItemList" ]
282 ), 285 ),
283 "ItemList": ( 286 "ItemList": (
284 traits: [ "FnDefOwner", "ModuleItemOwner" ], 287 traits: [ "FnDefOwner", "ModuleItemOwner" ],
285 ), 288 ),
286 "ConstDef": ( traits: [ 289 "ConstDef": ( traits: [
290 "VisibilityOwner",
287 "NameOwner", 291 "NameOwner",
288 "TypeParamsOwner", 292 "TypeParamsOwner",
289 "AttrsOwner", 293 "AttrsOwner",
290 "DocCommentsOwner" 294 "DocCommentsOwner"
291 ] ), 295 ] ),
292 "StaticDef": ( traits: [ 296 "StaticDef": ( traits: [
297 "VisibilityOwner",
293 "NameOwner", 298 "NameOwner",
294 "TypeParamsOwner", 299 "TypeParamsOwner",
295 "AttrsOwner", 300 "AttrsOwner",
296 "DocCommentsOwner" 301 "DocCommentsOwner"
297 ] ), 302 ] ),
298 "TypeDef": ( traits: [ 303 "TypeDef": ( traits: [
304 "VisibilityOwner",
299 "NameOwner", 305 "NameOwner",
300 "TypeParamsOwner", 306 "TypeParamsOwner",
301 "AttrsOwner", 307 "AttrsOwner",
@@ -482,6 +488,7 @@ Grammar(
482 ], 488 ],
483 ), 489 ),
484 490
491 "Visibility": (),
485 "Name": (), 492 "Name": (),
486 "NameRef": (), 493 "NameRef": (),
487 "MacroCall": ( options: [ "TokenTree", "Path" ] ), 494 "MacroCall": ( options: [ "TokenTree", "Path" ] ),
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 34a3aabef..6753c513f 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -51,7 +51,7 @@ use ra_text_edit::AtomTextEdit;
51use crate::yellow::GreenNode; 51use crate::yellow::GreenNode;
52 52
53/// `SourceFileNode` represents a parse tree for a single Rust file. 53/// `SourceFileNode` represents a parse tree for a single Rust file.
54pub use crate::ast::SourceFileNode; 54pub use crate::ast::{SourceFile, SourceFileNode};
55 55
56impl SourceFileNode { 56impl SourceFileNode {
57 fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SourceFileNode { 57 fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SourceFileNode {
diff --git a/crates/ra_syntax/src/validation/byte.rs b/crates/ra_syntax/src/validation/byte.rs
index d0897eeed..714224b09 100644
--- a/crates/ra_syntax/src/validation/byte.rs
+++ b/crates/ra_syntax/src/validation/byte.rs
@@ -88,7 +88,9 @@ fn validate_byte_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxErr
88 88
89fn validate_byte_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) { 89fn validate_byte_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) {
90 // A ByteCodeEscape has 4 chars, example: `\xDD` 90 // A ByteCodeEscape has 4 chars, example: `\xDD`
91 if text.len() < 4 { 91 if !text.is_ascii() {
92 errors.push(SyntaxError::new(MalformedByteCodeEscape, range));
93 } else if text.chars().count() < 4 {
92 errors.push(SyntaxError::new(TooShortByteCodeEscape, range)); 94 errors.push(SyntaxError::new(TooShortByteCodeEscape, range));
93 } else { 95 } else {
94 assert!( 96 assert!(
diff --git a/crates/ra_syntax/src/validation/char.rs b/crates/ra_syntax/src/validation/char.rs
index 10d3d1dec..1d6fe8837 100644
--- a/crates/ra_syntax/src/validation/char.rs
+++ b/crates/ra_syntax/src/validation/char.rs
@@ -89,12 +89,17 @@ pub(super) fn is_ascii_escape(code: char) -> bool {
89 89
90fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) { 90fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) {
91 // An AsciiCodeEscape has 4 chars, example: `\xDD` 91 // An AsciiCodeEscape has 4 chars, example: `\xDD`
92 if text.len() < 4 { 92 if !text.is_ascii() {
93 // TODO: Give a more precise error message (say what the invalid character was)
94 errors.push(SyntaxError::new(AsciiCodeEscapeOutOfRange, range));
95 } else if text.chars().count() < 4 {
93 errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range)); 96 errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range));
94 } else { 97 } else {
95 assert!( 98 assert_eq!(
96 text.chars().count() == 4, 99 text.chars().count(),
97 "AsciiCodeEscape cannot be longer than 4 chars" 100 4,
101 "AsciiCodeEscape cannot be longer than 4 chars, but text '{}' is",
102 text,
98 ); 103 );
99 104
100 match u8::from_str_radix(&text[2..], 16) { 105 match u8::from_str_radix(&text[2..], 16) {
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs
index 46bde9a08..783dca214 100644
--- a/crates/ra_syntax/src/yellow/syntax_text.rs
+++ b/crates/ra_syntax/src/yellow/syntax_text.rs
@@ -119,3 +119,9 @@ impl SyntaxTextSlice for ops::Range<TextUnit> {
119 TextRange::from_to(self.start, self.end).restrict(range) 119 TextRange::from_to(self.start, self.end).restrict(range)
120 } 120 }
121} 121}
122
123impl From<SyntaxText<'_>> for String {
124 fn from(text: SyntaxText) -> String {
125 text.to_string()
126 }
127}