diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-27 10:08:34 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-27 10:08:34 +0000 |
commit | 1d6dcef5c584d0dffdf5386eec993e41daad0210 (patch) | |
tree | 1e67675b7031115b1811863d0f186ad1f98b1fce /crates/ra_syntax/src | |
parent | 700165cf17290561dea511565278b9869ed61625 (diff) | |
parent | bc745a139674f289386f3081458793f756cab5b9 (diff) |
Merge #332
332: Struct types r=matklad a=flodiebold
Infer types for struct fields, and add basic field completions. There's also some code for enums, but I focused on getting structs working.
There's still ways to go before this becomes useful: There's no autoderef (or even reference types) and no inference for `self`, for example.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 70 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 321 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 38 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar/expressions.rs | 16 |
4 files changed, 399 insertions, 46 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index f12479fb4..8fb6b6408 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -363,3 +363,73 @@ impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> { | |||
363 | } | 363 | } |
364 | } | 364 | } |
365 | } | 365 | } |
366 | |||
367 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
368 | pub enum StructFlavor<'a> { | ||
369 | Tuple(PosFieldList<'a>), | ||
370 | Named(NamedFieldDefList<'a>), | ||
371 | Unit, | ||
372 | } | ||
373 | |||
374 | impl<'a> StructFlavor<'a> { | ||
375 | fn from_node<N: AstNode<'a>>(node: N) -> StructFlavor<'a> { | ||
376 | if let Some(nfdl) = child_opt::<_, NamedFieldDefList>(node) { | ||
377 | StructFlavor::Named(nfdl) | ||
378 | } else if let Some(pfl) = child_opt::<_, PosFieldList>(node) { | ||
379 | StructFlavor::Tuple(pfl) | ||
380 | } else { | ||
381 | StructFlavor::Unit | ||
382 | } | ||
383 | } | ||
384 | } | ||
385 | |||
386 | impl<'a> StructDef<'a> { | ||
387 | pub fn flavor(self) -> StructFlavor<'a> { | ||
388 | StructFlavor::from_node(self) | ||
389 | } | ||
390 | } | ||
391 | |||
392 | impl<'a> EnumVariant<'a> { | ||
393 | pub fn flavor(self) -> StructFlavor<'a> { | ||
394 | StructFlavor::from_node(self) | ||
395 | } | ||
396 | } | ||
397 | |||
398 | impl<'a> PointerType<'a> { | ||
399 | pub fn is_mut(&self) -> bool { | ||
400 | self.syntax().children().any(|n| n.kind() == MUT_KW) | ||
401 | } | ||
402 | } | ||
403 | |||
404 | impl<'a> ReferenceType<'a> { | ||
405 | pub fn is_mut(&self) -> bool { | ||
406 | self.syntax().children().any(|n| n.kind() == MUT_KW) | ||
407 | } | ||
408 | } | ||
409 | |||
410 | impl<'a> RefExpr<'a> { | ||
411 | pub fn is_mut(&self) -> bool { | ||
412 | self.syntax().children().any(|n| n.kind() == MUT_KW) | ||
413 | } | ||
414 | } | ||
415 | |||
416 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
417 | pub enum PrefixOp { | ||
418 | /// The `*` operator for dereferencing | ||
419 | Deref, | ||
420 | /// The `!` operator for logical inversion | ||
421 | Not, | ||
422 | /// The `-` operator for negation | ||
423 | Neg, | ||
424 | } | ||
425 | |||
426 | impl<'a> PrefixExpr<'a> { | ||
427 | pub fn op(&self) -> Option<PrefixOp> { | ||
428 | match self.syntax().first_child()?.kind() { | ||
429 | STAR => Some(PrefixOp::Deref), | ||
430 | EXCL => Some(PrefixOp::Not), | ||
431 | MINUS => Some(PrefixOp::Neg), | ||
432 | _ => None, | ||
433 | } | ||
434 | } | ||
435 | } | ||
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index c73533861..c22e026cf 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -131,7 +131,15 @@ impl<R: TreeRoot<RaTypes>> ArrayTypeNode<R> { | |||
131 | } | 131 | } |
132 | 132 | ||
133 | 133 | ||
134 | impl<'a> ArrayType<'a> {} | 134 | impl<'a> ArrayType<'a> { |
135 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
136 | super::child_opt(self) | ||
137 | } | ||
138 | |||
139 | pub fn expr(self) -> Option<Expr<'a>> { | ||
140 | super::child_opt(self) | ||
141 | } | ||
142 | } | ||
135 | 143 | ||
136 | // Attr | 144 | // Attr |
137 | #[derive(Debug, Clone, Copy,)] | 145 | #[derive(Debug, Clone, Copy,)] |
@@ -806,7 +814,94 @@ impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} | |||
806 | impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} | 814 | impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} |
807 | impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} | 815 | impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} |
808 | impl<'a> ast::DocCommentsOwner<'a> for EnumDef<'a> {} | 816 | impl<'a> ast::DocCommentsOwner<'a> for EnumDef<'a> {} |
809 | impl<'a> EnumDef<'a> {} | 817 | impl<'a> EnumDef<'a> { |
818 | pub fn variant_list(self) -> Option<EnumVariantList<'a>> { | ||
819 | super::child_opt(self) | ||
820 | } | ||
821 | } | ||
822 | |||
823 | // EnumVariant | ||
824 | #[derive(Debug, Clone, Copy,)] | ||
825 | pub struct EnumVariantNode<R: TreeRoot<RaTypes> = OwnedRoot> { | ||
826 | pub(crate) syntax: SyntaxNode<R>, | ||
827 | } | ||
828 | pub type EnumVariant<'a> = EnumVariantNode<RefRoot<'a>>; | ||
829 | |||
830 | impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<EnumVariantNode<R1>> for EnumVariantNode<R2> { | ||
831 | fn eq(&self, other: &EnumVariantNode<R1>) -> bool { self.syntax == other.syntax } | ||
832 | } | ||
833 | impl<R: TreeRoot<RaTypes>> Eq for EnumVariantNode<R> {} | ||
834 | impl<R: TreeRoot<RaTypes>> Hash for EnumVariantNode<R> { | ||
835 | fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) } | ||
836 | } | ||
837 | |||
838 | impl<'a> AstNode<'a> for EnumVariant<'a> { | ||
839 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
840 | match syntax.kind() { | ||
841 | ENUM_VARIANT => Some(EnumVariant { syntax }), | ||
842 | _ => None, | ||
843 | } | ||
844 | } | ||
845 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
846 | } | ||
847 | |||
848 | impl<R: TreeRoot<RaTypes>> EnumVariantNode<R> { | ||
849 | pub fn borrowed(&self) -> EnumVariant { | ||
850 | EnumVariantNode { syntax: self.syntax.borrowed() } | ||
851 | } | ||
852 | pub fn owned(&self) -> EnumVariantNode { | ||
853 | EnumVariantNode { syntax: self.syntax.owned() } | ||
854 | } | ||
855 | } | ||
856 | |||
857 | |||
858 | impl<'a> ast::NameOwner<'a> for EnumVariant<'a> {} | ||
859 | impl<'a> EnumVariant<'a> { | ||
860 | pub fn expr(self) -> Option<Expr<'a>> { | ||
861 | super::child_opt(self) | ||
862 | } | ||
863 | } | ||
864 | |||
865 | // EnumVariantList | ||
866 | #[derive(Debug, Clone, Copy,)] | ||
867 | pub struct EnumVariantListNode<R: TreeRoot<RaTypes> = OwnedRoot> { | ||
868 | pub(crate) syntax: SyntaxNode<R>, | ||
869 | } | ||
870 | pub type EnumVariantList<'a> = EnumVariantListNode<RefRoot<'a>>; | ||
871 | |||
872 | impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<EnumVariantListNode<R1>> for EnumVariantListNode<R2> { | ||
873 | fn eq(&self, other: &EnumVariantListNode<R1>) -> bool { self.syntax == other.syntax } | ||
874 | } | ||
875 | impl<R: TreeRoot<RaTypes>> Eq for EnumVariantListNode<R> {} | ||
876 | impl<R: TreeRoot<RaTypes>> Hash for EnumVariantListNode<R> { | ||
877 | fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) } | ||
878 | } | ||
879 | |||
880 | impl<'a> AstNode<'a> for EnumVariantList<'a> { | ||
881 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
882 | match syntax.kind() { | ||
883 | ENUM_VARIANT_LIST => Some(EnumVariantList { syntax }), | ||
884 | _ => None, | ||
885 | } | ||
886 | } | ||
887 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
888 | } | ||
889 | |||
890 | impl<R: TreeRoot<RaTypes>> EnumVariantListNode<R> { | ||
891 | pub fn borrowed(&self) -> EnumVariantList { | ||
892 | EnumVariantListNode { syntax: self.syntax.borrowed() } | ||
893 | } | ||
894 | pub fn owned(&self) -> EnumVariantListNode { | ||
895 | EnumVariantListNode { syntax: self.syntax.owned() } | ||
896 | } | ||
897 | } | ||
898 | |||
899 | |||
900 | impl<'a> EnumVariantList<'a> { | ||
901 | pub fn variants(self) -> impl Iterator<Item = EnumVariant<'a>> + 'a { | ||
902 | super::children(self) | ||
903 | } | ||
904 | } | ||
810 | 905 | ||
811 | // Expr | 906 | // Expr |
812 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 907 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
@@ -1036,7 +1131,15 @@ impl<R: TreeRoot<RaTypes>> FieldExprNode<R> { | |||
1036 | } | 1131 | } |
1037 | 1132 | ||
1038 | 1133 | ||
1039 | impl<'a> FieldExpr<'a> {} | 1134 | impl<'a> FieldExpr<'a> { |
1135 | pub fn expr(self) -> Option<Expr<'a>> { | ||
1136 | super::child_opt(self) | ||
1137 | } | ||
1138 | |||
1139 | pub fn name_ref(self) -> Option<NameRef<'a>> { | ||
1140 | super::child_opt(self) | ||
1141 | } | ||
1142 | } | ||
1040 | 1143 | ||
1041 | // FieldPatList | 1144 | // FieldPatList |
1042 | #[derive(Debug, Clone, Copy,)] | 1145 | #[derive(Debug, Clone, Copy,)] |
@@ -1163,7 +1266,15 @@ impl<R: TreeRoot<RaTypes>> FnPointerTypeNode<R> { | |||
1163 | } | 1266 | } |
1164 | 1267 | ||
1165 | 1268 | ||
1166 | impl<'a> FnPointerType<'a> {} | 1269 | impl<'a> FnPointerType<'a> { |
1270 | pub fn param_list(self) -> Option<ParamList<'a>> { | ||
1271 | super::child_opt(self) | ||
1272 | } | ||
1273 | |||
1274 | pub fn ret_type(self) -> Option<RetType<'a>> { | ||
1275 | super::child_opt(self) | ||
1276 | } | ||
1277 | } | ||
1167 | 1278 | ||
1168 | // ForExpr | 1279 | // ForExpr |
1169 | #[derive(Debug, Clone, Copy,)] | 1280 | #[derive(Debug, Clone, Copy,)] |
@@ -1246,7 +1357,11 @@ impl<R: TreeRoot<RaTypes>> ForTypeNode<R> { | |||
1246 | } | 1357 | } |
1247 | 1358 | ||
1248 | 1359 | ||
1249 | impl<'a> ForType<'a> {} | 1360 | impl<'a> ForType<'a> { |
1361 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
1362 | super::child_opt(self) | ||
1363 | } | ||
1364 | } | ||
1250 | 1365 | ||
1251 | // IfExpr | 1366 | // IfExpr |
1252 | #[derive(Debug, Clone, Copy,)] | 1367 | #[derive(Debug, Clone, Copy,)] |
@@ -1935,6 +2050,10 @@ impl<'a> MethodCallExpr<'a> { | |||
1935 | pub fn expr(self) -> Option<Expr<'a>> { | 2050 | pub fn expr(self) -> Option<Expr<'a>> { |
1936 | super::child_opt(self) | 2051 | super::child_opt(self) |
1937 | } | 2052 | } |
2053 | |||
2054 | pub fn name_ref(self) -> Option<NameRef<'a>> { | ||
2055 | super::child_opt(self) | ||
2056 | } | ||
1938 | } | 2057 | } |
1939 | 2058 | ||
1940 | // Module | 2059 | // Module |
@@ -2142,7 +2261,15 @@ impl<R: TreeRoot<RaTypes>> NamedFieldNode<R> { | |||
2142 | } | 2261 | } |
2143 | 2262 | ||
2144 | 2263 | ||
2145 | impl<'a> NamedField<'a> {} | 2264 | impl<'a> NamedField<'a> { |
2265 | pub fn name_ref(self) -> Option<NameRef<'a>> { | ||
2266 | super::child_opt(self) | ||
2267 | } | ||
2268 | |||
2269 | pub fn expr(self) -> Option<Expr<'a>> { | ||
2270 | super::child_opt(self) | ||
2271 | } | ||
2272 | } | ||
2146 | 2273 | ||
2147 | // NamedFieldDef | 2274 | // NamedFieldDef |
2148 | #[derive(Debug, Clone, Copy,)] | 2275 | #[derive(Debug, Clone, Copy,)] |
@@ -2181,7 +2308,52 @@ impl<R: TreeRoot<RaTypes>> NamedFieldDefNode<R> { | |||
2181 | 2308 | ||
2182 | impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} | 2309 | impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} |
2183 | impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} | 2310 | impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} |
2184 | impl<'a> NamedFieldDef<'a> {} | 2311 | impl<'a> NamedFieldDef<'a> { |
2312 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
2313 | super::child_opt(self) | ||
2314 | } | ||
2315 | } | ||
2316 | |||
2317 | // NamedFieldDefList | ||
2318 | #[derive(Debug, Clone, Copy,)] | ||
2319 | pub struct NamedFieldDefListNode<R: TreeRoot<RaTypes> = OwnedRoot> { | ||
2320 | pub(crate) syntax: SyntaxNode<R>, | ||
2321 | } | ||
2322 | pub type NamedFieldDefList<'a> = NamedFieldDefListNode<RefRoot<'a>>; | ||
2323 | |||
2324 | impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<NamedFieldDefListNode<R1>> for NamedFieldDefListNode<R2> { | ||
2325 | fn eq(&self, other: &NamedFieldDefListNode<R1>) -> bool { self.syntax == other.syntax } | ||
2326 | } | ||
2327 | impl<R: TreeRoot<RaTypes>> Eq for NamedFieldDefListNode<R> {} | ||
2328 | impl<R: TreeRoot<RaTypes>> Hash for NamedFieldDefListNode<R> { | ||
2329 | fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) } | ||
2330 | } | ||
2331 | |||
2332 | impl<'a> AstNode<'a> for NamedFieldDefList<'a> { | ||
2333 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2334 | match syntax.kind() { | ||
2335 | NAMED_FIELD_DEF_LIST => Some(NamedFieldDefList { syntax }), | ||
2336 | _ => None, | ||
2337 | } | ||
2338 | } | ||
2339 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2340 | } | ||
2341 | |||
2342 | impl<R: TreeRoot<RaTypes>> NamedFieldDefListNode<R> { | ||
2343 | pub fn borrowed(&self) -> NamedFieldDefList { | ||
2344 | NamedFieldDefListNode { syntax: self.syntax.borrowed() } | ||
2345 | } | ||
2346 | pub fn owned(&self) -> NamedFieldDefListNode { | ||
2347 | NamedFieldDefListNode { syntax: self.syntax.owned() } | ||
2348 | } | ||
2349 | } | ||
2350 | |||
2351 | |||
2352 | impl<'a> NamedFieldDefList<'a> { | ||
2353 | pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a { | ||
2354 | super::children(self) | ||
2355 | } | ||
2356 | } | ||
2185 | 2357 | ||
2186 | // NamedFieldList | 2358 | // NamedFieldList |
2187 | #[derive(Debug, Clone, Copy,)] | 2359 | #[derive(Debug, Clone, Copy,)] |
@@ -2218,7 +2390,11 @@ impl<R: TreeRoot<RaTypes>> NamedFieldListNode<R> { | |||
2218 | } | 2390 | } |
2219 | 2391 | ||
2220 | 2392 | ||
2221 | impl<'a> NamedFieldList<'a> {} | 2393 | impl<'a> NamedFieldList<'a> { |
2394 | pub fn fields(self) -> impl Iterator<Item = NamedField<'a>> + 'a { | ||
2395 | super::children(self) | ||
2396 | } | ||
2397 | } | ||
2222 | 2398 | ||
2223 | // NeverType | 2399 | // NeverType |
2224 | #[derive(Debug, Clone, Copy,)] | 2400 | #[derive(Debug, Clone, Copy,)] |
@@ -2451,7 +2627,11 @@ impl<R: TreeRoot<RaTypes>> ParenTypeNode<R> { | |||
2451 | } | 2627 | } |
2452 | 2628 | ||
2453 | 2629 | ||
2454 | impl<'a> ParenType<'a> {} | 2630 | impl<'a> ParenType<'a> { |
2631 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
2632 | super::child_opt(self) | ||
2633 | } | ||
2634 | } | ||
2455 | 2635 | ||
2456 | // Pat | 2636 | // Pat |
2457 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 2637 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
@@ -2816,7 +2996,94 @@ impl<R: TreeRoot<RaTypes>> PointerTypeNode<R> { | |||
2816 | } | 2996 | } |
2817 | 2997 | ||
2818 | 2998 | ||
2819 | impl<'a> PointerType<'a> {} | 2999 | impl<'a> PointerType<'a> { |
3000 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
3001 | super::child_opt(self) | ||
3002 | } | ||
3003 | } | ||
3004 | |||
3005 | // PosField | ||
3006 | #[derive(Debug, Clone, Copy,)] | ||
3007 | pub struct PosFieldNode<R: TreeRoot<RaTypes> = OwnedRoot> { | ||
3008 | pub(crate) syntax: SyntaxNode<R>, | ||
3009 | } | ||
3010 | pub type PosField<'a> = PosFieldNode<RefRoot<'a>>; | ||
3011 | |||
3012 | impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<PosFieldNode<R1>> for PosFieldNode<R2> { | ||
3013 | fn eq(&self, other: &PosFieldNode<R1>) -> bool { self.syntax == other.syntax } | ||
3014 | } | ||
3015 | impl<R: TreeRoot<RaTypes>> Eq for PosFieldNode<R> {} | ||
3016 | impl<R: TreeRoot<RaTypes>> Hash for PosFieldNode<R> { | ||
3017 | fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) } | ||
3018 | } | ||
3019 | |||
3020 | impl<'a> AstNode<'a> for PosField<'a> { | ||
3021 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
3022 | match syntax.kind() { | ||
3023 | POS_FIELD => Some(PosField { syntax }), | ||
3024 | _ => None, | ||
3025 | } | ||
3026 | } | ||
3027 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
3028 | } | ||
3029 | |||
3030 | impl<R: TreeRoot<RaTypes>> PosFieldNode<R> { | ||
3031 | pub fn borrowed(&self) -> PosField { | ||
3032 | PosFieldNode { syntax: self.syntax.borrowed() } | ||
3033 | } | ||
3034 | pub fn owned(&self) -> PosFieldNode { | ||
3035 | PosFieldNode { syntax: self.syntax.owned() } | ||
3036 | } | ||
3037 | } | ||
3038 | |||
3039 | |||
3040 | impl<'a> ast::AttrsOwner<'a> for PosField<'a> {} | ||
3041 | impl<'a> PosField<'a> { | ||
3042 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
3043 | super::child_opt(self) | ||
3044 | } | ||
3045 | } | ||
3046 | |||
3047 | // PosFieldList | ||
3048 | #[derive(Debug, Clone, Copy,)] | ||
3049 | pub struct PosFieldListNode<R: TreeRoot<RaTypes> = OwnedRoot> { | ||
3050 | pub(crate) syntax: SyntaxNode<R>, | ||
3051 | } | ||
3052 | pub type PosFieldList<'a> = PosFieldListNode<RefRoot<'a>>; | ||
3053 | |||
3054 | impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<PosFieldListNode<R1>> for PosFieldListNode<R2> { | ||
3055 | fn eq(&self, other: &PosFieldListNode<R1>) -> bool { self.syntax == other.syntax } | ||
3056 | } | ||
3057 | impl<R: TreeRoot<RaTypes>> Eq for PosFieldListNode<R> {} | ||
3058 | impl<R: TreeRoot<RaTypes>> Hash for PosFieldListNode<R> { | ||
3059 | fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) } | ||
3060 | } | ||
3061 | |||
3062 | impl<'a> AstNode<'a> for PosFieldList<'a> { | ||
3063 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
3064 | match syntax.kind() { | ||
3065 | POS_FIELD_LIST => Some(PosFieldList { syntax }), | ||
3066 | _ => None, | ||
3067 | } | ||
3068 | } | ||
3069 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
3070 | } | ||
3071 | |||
3072 | impl<R: TreeRoot<RaTypes>> PosFieldListNode<R> { | ||
3073 | pub fn borrowed(&self) -> PosFieldList { | ||
3074 | PosFieldListNode { syntax: self.syntax.borrowed() } | ||
3075 | } | ||
3076 | pub fn owned(&self) -> PosFieldListNode { | ||
3077 | PosFieldListNode { syntax: self.syntax.owned() } | ||
3078 | } | ||
3079 | } | ||
3080 | |||
3081 | |||
3082 | impl<'a> PosFieldList<'a> { | ||
3083 | pub fn fields(self) -> impl Iterator<Item = PosField<'a>> + 'a { | ||
3084 | super::children(self) | ||
3085 | } | ||
3086 | } | ||
2820 | 3087 | ||
2821 | // PrefixExpr | 3088 | // PrefixExpr |
2822 | #[derive(Debug, Clone, Copy,)] | 3089 | #[derive(Debug, Clone, Copy,)] |
@@ -3046,7 +3313,11 @@ impl<R: TreeRoot<RaTypes>> ReferenceTypeNode<R> { | |||
3046 | } | 3313 | } |
3047 | 3314 | ||
3048 | 3315 | ||
3049 | impl<'a> ReferenceType<'a> {} | 3316 | impl<'a> ReferenceType<'a> { |
3317 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
3318 | super::child_opt(self) | ||
3319 | } | ||
3320 | } | ||
3050 | 3321 | ||
3051 | // RetType | 3322 | // RetType |
3052 | #[derive(Debug, Clone, Copy,)] | 3323 | #[derive(Debug, Clone, Copy,)] |
@@ -3239,7 +3510,11 @@ impl<R: TreeRoot<RaTypes>> SliceTypeNode<R> { | |||
3239 | } | 3510 | } |
3240 | 3511 | ||
3241 | 3512 | ||
3242 | impl<'a> SliceType<'a> {} | 3513 | impl<'a> SliceType<'a> { |
3514 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
3515 | super::child_opt(self) | ||
3516 | } | ||
3517 | } | ||
3243 | 3518 | ||
3244 | // SourceFile | 3519 | // SourceFile |
3245 | #[derive(Debug, Clone, Copy,)] | 3520 | #[derive(Debug, Clone, Copy,)] |
@@ -3426,11 +3701,7 @@ impl<'a> ast::NameOwner<'a> for StructDef<'a> {} | |||
3426 | impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} | 3701 | impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} |
3427 | impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} | 3702 | impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} |
3428 | impl<'a> ast::DocCommentsOwner<'a> for StructDef<'a> {} | 3703 | impl<'a> ast::DocCommentsOwner<'a> for StructDef<'a> {} |
3429 | impl<'a> StructDef<'a> { | 3704 | impl<'a> StructDef<'a> {} |
3430 | pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a { | ||
3431 | super::children(self) | ||
3432 | } | ||
3433 | } | ||
3434 | 3705 | ||
3435 | // StructLit | 3706 | // StructLit |
3436 | #[derive(Debug, Clone, Copy,)] | 3707 | #[derive(Debug, Clone, Copy,)] |
@@ -3467,7 +3738,15 @@ impl<R: TreeRoot<RaTypes>> StructLitNode<R> { | |||
3467 | } | 3738 | } |
3468 | 3739 | ||
3469 | 3740 | ||
3470 | impl<'a> StructLit<'a> {} | 3741 | impl<'a> StructLit<'a> { |
3742 | pub fn path(self) -> Option<Path<'a>> { | ||
3743 | super::child_opt(self) | ||
3744 | } | ||
3745 | |||
3746 | pub fn named_field_list(self) -> Option<NamedFieldList<'a>> { | ||
3747 | super::child_opt(self) | ||
3748 | } | ||
3749 | } | ||
3471 | 3750 | ||
3472 | // StructPat | 3751 | // StructPat |
3473 | #[derive(Debug, Clone, Copy,)] | 3752 | #[derive(Debug, Clone, Copy,)] |
@@ -3770,7 +4049,11 @@ impl<R: TreeRoot<RaTypes>> TupleTypeNode<R> { | |||
3770 | } | 4049 | } |
3771 | 4050 | ||
3772 | 4051 | ||
3773 | impl<'a> TupleType<'a> {} | 4052 | impl<'a> TupleType<'a> { |
4053 | pub fn fields(self) -> impl Iterator<Item = TypeRef<'a>> + 'a { | ||
4054 | super::children(self) | ||
4055 | } | ||
4056 | } | ||
3774 | 4057 | ||
3775 | // TypeDef | 4058 | // TypeDef |
3776 | #[derive(Debug, Clone, Copy,)] | 4059 | #[derive(Debug, Clone, Copy,)] |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index e3b9032a0..4bcff4e14 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -261,18 +261,20 @@ Grammar( | |||
261 | "TypeParamsOwner", | 261 | "TypeParamsOwner", |
262 | "AttrsOwner", | 262 | "AttrsOwner", |
263 | "DocCommentsOwner" | 263 | "DocCommentsOwner" |
264 | ], | ||
265 | collections: [ | ||
266 | ["fields", "NamedFieldDef"] | ||
267 | ] | 264 | ] |
268 | ), | 265 | ), |
269 | "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"] ), | 266 | "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]), |
267 | "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"], options: ["TypeRef"] ), | ||
268 | "PosFieldList": (collections: [["fields", "PosField"]]), | ||
269 | "PosField": ( traits: ["AttrsOwner"], options: ["TypeRef"]), | ||
270 | "EnumDef": ( traits: [ | 270 | "EnumDef": ( traits: [ |
271 | "NameOwner", | 271 | "NameOwner", |
272 | "TypeParamsOwner", | 272 | "TypeParamsOwner", |
273 | "AttrsOwner", | 273 | "AttrsOwner", |
274 | "DocCommentsOwner" | 274 | "DocCommentsOwner" |
275 | ] ), | 275 | ], options: [["variant_list", "EnumVariantList"]] ), |
276 | "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ), | ||
277 | "EnumVariant": ( traits: ["NameOwner"], options: ["Expr"] ), | ||
276 | "TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ), | 278 | "TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ), |
277 | "Module": ( | 279 | "Module": ( |
278 | traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ], | 280 | traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ], |
@@ -301,17 +303,17 @@ Grammar( | |||
301 | ] ), | 303 | ] ), |
302 | "ImplItem": (), | 304 | "ImplItem": (), |
303 | 305 | ||
304 | "ParenType": (), | 306 | "ParenType": (options: ["TypeRef"]), |
305 | "TupleType": (), | 307 | "TupleType": ( collections: [["fields", "TypeRef"]] ), |
306 | "NeverType": (), | 308 | "NeverType": (), |
307 | "PathType": (options: ["Path"]), | 309 | "PathType": (options: ["Path"]), |
308 | "PointerType": (), | 310 | "PointerType": (options: ["TypeRef"]), |
309 | "ArrayType": (), | 311 | "ArrayType": ( options: ["TypeRef", "Expr"] ), |
310 | "SliceType": (), | 312 | "SliceType": ( options: ["TypeRef"] ), |
311 | "ReferenceType": (), | 313 | "ReferenceType": (options: ["TypeRef"]), |
312 | "PlaceholderType": (), | 314 | "PlaceholderType": (), |
313 | "FnPointerType": (), | 315 | "FnPointerType": (options: ["ParamList", "RetType"]), |
314 | "ForType": (), | 316 | "ForType": (options: ["TypeRef"]), |
315 | "ImplTraitType": (), | 317 | "ImplTraitType": (), |
316 | "DynTraitType": (), | 318 | "DynTraitType": (), |
317 | 319 | ||
@@ -392,19 +394,19 @@ Grammar( | |||
392 | collections: [ [ "pats", "Pat" ] ] | 394 | collections: [ [ "pats", "Pat" ] ] |
393 | ), | 395 | ), |
394 | "MatchGuard": (), | 396 | "MatchGuard": (), |
395 | "StructLit": (), | 397 | "StructLit": (options: ["Path", "NamedFieldList"]), |
396 | "NamedFieldList": (), | 398 | "NamedFieldList": (collections: [ ["fields", "NamedField"] ]), |
397 | "NamedField": (), | 399 | "NamedField": (options: ["NameRef", "Expr"]), |
398 | "CallExpr": ( | 400 | "CallExpr": ( |
399 | traits: ["ArgListOwner"], | 401 | traits: ["ArgListOwner"], |
400 | options: [ "Expr" ], | 402 | options: [ "Expr" ], |
401 | ), | 403 | ), |
402 | "MethodCallExpr": ( | 404 | "MethodCallExpr": ( |
403 | traits: ["ArgListOwner"], | 405 | traits: ["ArgListOwner"], |
404 | options: [ "Expr" ], | 406 | options: [ "Expr", "NameRef" ], |
405 | ), | 407 | ), |
406 | "IndexExpr": (), | 408 | "IndexExpr": (), |
407 | "FieldExpr": (), | 409 | "FieldExpr": (options: ["Expr", "NameRef"]), |
408 | "TryExpr": (options: ["Expr"]), | 410 | "TryExpr": (options: ["Expr"]), |
409 | "CastExpr": (options: ["Expr", "TypeRef"]), | 411 | "CastExpr": (options: ["Expr", "TypeRef"]), |
410 | "RefExpr": (options: ["Expr"]), | 412 | "RefExpr": (options: ["Expr"]), |
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index da78d85a2..2d1f17491 100644 --- a/crates/ra_syntax/src/grammar/expressions.rs +++ b/crates/ra_syntax/src/grammar/expressions.rs | |||
@@ -283,14 +283,10 @@ fn postfix_expr( | |||
283 | // } | 283 | // } |
284 | L_PAREN if allow_calls => call_expr(p, lhs), | 284 | L_PAREN if allow_calls => call_expr(p, lhs), |
285 | L_BRACK if allow_calls => index_expr(p, lhs), | 285 | L_BRACK if allow_calls => index_expr(p, lhs), |
286 | DOT if p.nth(1) == IDENT => { | 286 | DOT if p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) => { |
287 | if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { | 287 | method_call_expr(p, lhs) |
288 | method_call_expr(p, lhs) | ||
289 | } else { | ||
290 | field_expr(p, lhs) | ||
291 | } | ||
292 | } | 288 | } |
293 | DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), | 289 | DOT => field_expr(p, lhs), |
294 | // test postfix_range | 290 | // test postfix_range |
295 | // fn foo() { let x = 1..; } | 291 | // fn foo() { let x = 1..; } |
296 | DOTDOT | DOTDOTEQ if !EXPR_FIRST.contains(p.nth(1)) => { | 292 | DOTDOT | DOTDOTEQ if !EXPR_FIRST.contains(p.nth(1)) => { |
@@ -355,13 +351,15 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
355 | // x.0.bar; | 351 | // x.0.bar; |
356 | // } | 352 | // } |
357 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 353 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { |
358 | assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); | 354 | assert!(p.at(DOT)); |
359 | let m = lhs.precede(p); | 355 | let m = lhs.precede(p); |
360 | p.bump(); | 356 | p.bump(); |
361 | if p.at(IDENT) { | 357 | if p.at(IDENT) { |
362 | name_ref(p) | 358 | name_ref(p) |
363 | } else { | 359 | } else if p.at(INT_NUMBER) { |
364 | p.bump() | 360 | p.bump() |
361 | } else { | ||
362 | p.error("expected field name or number") | ||
365 | } | 363 | } |
366 | m.complete(p, FIELD_EXPR) | 364 | m.complete(p, FIELD_EXPR) |
367 | } | 365 | } |