diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/add_impl.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/ast_editor.rs | 2 | ||||
-rw-r--r-- | crates/ra_assists/src/introduce_variable.rs | 5 | ||||
-rw-r--r-- | crates/ra_fmt/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 41 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 35 | ||||
-rw-r--r-- | crates/ra_ide_api/src/display/short_label.rs | 7 | ||||
-rw-r--r-- | crates/ra_ide_api/src/folding_ranges.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/join_lines.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/typing.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 33 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_text.rs | 16 |
15 files changed, 139 insertions, 25 deletions
diff --git a/crates/ra_assists/src/add_impl.rs b/crates/ra_assists/src/add_impl.rs index 9a0cfb4e7..59ca88468 100644 --- a/crates/ra_assists/src/add_impl.rs +++ b/crates/ra_assists/src/add_impl.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | use std::fmt::Write; | ||
2 | |||
1 | use hir::db::HirDatabase; | 3 | use hir::db::HirDatabase; |
2 | use join_to_string::join; | 4 | use join_to_string::join; |
3 | use ra_syntax::{ | 5 | use ra_syntax::{ |
@@ -17,7 +19,7 @@ pub(crate) fn add_impl(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
17 | let mut buf = String::new(); | 19 | let mut buf = String::new(); |
18 | buf.push_str("\n\nimpl"); | 20 | buf.push_str("\n\nimpl"); |
19 | if let Some(type_params) = &type_params { | 21 | if let Some(type_params) = &type_params { |
20 | type_params.syntax().text().push_to(&mut buf); | 22 | write!(buf, "{}", type_params.syntax()).unwrap(); |
21 | } | 23 | } |
22 | buf.push_str(" "); | 24 | buf.push_str(" "); |
23 | buf.push_str(name.text().as_str()); | 25 | buf.push_str(name.text().as_str()); |
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs index 36235eb13..ab6c347ad 100644 --- a/crates/ra_assists/src/ast_editor.rs +++ b/crates/ra_assists/src/ast_editor.rs | |||
@@ -95,7 +95,7 @@ impl AstEditor<ast::NamedFieldList> { | |||
95 | position: InsertPosition<&'_ ast::NamedField>, | 95 | position: InsertPosition<&'_ ast::NamedField>, |
96 | field: &ast::NamedField, | 96 | field: &ast::NamedField, |
97 | ) { | 97 | ) { |
98 | let is_multiline = self.ast().syntax().text().contains('\n'); | 98 | let is_multiline = self.ast().syntax().text().contains_char('\n'); |
99 | let ws; | 99 | let ws; |
100 | let space = if is_multiline { | 100 | let space = if is_multiline { |
101 | ws = tokens::WsBuilder::new(&format!( | 101 | ws = tokens::WsBuilder::new(&format!( |
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs index df6c58989..911de2d48 100644 --- a/crates/ra_assists/src/introduce_variable.rs +++ b/crates/ra_assists/src/introduce_variable.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | use std::fmt::Write; | ||
2 | |||
1 | use hir::db::HirDatabase; | 3 | use hir::db::HirDatabase; |
2 | use ra_syntax::{ | 4 | use ra_syntax::{ |
3 | ast::{self, AstNode}, | 5 | ast::{self, AstNode}, |
@@ -35,8 +37,7 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option | |||
35 | buf.push_str("let var_name = "); | 37 | buf.push_str("let var_name = "); |
36 | TextUnit::of_str("let ") | 38 | TextUnit::of_str("let ") |
37 | }; | 39 | }; |
38 | 40 | write!(buf, "{}", expr.syntax()).unwrap(); | |
39 | expr.syntax().text().push_to(&mut buf); | ||
40 | let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); | 41 | let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); |
41 | let is_full_stmt = if let Some(expr_stmt) = &full_stmt { | 42 | let is_full_stmt = if let Some(expr_stmt) = &full_stmt { |
42 | Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone()) | 43 | Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone()) |
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs index d6e895729..b09478d7a 100644 --- a/crates/ra_fmt/src/lib.rs +++ b/crates/ra_fmt/src/lib.rs | |||
@@ -36,7 +36,7 @@ fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { | |||
36 | 36 | ||
37 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<ast::Expr> { | 37 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<ast::Expr> { |
38 | let expr = block.expr()?; | 38 | let expr = block.expr()?; |
39 | if expr.syntax().text().contains('\n') { | 39 | if expr.syntax().text().contains_char('\n') { |
40 | return None; | 40 | return None; |
41 | } | 41 | } |
42 | let non_trivial_children = block.syntax().children().filter(|it| match it.kind() { | 42 | let non_trivial_children = block.syntax().children().filter(|it| match it.kind() { |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6eed67f50..4dcea19a9 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -220,6 +220,9 @@ pub enum Expr { | |||
220 | expr: ExprId, | 220 | expr: ExprId, |
221 | name: Name, | 221 | name: Name, |
222 | }, | 222 | }, |
223 | Await { | ||
224 | expr: ExprId, | ||
225 | }, | ||
223 | Try { | 226 | Try { |
224 | expr: ExprId, | 227 | expr: ExprId, |
225 | }, | 228 | }, |
@@ -359,6 +362,7 @@ impl Expr { | |||
359 | f(*rhs); | 362 | f(*rhs); |
360 | } | 363 | } |
361 | Expr::Field { expr, .. } | 364 | Expr::Field { expr, .. } |
365 | | Expr::Await { expr } | ||
362 | | Expr::Try { expr } | 366 | | Expr::Try { expr } |
363 | | Expr::Cast { expr, .. } | 367 | | Expr::Cast { expr, .. } |
364 | | Expr::Ref { expr, .. } | 368 | | Expr::Ref { expr, .. } |
@@ -729,6 +733,10 @@ where | |||
729 | }; | 733 | }; |
730 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) | 734 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) |
731 | } | 735 | } |
736 | ast::ExprKind::AwaitExpr(e) => { | ||
737 | let expr = self.collect_expr_opt(e.expr()); | ||
738 | self.alloc_expr(Expr::Await { expr }, syntax_ptr) | ||
739 | } | ||
732 | ast::ExprKind::TryExpr(e) => { | 740 | ast::ExprKind::TryExpr(e) => { |
733 | let expr = self.collect_expr_opt(e.expr()); | 741 | let expr = self.collect_expr_opt(e.expr()); |
734 | self.alloc_expr(Expr::Try { expr }, syntax_ptr) | 742 | self.alloc_expr(Expr::Try { expr }, syntax_ptr) |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index c589f8aba..6d14eea8e 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs | |||
@@ -118,6 +118,9 @@ pub(crate) const ITEM: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"Item | |||
118 | pub(crate) const OPS: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"ops")); | 118 | pub(crate) const OPS: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"ops")); |
119 | pub(crate) const TRY: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"Try")); | 119 | pub(crate) const TRY: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"Try")); |
120 | pub(crate) const OK: Name = Name::new(SmolStr::new_inline_from_ascii(2, b"Ok")); | 120 | pub(crate) const OK: Name = Name::new(SmolStr::new_inline_from_ascii(2, b"Ok")); |
121 | pub(crate) const FUTURE_MOD: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"future")); | ||
122 | pub(crate) const FUTURE_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Future")); | ||
123 | pub(crate) const OUTPUT: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Output")); | ||
121 | 124 | ||
122 | fn resolve_name(text: &SmolStr) -> SmolStr { | 125 | fn resolve_name(text: &SmolStr) -> SmolStr { |
123 | let raw_start = "r#"; | 126 | let raw_start = "r#"; |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 0e030576d..a82dff711 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -1114,6 +1114,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1114 | .unwrap_or(Ty::Unknown); | 1114 | .unwrap_or(Ty::Unknown); |
1115 | self.insert_type_vars(ty) | 1115 | self.insert_type_vars(ty) |
1116 | } | 1116 | } |
1117 | Expr::Await { expr } => { | ||
1118 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | ||
1119 | let ty = match self.resolve_future_future_output() { | ||
1120 | Some(future_future_output_alias) => { | ||
1121 | let ty = self.new_type_var(); | ||
1122 | let projection = ProjectionPredicate { | ||
1123 | ty: ty.clone(), | ||
1124 | projection_ty: ProjectionTy { | ||
1125 | associated_ty: future_future_output_alias, | ||
1126 | parameters: vec![inner_ty].into(), | ||
1127 | }, | ||
1128 | }; | ||
1129 | self.obligations.push(Obligation::Projection(projection)); | ||
1130 | self.resolve_ty_as_possible(&mut vec![], ty) | ||
1131 | } | ||
1132 | None => Ty::Unknown, | ||
1133 | }; | ||
1134 | ty | ||
1135 | } | ||
1117 | Expr::Try { expr } => { | 1136 | Expr::Try { expr } => { |
1118 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 1137 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1119 | let ty = match self.resolve_ops_try_ok() { | 1138 | let ty = match self.resolve_ops_try_ok() { |
@@ -1368,6 +1387,28 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1368 | _ => None, | 1387 | _ => None, |
1369 | } | 1388 | } |
1370 | } | 1389 | } |
1390 | |||
1391 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { | ||
1392 | let future_future_path = Path { | ||
1393 | kind: PathKind::Abs, | ||
1394 | segments: vec![ | ||
1395 | PathSegment { name: name::STD, args_and_bindings: None }, | ||
1396 | PathSegment { name: name::FUTURE_MOD, args_and_bindings: None }, | ||
1397 | PathSegment { name: name::FUTURE_TYPE, args_and_bindings: None }, | ||
1398 | ], | ||
1399 | }; | ||
1400 | |||
1401 | match self | ||
1402 | .resolver | ||
1403 | .resolve_path_segments(self.db, &future_future_path) | ||
1404 | .into_fully_resolved() | ||
1405 | { | ||
1406 | PerNs { types: Some(Def(Trait(trait_))), .. } => { | ||
1407 | Some(trait_.associated_type_by_name(self.db, name::OUTPUT)?) | ||
1408 | } | ||
1409 | _ => None, | ||
1410 | } | ||
1411 | } | ||
1371 | } | 1412 | } |
1372 | 1413 | ||
1373 | /// The ID of a type variable. | 1414 | /// The ID of a type variable. |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 7b2bdeb3f..706500484 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -21,6 +21,41 @@ use crate::{ | |||
21 | // update the snapshots. | 21 | // update the snapshots. |
22 | 22 | ||
23 | #[test] | 23 | #[test] |
24 | fn infer_await() { | ||
25 | let (mut db, pos) = MockDatabase::with_position( | ||
26 | r#" | ||
27 | //- /main.rs | ||
28 | |||
29 | struct IntFuture; | ||
30 | |||
31 | impl Future for IntFuture { | ||
32 | type Output = u64; | ||
33 | } | ||
34 | |||
35 | fn test() { | ||
36 | let r = IntFuture; | ||
37 | let v = r.await; | ||
38 | v<|>; | ||
39 | } | ||
40 | |||
41 | //- /std.rs | ||
42 | #[prelude_import] use future::*; | ||
43 | mod future { | ||
44 | trait Future { | ||
45 | type Output; | ||
46 | } | ||
47 | } | ||
48 | |||
49 | "#, | ||
50 | ); | ||
51 | db.set_crate_graph_from_fixture(crate_graph! { | ||
52 | "main": ("/main.rs", ["std"]), | ||
53 | "std": ("/std.rs", []), | ||
54 | }); | ||
55 | assert_eq!("u64", type_at_pos(&db, pos)); | ||
56 | } | ||
57 | |||
58 | #[test] | ||
24 | fn infer_try() { | 59 | fn infer_try() { |
25 | let (mut db, pos) = MockDatabase::with_position( | 60 | let (mut db, pos) = MockDatabase::with_position( |
26 | r#" | 61 | r#" |
diff --git a/crates/ra_ide_api/src/display/short_label.rs b/crates/ra_ide_api/src/display/short_label.rs index f926f631f..be499e485 100644 --- a/crates/ra_ide_api/src/display/short_label.rs +++ b/crates/ra_ide_api/src/display/short_label.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | use std::fmt::Write; | ||
2 | |||
1 | use ra_syntax::ast::{self, AstNode, NameOwner, TypeAscriptionOwner, VisibilityOwner}; | 3 | use ra_syntax::ast::{self, AstNode, NameOwner, TypeAscriptionOwner, VisibilityOwner}; |
2 | 4 | ||
3 | pub(crate) trait ShortLabel { | 5 | pub(crate) trait ShortLabel { |
@@ -71,8 +73,7 @@ where | |||
71 | let mut buf = short_label_from_node(node, prefix)?; | 73 | let mut buf = short_label_from_node(node, prefix)?; |
72 | 74 | ||
73 | if let Some(type_ref) = node.ascribed_type() { | 75 | if let Some(type_ref) = node.ascribed_type() { |
74 | buf.push_str(": "); | 76 | write!(buf, ": {}", type_ref.syntax()).unwrap(); |
75 | type_ref.syntax().text().push_to(&mut buf); | ||
76 | } | 77 | } |
77 | 78 | ||
78 | Some(buf) | 79 | Some(buf) |
@@ -82,7 +83,7 @@ fn short_label_from_node<T>(node: &T, label: &str) -> Option<String> | |||
82 | where | 83 | where |
83 | T: NameOwner + VisibilityOwner, | 84 | T: NameOwner + VisibilityOwner, |
84 | { | 85 | { |
85 | let mut buf = node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); | 86 | let mut buf = node.visibility().map(|v| format!("{} ", v.syntax())).unwrap_or_default(); |
86 | buf.push_str(label); | 87 | buf.push_str(label); |
87 | buf.push_str(node.name()?.text().as_str()); | 88 | buf.push_str(node.name()?.text().as_str()); |
88 | Some(buf) | 89 | Some(buf) |
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs index 9699000db..571d1c595 100644 --- a/crates/ra_ide_api/src/folding_ranges.rs +++ b/crates/ra_ide_api/src/folding_ranges.rs | |||
@@ -31,7 +31,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { | |||
31 | // Fold items that span multiple lines | 31 | // Fold items that span multiple lines |
32 | if let Some(kind) = fold_kind(element.kind()) { | 32 | if let Some(kind) = fold_kind(element.kind()) { |
33 | let is_multiline = match &element { | 33 | let is_multiline = match &element { |
34 | SyntaxElement::Node(node) => node.text().contains('\n'), | 34 | SyntaxElement::Node(node) => node.text().contains_char('\n'), |
35 | SyntaxElement::Token(token) => token.text().contains('\n'), | 35 | SyntaxElement::Token(token) => token.text().contains('\n'), |
36 | }; | 36 | }; |
37 | if is_multiline { | 37 | if is_multiline { |
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs index fa998ebe1..7f25f2108 100644 --- a/crates/ra_ide_api/src/join_lines.rs +++ b/crates/ra_ide_api/src/join_lines.rs | |||
@@ -13,7 +13,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { | |||
13 | let range = if range.is_empty() { | 13 | let range = if range.is_empty() { |
14 | let syntax = file.syntax(); | 14 | let syntax = file.syntax(); |
15 | let text = syntax.text().slice(range.start()..); | 15 | let text = syntax.text().slice(range.start()..); |
16 | let pos = match text.find('\n') { | 16 | let pos = match text.find_char('\n') { |
17 | None => return TextEditBuilder::default().finish(), | 17 | None => return TextEditBuilder::default().finish(), |
18 | Some(pos) => pos, | 18 | Some(pos) => pos, |
19 | }; | 19 | }; |
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs index 1747a529e..5a1cbcc49 100644 --- a/crates/ra_ide_api/src/typing.rs +++ b/crates/ra_ide_api/src/typing.rs | |||
@@ -75,7 +75,7 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> { | |||
75 | if expr_range.contains(eq_offset) && eq_offset != expr_range.start() { | 75 | if expr_range.contains(eq_offset) && eq_offset != expr_range.start() { |
76 | return None; | 76 | return None; |
77 | } | 77 | } |
78 | if file.syntax().text().slice(eq_offset..expr_range.start()).contains('\n') { | 78 | if file.syntax().text().slice(eq_offset..expr_range.start()).contains_char('\n') { |
79 | return None; | 79 | return None; |
80 | } | 80 | } |
81 | } else { | 81 | } else { |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 99fcdbd9a..da8cf4ae8 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -175,6 +175,32 @@ impl Attr { | |||
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | // AwaitExpr | ||
179 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
180 | pub struct AwaitExpr { | ||
181 | pub(crate) syntax: SyntaxNode, | ||
182 | } | ||
183 | |||
184 | impl AstNode for AwaitExpr { | ||
185 | fn can_cast(kind: SyntaxKind) -> bool { | ||
186 | match kind { | ||
187 | AWAIT_EXPR => true, | ||
188 | _ => false, | ||
189 | } | ||
190 | } | ||
191 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
192 | if Self::can_cast(syntax.kind()) { Some(AwaitExpr { syntax }) } else { None } | ||
193 | } | ||
194 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
195 | } | ||
196 | |||
197 | |||
198 | impl AwaitExpr { | ||
199 | pub fn expr(&self) -> Option<Expr> { | ||
200 | super::child_opt(self) | ||
201 | } | ||
202 | } | ||
203 | |||
178 | // BinExpr | 204 | // BinExpr |
179 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 205 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
180 | pub struct BinExpr { | 206 | pub struct BinExpr { |
@@ -566,7 +592,7 @@ pub struct Expr { | |||
566 | impl AstNode for Expr { | 592 | impl AstNode for Expr { |
567 | fn can_cast(kind: SyntaxKind) -> bool { | 593 | fn can_cast(kind: SyntaxKind) -> bool { |
568 | match kind { | 594 | match kind { |
569 | | TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | STRUCT_LIT | CALL_EXPR | INDEX_EXPR | METHOD_CALL_EXPR | FIELD_EXPR | TRY_EXPR | TRY_BLOCK_EXPR | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL => true, | 595 | | TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | STRUCT_LIT | CALL_EXPR | INDEX_EXPR | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL => true, |
570 | _ => false, | 596 | _ => false, |
571 | } | 597 | } |
572 | } | 598 | } |
@@ -599,6 +625,7 @@ pub enum ExprKind { | |||
599 | IndexExpr(IndexExpr), | 625 | IndexExpr(IndexExpr), |
600 | MethodCallExpr(MethodCallExpr), | 626 | MethodCallExpr(MethodCallExpr), |
601 | FieldExpr(FieldExpr), | 627 | FieldExpr(FieldExpr), |
628 | AwaitExpr(AwaitExpr), | ||
602 | TryExpr(TryExpr), | 629 | TryExpr(TryExpr), |
603 | TryBlockExpr(TryBlockExpr), | 630 | TryBlockExpr(TryBlockExpr), |
604 | CastExpr(CastExpr), | 631 | CastExpr(CastExpr), |
@@ -669,6 +696,9 @@ impl From<MethodCallExpr> for Expr { | |||
669 | impl From<FieldExpr> for Expr { | 696 | impl From<FieldExpr> for Expr { |
670 | fn from(n: FieldExpr) -> Expr { Expr { syntax: n.syntax } } | 697 | fn from(n: FieldExpr) -> Expr { Expr { syntax: n.syntax } } |
671 | } | 698 | } |
699 | impl From<AwaitExpr> for Expr { | ||
700 | fn from(n: AwaitExpr) -> Expr { Expr { syntax: n.syntax } } | ||
701 | } | ||
672 | impl From<TryExpr> for Expr { | 702 | impl From<TryExpr> for Expr { |
673 | fn from(n: TryExpr) -> Expr { Expr { syntax: n.syntax } } | 703 | fn from(n: TryExpr) -> Expr { Expr { syntax: n.syntax } } |
674 | } | 704 | } |
@@ -719,6 +749,7 @@ impl Expr { | |||
719 | INDEX_EXPR => ExprKind::IndexExpr(IndexExpr::cast(self.syntax.clone()).unwrap()), | 749 | INDEX_EXPR => ExprKind::IndexExpr(IndexExpr::cast(self.syntax.clone()).unwrap()), |
720 | METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(self.syntax.clone()).unwrap()), | 750 | METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(self.syntax.clone()).unwrap()), |
721 | FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(self.syntax.clone()).unwrap()), | 751 | FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(self.syntax.clone()).unwrap()), |
752 | AWAIT_EXPR => ExprKind::AwaitExpr(AwaitExpr::cast(self.syntax.clone()).unwrap()), | ||
722 | TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(self.syntax.clone()).unwrap()), | 753 | TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(self.syntax.clone()).unwrap()), |
723 | TRY_BLOCK_EXPR => ExprKind::TryBlockExpr(TryBlockExpr::cast(self.syntax.clone()).unwrap()), | 754 | TRY_BLOCK_EXPR => ExprKind::TryBlockExpr(TryBlockExpr::cast(self.syntax.clone()).unwrap()), |
724 | CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(self.syntax.clone()).unwrap()), | 755 | CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(self.syntax.clone()).unwrap()), |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 55494239e..817dedfbf 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -477,6 +477,7 @@ Grammar( | |||
477 | ), | 477 | ), |
478 | "IndexExpr": (), | 478 | "IndexExpr": (), |
479 | "FieldExpr": (options: ["Expr", "NameRef"]), | 479 | "FieldExpr": (options: ["Expr", "NameRef"]), |
480 | "AwaitExpr": (options: ["Expr"]), | ||
480 | "TryExpr": (options: ["Expr"]), | 481 | "TryExpr": (options: ["Expr"]), |
481 | "CastExpr": (options: ["Expr", "TypeRef"]), | 482 | "CastExpr": (options: ["Expr", "TypeRef"]), |
482 | "RefExpr": (options: ["Expr"]), | 483 | "RefExpr": (options: ["Expr"]), |
@@ -508,6 +509,7 @@ Grammar( | |||
508 | "IndexExpr", | 509 | "IndexExpr", |
509 | "MethodCallExpr", | 510 | "MethodCallExpr", |
510 | "FieldExpr", | 511 | "FieldExpr", |
512 | "AwaitExpr", | ||
511 | "TryExpr", | 513 | "TryExpr", |
512 | "TryBlockExpr", | 514 | "TryBlockExpr", |
513 | "CastExpr", | 515 | "CastExpr", |
diff --git a/crates/ra_syntax/src/syntax_text.rs b/crates/ra_syntax/src/syntax_text.rs index f8ddff48e..652cb7a1e 100644 --- a/crates/ra_syntax/src/syntax_text.rs +++ b/crates/ra_syntax/src/syntax_text.rs | |||
@@ -57,25 +57,15 @@ impl SyntaxText { | |||
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | pub fn push_to(&self, buf: &mut String) { | ||
61 | self.for_each_chunk(|chunk| buf.push_str(chunk)) | ||
62 | } | ||
63 | |||
64 | pub fn to_string(&self) -> String { | ||
65 | let mut buf = String::new(); | ||
66 | self.push_to(&mut buf); | ||
67 | buf | ||
68 | } | ||
69 | |||
70 | pub fn to_smol_string(&self) -> SmolStr { | 60 | pub fn to_smol_string(&self) -> SmolStr { |
71 | self.to_string().into() | 61 | self.to_string().into() |
72 | } | 62 | } |
73 | 63 | ||
74 | pub fn contains(&self, c: char) -> bool { | 64 | pub fn contains_char(&self, c: char) -> bool { |
75 | self.try_for_each_chunk(|chunk| if chunk.contains(c) { Err(()) } else { Ok(()) }).is_err() | 65 | self.try_for_each_chunk(|chunk| if chunk.contains(c) { Err(()) } else { Ok(()) }).is_err() |
76 | } | 66 | } |
77 | 67 | ||
78 | pub fn find(&self, c: char) -> Option<TextUnit> { | 68 | pub fn find_char(&self, c: char) -> Option<TextUnit> { |
79 | let mut acc: TextUnit = 0.into(); | 69 | let mut acc: TextUnit = 0.into(); |
80 | let res = self.try_for_each_chunk(|chunk| { | 70 | let res = self.try_for_each_chunk(|chunk| { |
81 | if let Some(pos) = chunk.find(c) { | 71 | if let Some(pos) = chunk.find(c) { |
@@ -158,7 +148,7 @@ impl fmt::Debug for SyntaxText { | |||
158 | 148 | ||
159 | impl fmt::Display for SyntaxText { | 149 | impl fmt::Display for SyntaxText { |
160 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 150 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
161 | fmt::Display::fmt(&self.to_string(), f) | 151 | self.try_for_each_chunk(|chunk| fmt::Display::fmt(chunk, f)) |
162 | } | 152 | } |
163 | } | 153 | } |
164 | 154 | ||