@@ -111,55 +111,46 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
111111 errors
112112}
113113
114- // FIXME: kill duplication
115114fn validate_literal ( literal : ast:: Literal , acc : & mut Vec < SyntaxError > ) {
115+ fn unquote ( text : & str , prefix_len : usize , end_delimiter : char ) -> Option < & str > {
116+ text. rfind ( end_delimiter) . and_then ( |end| text. get ( prefix_len..end) )
117+ }
118+
116119 let token = literal. token ( ) ;
117120 let text = token. text ( ) . as_str ( ) ;
121+
122+ let mut push_err = |prefix_len, ( off, err) : ( usize , unescape:: EscapeError ) | {
123+ let off = token. text_range ( ) . start ( ) + TextUnit :: from_usize ( off + prefix_len) ;
124+ acc. push ( SyntaxError :: new ( err. into ( ) , off) ) ;
125+ } ;
126+
118127 match token. kind ( ) {
119128 BYTE => {
120- if let Some ( end) = text. rfind ( '\'' ) {
121- if let Some ( without_quotes) = text. get ( 2 ..end) {
122- if let Err ( ( off, err) ) = unescape:: unescape_byte ( without_quotes) {
123- let off = token. text_range ( ) . start ( ) + TextUnit :: from_usize ( off + 2 ) ;
124- acc. push ( SyntaxError :: new ( err. into ( ) , off) )
125- }
126- }
129+ if let Some ( Err ( e) ) = unquote ( text, 2 , '\'' ) . map ( unescape:: unescape_byte) {
130+ push_err ( 2 , e) ;
127131 }
128132 }
129133 CHAR => {
130- if let Some ( end) = text. rfind ( '\'' ) {
131- if let Some ( without_quotes) = text. get ( 1 ..end) {
132- if let Err ( ( off, err) ) = unescape:: unescape_char ( without_quotes) {
133- let off = token. text_range ( ) . start ( ) + TextUnit :: from_usize ( off + 1 ) ;
134- acc. push ( SyntaxError :: new ( err. into ( ) , off) )
135- }
136- }
134+ if let Some ( Err ( e) ) = unquote ( text, 1 , '\'' ) . map ( unescape:: unescape_char) {
135+ push_err ( 1 , e) ;
137136 }
138137 }
139138 BYTE_STRING => {
140- if let Some ( end) = text. rfind ( '\"' ) {
141- if let Some ( without_quotes) = text. get ( 2 ..end) {
142- unescape:: unescape_byte_str ( without_quotes, & mut |range, char| {
143- if let Err ( err) = char {
144- let off = range. start ;
145- let off = token. text_range ( ) . start ( ) + TextUnit :: from_usize ( off + 2 ) ;
146- acc. push ( SyntaxError :: new ( err. into ( ) , off) )
147- }
148- } )
149- }
139+ if let Some ( without_quotes) = unquote ( text, 2 , '"' ) {
140+ unescape:: unescape_byte_str ( without_quotes, & mut |range, char| {
141+ if let Err ( err) = char {
142+ push_err ( 2 , ( range. start , err) ) ;
143+ }
144+ } )
150145 }
151146 }
152147 STRING => {
153- if let Some ( end) = text. rfind ( '\"' ) {
154- if let Some ( without_quotes) = text. get ( 1 ..end) {
155- unescape:: unescape_str ( without_quotes, & mut |range, char| {
156- if let Err ( err) = char {
157- let off = range. start ;
158- let off = token. text_range ( ) . start ( ) + TextUnit :: from_usize ( off + 1 ) ;
159- acc. push ( SyntaxError :: new ( err. into ( ) , off) )
160- }
161- } )
162- }
148+ if let Some ( without_quotes) = unquote ( text, 1 , '"' ) {
149+ unescape:: unescape_str ( without_quotes, & mut |range, char| {
150+ if let Err ( err) = char {
151+ push_err ( 1 , ( range. start , err) ) ;
152+ }
153+ } )
163154 }
164155 }
165156 _ => ( ) ,
0 commit comments