nff: LexError should include position for InvalidNumber; update diagnostics
This commit is contained in:
		
					parent
					
						
							
								728483d84f
							
						
					
				
			
			
				commit
				
					
						c0002f5806
					
				
			
		
					 2 changed files with 49 additions and 24 deletions
				
			
		|  | @ -453,7 +453,7 @@ impl AnalyzerModule for LexicalAnalyzer { | |||
| } | ||||
| 
 | ||||
| impl LexicalAnalyzer { | ||||
|     fn lex_error_to_diagnostic(error: &LexError, source: &str) -> Diagnostic { | ||||
|     pub fn lex_error_to_diagnostic(error: &LexError, source: &str) -> Diagnostic { | ||||
|         match error { | ||||
|             LexError::InvalidToken { position, text } => { | ||||
|                 let pos = Position::from_text_size(TextSize::from(*position as u32), source); | ||||
|  | @ -478,27 +478,17 @@ impl LexicalAnalyzer { | |||
|                     "Unterminated string literal".to_string(), | ||||
|                 ) | ||||
|             } | ||||
|             LexError::InvalidNumber { text } => { | ||||
|                 if let Some(pos) = source.find(text) { | ||||
|                     let start_pos = Position::from_text_size(TextSize::from(pos as u32), source); | ||||
|                     let end_pos = | ||||
|                         Position::new(start_pos.line, start_pos.character + text.len() as u32); | ||||
|                     let range = Range::new(start_pos, end_pos); | ||||
|                     Diagnostic::new( | ||||
|                         range, | ||||
|                         DiagnosticSeverity::Error, | ||||
|                         DiagnosticCode::InvalidNumber, | ||||
|                         format!("Invalid number: '{}'", text), | ||||
|                     ) | ||||
|                 } else { | ||||
|                     let range = Range::single_position(Position::new(0, 0)); | ||||
|                     Diagnostic::new( | ||||
|                         range, | ||||
|                         DiagnosticSeverity::Error, | ||||
|                         DiagnosticCode::InvalidNumber, | ||||
|                         format!("Invalid number: '{}'", text), | ||||
|                     ) | ||||
|                 } | ||||
|             LexError::InvalidNumber { position, text } => { | ||||
|                 let start_pos = Position::from_text_size(TextSize::from(*position as u32), source); | ||||
|                 let end_pos = | ||||
|                     Position::new(start_pos.line, start_pos.character + text.len() as u32); | ||||
|                 let range = Range::new(start_pos, end_pos); | ||||
|                 Diagnostic::new( | ||||
|                     range, | ||||
|                     DiagnosticSeverity::Error, | ||||
|                     DiagnosticCode::InvalidNumber, | ||||
|                     format!("Invalid number: '{}'", text), | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										39
									
								
								src/lexer.rs
									
										
									
									
									
								
							
							
						
						
									
										39
									
								
								src/lexer.rs
									
										
									
									
									
								
							|  | @ -10,8 +10,8 @@ pub enum LexError { | |||
|     InvalidToken { position: usize, text: String }, | ||||
|     #[error("Unterminated string literal starting at position {position}")] | ||||
|     UnterminatedString { position: usize }, | ||||
|     #[error("Invalid numeric literal: {text}")] | ||||
|     InvalidNumber { text: String }, | ||||
|     #[error("Invalid numeric literal at position {position}: {text}")] | ||||
|     InvalidNumber { position: usize, text: String }, | ||||
| } | ||||
| 
 | ||||
| /// Result type for lexical analysis
 | ||||
|  | @ -356,6 +356,7 @@ impl<'a> NftablesLexer<'a> { | |||
|                             .any(|c| !c.is_ascii_digit() && c != '.' && c != 'x' && c != 'X') | ||||
|                     { | ||||
|                         return Err(LexError::InvalidNumber { | ||||
|                             position: span.start, | ||||
|                             text: text.to_owned(), | ||||
|                         }); | ||||
|                     } else { | ||||
|  | @ -448,4 +449,38 @@ mod tests { | |||
|             panic!("Expected InvalidToken error"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_invalid_number_with_position() { | ||||
|         // Test that we can create a proper diagnostic with position information
 | ||||
|         use crate::diagnostic::LexicalAnalyzer; | ||||
| 
 | ||||
|         // Create a source with the same invalid pattern at different positions
 | ||||
|         let source = "123abc normal 123abc end"; | ||||
| 
 | ||||
|         // Since normal tokenization splits "123abc" into "123" + "abc",
 | ||||
|         // let's test the diagnostic creation directly with a mock error
 | ||||
|         let error1 = LexError::InvalidNumber { | ||||
|             position: 0, | ||||
|             text: "123abc".to_string(), | ||||
|         }; | ||||
|         let error2 = LexError::InvalidNumber { | ||||
|             position: 14, | ||||
|             text: "123abc".to_string(), | ||||
|         }; | ||||
| 
 | ||||
|         // Test that diagnostics are created with correct positions
 | ||||
|         let diagnostic1 = LexicalAnalyzer::lex_error_to_diagnostic(&error1, source); | ||||
|         let diagnostic2 = LexicalAnalyzer::lex_error_to_diagnostic(&error2, source); | ||||
| 
 | ||||
|         // First occurrence should be at position 0
 | ||||
|         assert_eq!(diagnostic1.range.start.line, 0); | ||||
|         assert_eq!(diagnostic1.range.start.character, 0); | ||||
|         assert_eq!(diagnostic1.message, "Invalid number: '123abc'"); | ||||
| 
 | ||||
|         // Second occurrence should be at position 14 (not 0)
 | ||||
|         assert_eq!(diagnostic2.range.start.line, 0); | ||||
|         assert_eq!(diagnostic2.range.start.character, 14); | ||||
|         assert_eq!(diagnostic2.message, "Invalid number: '123abc'"); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue