aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-11-06 18:01:25 +0000
committerAleksey Kladov <[email protected]>2020-11-06 18:09:01 +0000
commiteb460333907a44c37bf7287b31c653877c3358c2 (patch)
tree1f048935ea6b51cc1e5f01d0613552264b31f02d /crates/syntax
parent735aaa7b39b4d3d789ad75c167bbf322a65ca257 (diff)
More orthogonal API
Diffstat (limited to 'crates/syntax')
-rw-r--r--crates/syntax/src/ast/token_ext.rs63
1 files changed, 30 insertions, 33 deletions
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index 5623799b4..8d3fad5a6 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -166,6 +166,7 @@ impl HasStringValue for ast::String {
166 } 166 }
167} 167}
168 168
169// FIXME: merge `ast::RawString` and `ast::String`.
169impl HasStringValue for ast::RawString { 170impl HasStringValue for ast::RawString {
170 fn value(&self) -> Option<Cow<'_, str>> { 171 fn value(&self) -> Option<Cow<'_, str>> {
171 let text = self.text().as_str(); 172 let text = self.text().as_str();
@@ -544,29 +545,46 @@ impl ast::IntNumber {
544 "i8", "i16", "i32", "i64", "i128", "isize", 545 "i8", "i16", "i32", "i64", "i128", "isize",
545 ]; 546 ];
546 547
547 // FIXME: should probably introduce string token type? 548 pub fn radix(&self) -> Radix {
548 // https://github.com/rust-analyzer/rust-analyzer/issues/6308 549 match self.text().get(..2).unwrap_or_default() {
549 pub fn value(&self) -> Option<(Radix, u128)> { 550 "0b" => Radix::Binary,
551 "0o" => Radix::Octal,
552 "0x" => Radix::Hexadecimal,
553 _ => Radix::Decimal,
554 }
555 }
556
557 pub fn value(&self) -> Option<u128> {
550 let token = self.syntax(); 558 let token = self.syntax();
551 559
552 let mut text = token.text().as_str(); 560 let mut text = token.text().as_str();
553 for suffix in ast::IntNumber::SUFFIXES { 561 if let Some(suffix) = self.suffix() {
554 if let Some(without_suffix) = text.strip_suffix(suffix) { 562 text = &text[..text.len() - suffix.len()]
555 text = without_suffix;
556 break;
557 }
558 } 563 }
559 564
565 let radix = self.radix();
566 text = &text[radix.prefix_len()..];
567
560 let buf; 568 let buf;
561 if text.contains("_") { 569 if text.contains("_") {
562 buf = text.replace('_', ""); 570 buf = text.replace('_', "");
563 text = buf.as_str(); 571 text = buf.as_str();
564 }; 572 };
565 573
566 let radix = Radix::identify(text)?; 574 let value = u128::from_str_radix(text, radix as u32).ok()?;
567 let digits = &text[radix.prefix_len()..]; 575 Some(value)
568 let value = u128::from_str_radix(digits, radix as u32).ok()?; 576 }
569 Some((radix, value)) 577
578 pub fn suffix(&self) -> Option<&str> {
579 let text = self.text();
580 // FIXME: don't check a fixed set of suffixes, `1_0_1___lol` is valid
581 // syntax, suffix is `lol`.
582 ast::IntNumber::SUFFIXES.iter().find_map(|suffix| {
583 if text.ends_with(suffix) {
584 return Some(&text[text.len() - suffix.len()..]);
585 }
586 None
587 })
570 } 588 }
571} 589}
572 590
@@ -586,27 +604,6 @@ impl Radix {
586 pub const ALL: &'static [Radix] = 604 pub const ALL: &'static [Radix] =
587 &[Radix::Binary, Radix::Octal, Radix::Decimal, Radix::Hexadecimal]; 605 &[Radix::Binary, Radix::Octal, Radix::Decimal, Radix::Hexadecimal];
588 606
589 fn identify(literal_text: &str) -> Option<Self> {
590 // We cannot express a literal in anything other than decimal in under 3 characters, so we return here if possible.
591 if literal_text.len() < 3 && literal_text.chars().all(|c| c.is_digit(10)) {
592 return Some(Self::Decimal);
593 }
594
595 let res = match &literal_text[..2] {
596 "0b" => Radix::Binary,
597 "0o" => Radix::Octal,
598 "0x" => Radix::Hexadecimal,
599 _ => Radix::Decimal,
600 };
601
602 // Checks that all characters after the base prefix are all valid digits for that base.
603 if literal_text[res.prefix_len()..].chars().all(|c| c.is_digit(res as u32)) {
604 Some(res)
605 } else {
606 None
607 }
608 }
609
610 const fn prefix_len(&self) -> usize { 607 const fn prefix_len(&self) -> usize {
611 match self { 608 match self {
612 Self::Decimal => 0, 609 Self::Decimal => 0,