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