diff options
Diffstat (limited to 'crates/syntax/src/ast')
-rw-r--r-- | crates/syntax/src/ast/expr_ext.rs | 64 | ||||
-rw-r--r-- | crates/syntax/src/ast/token_ext.rs | 32 |
2 files changed, 39 insertions, 57 deletions
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs index eb44bb2ab..9253c97d0 100644 --- a/crates/syntax/src/ast/expr_ext.rs +++ b/crates/syntax/src/ast/expr_ext.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | ast::{self, support, AstChildren, AstNode}, | 4 | ast::{self, support, AstChildren, AstNode}, |
5 | AstToken, SmolStr, | 5 | AstToken, |
6 | SyntaxKind::*, | 6 | SyntaxKind::*, |
7 | SyntaxToken, T, | 7 | SyntaxToken, T, |
8 | }; | 8 | }; |
@@ -298,12 +298,12 @@ impl ast::ArrayExpr { | |||
298 | 298 | ||
299 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 299 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
300 | pub enum LiteralKind { | 300 | pub enum LiteralKind { |
301 | String, | 301 | String(ast::String), |
302 | ByteString, | 302 | ByteString(ast::ByteString), |
303 | IntNumber(ast::IntNumber), | ||
304 | FloatNumber(ast::FloatNumber), | ||
303 | Char, | 305 | Char, |
304 | Byte, | 306 | Byte, |
305 | IntNumber { suffix: Option<SmolStr> }, | ||
306 | FloatNumber { suffix: Option<SmolStr> }, | ||
307 | Bool(bool), | 307 | Bool(bool), |
308 | } | 308 | } |
309 | 309 | ||
@@ -315,53 +315,25 @@ impl ast::Literal { | |||
315 | .and_then(|e| e.into_token()) | 315 | .and_then(|e| e.into_token()) |
316 | .unwrap() | 316 | .unwrap() |
317 | } | 317 | } |
318 | |||
319 | pub fn as_int_number(&self) -> Option<ast::IntNumber> { | ||
320 | ast::IntNumber::cast(self.token()) | ||
321 | } | ||
322 | |||
323 | pub fn as_string(&self) -> Option<ast::String> { | ||
324 | ast::String::cast(self.token()) | ||
325 | } | ||
326 | pub fn as_byte_string(&self) -> Option<ast::ByteString> { | ||
327 | ast::ByteString::cast(self.token()) | ||
328 | } | ||
329 | |||
330 | fn find_suffix(text: &str, possible_suffixes: &[&str]) -> Option<SmolStr> { | ||
331 | possible_suffixes | ||
332 | .iter() | ||
333 | .find(|&suffix| text.ends_with(suffix)) | ||
334 | .map(|&suffix| SmolStr::new(suffix)) | ||
335 | } | ||
336 | |||
337 | pub fn kind(&self) -> LiteralKind { | 318 | pub fn kind(&self) -> LiteralKind { |
338 | let token = self.token(); | 319 | let token = self.token(); |
339 | 320 | ||
321 | if let Some(t) = ast::IntNumber::cast(token.clone()) { | ||
322 | return LiteralKind::IntNumber(t); | ||
323 | } | ||
324 | if let Some(t) = ast::FloatNumber::cast(token.clone()) { | ||
325 | return LiteralKind::FloatNumber(t); | ||
326 | } | ||
327 | if let Some(t) = ast::String::cast(token.clone()) { | ||
328 | return LiteralKind::String(t); | ||
329 | } | ||
330 | if let Some(t) = ast::ByteString::cast(token.clone()) { | ||
331 | return LiteralKind::ByteString(t); | ||
332 | } | ||
333 | |||
340 | match token.kind() { | 334 | match token.kind() { |
341 | INT_NUMBER => { | ||
342 | // FYI: there was a bug here previously, thus the if statement below is necessary. | ||
343 | // The lexer treats e.g. `1f64` as an integer literal. See | ||
344 | // https://github.com/rust-analyzer/rust-analyzer/issues/1592 | ||
345 | // and the comments on the linked PR. | ||
346 | let text = token.text(); | ||
347 | if let suffix @ Some(_) = Self::find_suffix(&text, &ast::FloatNumber::SUFFIXES) { | ||
348 | LiteralKind::FloatNumber { suffix } | ||
349 | } else { | ||
350 | LiteralKind::IntNumber { | ||
351 | suffix: Self::find_suffix(&text, &ast::IntNumber::SUFFIXES), | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | FLOAT_NUMBER => { | ||
356 | let text = token.text(); | ||
357 | LiteralKind::FloatNumber { | ||
358 | suffix: Self::find_suffix(&text, &ast::FloatNumber::SUFFIXES), | ||
359 | } | ||
360 | } | ||
361 | STRING => LiteralKind::String, | ||
362 | T![true] => LiteralKind::Bool(true), | 335 | T![true] => LiteralKind::Bool(true), |
363 | T![false] => LiteralKind::Bool(false), | 336 | T![false] => LiteralKind::Bool(false), |
364 | BYTE_STRING => LiteralKind::ByteString, | ||
365 | CHAR => LiteralKind::Char, | 337 | CHAR => LiteralKind::Char, |
366 | BYTE => LiteralKind::Byte, | 338 | BYTE => LiteralKind::Byte, |
367 | _ => unreachable!(), | 339 | _ => unreachable!(), |
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs index bf0035986..e4e512f2e 100644 --- a/crates/syntax/src/ast/token_ext.rs +++ b/crates/syntax/src/ast/token_ext.rs | |||
@@ -517,10 +517,9 @@ impl HasFormatSpecifier for ast::String { | |||
517 | } | 517 | } |
518 | 518 | ||
519 | impl ast::IntNumber { | 519 | impl ast::IntNumber { |
520 | #[rustfmt::skip] | 520 | const SUFFIXES: &'static [&'static str] = &[ |
521 | pub(crate) const SUFFIXES: &'static [&'static str] = &[ | 521 | "u8", "u16", "u32", "u64", "u128", "usize", // Unsigned. |
522 | "u8", "u16", "u32", "u64", "u128", "usize", | 522 | "i8", "i16", "i32", "i64", "i128", "isize", // Signed. |
523 | "i8", "i16", "i32", "i64", "i128", "isize", | ||
524 | ]; | 523 | ]; |
525 | 524 | ||
526 | pub fn radix(&self) -> Radix { | 525 | pub fn radix(&self) -> Radix { |
@@ -555,9 +554,24 @@ impl ast::IntNumber { | |||
555 | 554 | ||
556 | pub fn suffix(&self) -> Option<&str> { | 555 | pub fn suffix(&self) -> Option<&str> { |
557 | let text = self.text(); | 556 | let text = self.text(); |
558 | // FIXME: don't check a fixed set of suffixes, `1_0_1___lol` is valid | 557 | // FIXME: don't check a fixed set of suffixes, `1_0_1_l_o_l` is valid |
559 | // syntax, suffix is `lol`. | 558 | // syntax, suffix is `l_o_l`. |
560 | ast::IntNumber::SUFFIXES.iter().find_map(|suffix| { | 559 | ast::IntNumber::SUFFIXES.iter().chain(ast::FloatNumber::SUFFIXES.iter()).find_map( |
560 | |suffix| { | ||
561 | if text.ends_with(suffix) { | ||
562 | return Some(&text[text.len() - suffix.len()..]); | ||
563 | } | ||
564 | None | ||
565 | }, | ||
566 | ) | ||
567 | } | ||
568 | } | ||
569 | |||
570 | impl ast::FloatNumber { | ||
571 | const SUFFIXES: &'static [&'static str] = &["f32", "f64"]; | ||
572 | pub fn suffix(&self) -> Option<&str> { | ||
573 | let text = self.text(); | ||
574 | ast::FloatNumber::SUFFIXES.iter().find_map(|suffix| { | ||
561 | if text.ends_with(suffix) { | 575 | if text.ends_with(suffix) { |
562 | return Some(&text[text.len() - suffix.len()..]); | 576 | return Some(&text[text.len() - suffix.len()..]); |
563 | } | 577 | } |
@@ -566,10 +580,6 @@ impl ast::IntNumber { | |||
566 | } | 580 | } |
567 | } | 581 | } |
568 | 582 | ||
569 | impl ast::FloatNumber { | ||
570 | pub(crate) const SUFFIXES: &'static [&'static str] = &["f32", "f64"]; | ||
571 | } | ||
572 | |||
573 | #[derive(Debug, PartialEq, Eq, Copy, Clone)] | 583 | #[derive(Debug, PartialEq, Eq, Copy, Clone)] |
574 | pub enum Radix { | 584 | pub enum Radix { |
575 | Binary = 2, | 585 | Binary = 2, |