aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/string_lexing.rs
diff options
context:
space:
mode:
authorAdolfo OchagavĂ­a <[email protected]>2018-11-11 19:41:43 +0000
committerAdolfo OchagavĂ­a <[email protected]>2018-11-11 19:41:43 +0000
commit30cd4d5acb7dfd40cea264a926d1c89f0c3522c3 (patch)
treed71024919de98d74bf1a6bedc8a755c8810f1723 /crates/ra_syntax/src/string_lexing.rs
parentc258b4fdb0e421813330c2428985c4537c787582 (diff)
Validate byte string literals
Diffstat (limited to 'crates/ra_syntax/src/string_lexing.rs')
-rw-r--r--crates/ra_syntax/src/string_lexing.rs53
1 files changed, 51 insertions, 2 deletions
diff --git a/crates/ra_syntax/src/string_lexing.rs b/crates/ra_syntax/src/string_lexing.rs
index 4e8c3a91c..d253c97e7 100644
--- a/crates/ra_syntax/src/string_lexing.rs
+++ b/crates/ra_syntax/src/string_lexing.rs
@@ -1,6 +1,55 @@
1use self::CharComponentKind::*; 1use self::CharComponentKind::*;
2use rowan::{TextRange, TextUnit}; 2use rowan::{TextRange, TextUnit};
3 3
4pub fn parse_byte_string_literal(src: &str) -> ByteStringComponentIterator {
5 ByteStringComponentIterator {
6 parser: Parser::new(src),
7 has_closing_quote: false,
8 }
9}
10
11pub struct ByteStringComponentIterator<'a> {
12 parser: Parser<'a>,
13 pub has_closing_quote: bool,
14}
15
16impl<'a> Iterator for ByteStringComponentIterator<'a> {
17 type Item = StringComponent;
18 fn next(&mut self) -> Option<StringComponent> {
19 if self.parser.pos == 0 {
20 assert!(
21 self.parser.advance() == 'b',
22 "byte string literal should start with a `b`"
23 );
24
25 assert!(
26 self.parser.advance() == '"',
27 "byte string literal should start with a `b`, followed by double quotes"
28 );
29 }
30
31 if let Some(component) = self.parser.parse_string_component() {
32 return Some(component);
33 }
34
35 // We get here when there are no char components left to parse
36 if self.parser.peek() == Some('"') {
37 self.parser.advance();
38 self.has_closing_quote = true;
39 }
40
41 assert!(
42 self.parser.peek() == None,
43 "byte string literal should leave no unparsed input: src = {}, pos = {}, length = {}",
44 self.parser.src,
45 self.parser.pos,
46 self.parser.src.len()
47 );
48
49 None
50 }
51}
52
4pub fn parse_string_literal(src: &str) -> StringComponentIterator { 53pub fn parse_string_literal(src: &str) -> StringComponentIterator {
5 StringComponentIterator { 54 StringComponentIterator {
6 parser: Parser::new(src), 55 parser: Parser::new(src),
@@ -81,12 +130,12 @@ impl<'a> Iterator for ByteComponentIterator<'a> {
81 if self.parser.pos == 0 { 130 if self.parser.pos == 0 {
82 assert!( 131 assert!(
83 self.parser.advance() == 'b', 132 self.parser.advance() == 'b',
84 "Byte literal should start with a b" 133 "Byte literal should start with a `b`"
85 ); 134 );
86 135
87 assert!( 136 assert!(
88 self.parser.advance() == '\'', 137 self.parser.advance() == '\'',
89 "Byte literal should start with a b, followed by a quote" 138 "Byte literal should start with a `b`, followed by a quote"
90 ); 139 );
91 } 140 }
92 141