Skip to content

Commit d9a9a60

Browse files
committed
Add width to compiler error messages
1 parent d3d311d commit d9a9a60

File tree

6 files changed

+331
-240
lines changed

6 files changed

+331
-240
lines changed

src/editor/server.rs

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -396,132 +396,137 @@ impl TechniqueLanguageServer {
396396

397397
for error in errors {
398398
let offset = error.offset();
399-
let position = offset_to_position(content, offset);
399+
let width = error.width();
400+
let start_position = offset_to_position(content, offset);
401+
let end_position = if width > 0 {
402+
offset_to_position(content, offset + width)
403+
} else {
404+
start_position // Fallback to single character if width is unknown
405+
};
406+
let range = Range {
407+
start: start_position,
408+
end: end_position,
409+
};
400410

401411
let (message, severity) = match &error {
402-
ParsingError::IllegalParserState(_) => (
412+
ParsingError::IllegalParserState(_, _) => (
403413
"Internal parser error".to_string(),
404414
DiagnosticSeverity::ERROR,
405415
),
406-
ParsingError::Unimplemented(_) => (
416+
ParsingError::Unimplemented(_, _) => (
407417
"Unimplemented feature".to_string(),
408418
DiagnosticSeverity::WARNING,
409419
),
410-
ParsingError::Unrecognized(_) => {
420+
ParsingError::Unrecognized(_, _) => {
411421
("Unrecognized syntax".to_string(), DiagnosticSeverity::ERROR)
412422
}
413-
ParsingError::UnexpectedEndOfInput(_) => (
423+
ParsingError::UnexpectedEndOfInput(_, _) => (
414424
"Unexpected end of input".to_string(),
415425
DiagnosticSeverity::ERROR,
416426
),
417-
ParsingError::Expected(_, expected) => {
427+
ParsingError::Expected(_, _, expected) => {
418428
(format!("Expected {}", expected), DiagnosticSeverity::ERROR)
419429
}
420-
ParsingError::ExpectedMatchingChar(_, subject, start, end) => (
430+
ParsingError::ExpectedMatchingChar(_, _, subject, start, end) => (
421431
format!("Expected matching '{}' for '{}' in {}", end, start, subject),
422432
DiagnosticSeverity::ERROR,
423433
),
424-
ParsingError::MissingParenthesis(_) => (
434+
ParsingError::MissingParenthesis(_, _) => (
425435
"Require parenthesis around multiple parameters in binding".to_string(),
426436
DiagnosticSeverity::ERROR,
427437
),
428-
ParsingError::InvalidCharacter(_, ch) => (
438+
ParsingError::InvalidCharacter(_, _, ch) => (
429439
format!("Invalid character '{}'", ch),
430440
DiagnosticSeverity::ERROR,
431441
),
432-
ParsingError::InvalidHeader(_) => {
442+
ParsingError::InvalidHeader(_, _) => {
433443
("Invalid header line".to_string(), DiagnosticSeverity::ERROR)
434444
}
435-
ParsingError::InvalidIdentifier(_, id) => (
445+
ParsingError::InvalidIdentifier(_, _, id) => (
436446
format!("Invalid identifier '{}'", id),
437447
DiagnosticSeverity::ERROR,
438448
),
439-
ParsingError::InvalidForma(_) => (
449+
ParsingError::InvalidForma(_, _) => (
440450
"Invalid forma in signature".to_string(),
441451
DiagnosticSeverity::ERROR,
442452
),
443-
ParsingError::InvalidGenus(_) => (
453+
ParsingError::InvalidGenus(_, _) => (
444454
"Invalid genus in signature".to_string(),
445455
DiagnosticSeverity::ERROR,
446456
),
447-
ParsingError::InvalidSignature(_) => (
457+
ParsingError::InvalidSignature(_, _) => (
448458
"Invalid signature in procedure declaration".to_string(),
449459
DiagnosticSeverity::ERROR,
450460
),
451-
ParsingError::InvalidParameters(_) => (
461+
ParsingError::InvalidParameters(_, _) => (
452462
"Malformed parameters in procedure declaration".to_string(),
453463
DiagnosticSeverity::ERROR,
454464
),
455-
ParsingError::InvalidDeclaration(_) => (
465+
ParsingError::InvalidDeclaration(_, _) => (
456466
"Invalid procedure declaration".to_string(),
457467
DiagnosticSeverity::ERROR,
458468
),
459-
ParsingError::InvalidSection(_) => (
469+
ParsingError::InvalidSection(_, _) => (
460470
"Invalid section heading".to_string(),
461471
DiagnosticSeverity::ERROR,
462472
),
463-
ParsingError::InvalidInvocation(_) => (
473+
ParsingError::InvalidInvocation(_, _) => (
464474
"Invalid procedure Invocation".to_string(),
465475
DiagnosticSeverity::ERROR,
466476
),
467-
ParsingError::InvalidFunction(_) => (
477+
ParsingError::InvalidFunction(_, _) => (
468478
"Invalid function call".to_string(),
469479
DiagnosticSeverity::ERROR,
470480
),
471-
ParsingError::InvalidCodeBlock(_) => {
481+
ParsingError::InvalidCodeBlock(_, _) => {
472482
("Invalid code block".to_string(), DiagnosticSeverity::ERROR)
473483
}
474-
ParsingError::InvalidStep(_) => {
484+
ParsingError::InvalidStep(_, _) => {
475485
("Invalid step".to_string(), DiagnosticSeverity::ERROR)
476486
}
477-
ParsingError::InvalidSubstep(_) => {
487+
ParsingError::InvalidSubstep(_, _) => {
478488
("Invalid substep".to_string(), DiagnosticSeverity::ERROR)
479489
}
480-
ParsingError::InvalidResponse(_) => {
490+
ParsingError::InvalidResponse(_, _) => {
481491
("Invalid response".to_string(), DiagnosticSeverity::ERROR)
482492
}
483-
ParsingError::InvalidMultiline(_) => (
493+
ParsingError::InvalidMultiline(_, _) => (
484494
"Invalid multiline content".to_string(),
485495
DiagnosticSeverity::ERROR,
486496
),
487-
ParsingError::InvalidForeach(_) => (
497+
ParsingError::InvalidForeach(_, _) => (
488498
"Invalid foreach expression".to_string(),
489499
DiagnosticSeverity::ERROR,
490500
),
491-
ParsingError::InvalidIntegral(_) => (
501+
ParsingError::InvalidIntegral(_, _) => (
492502
"Invalid integral number".to_string(),
493503
DiagnosticSeverity::ERROR,
494504
),
495-
ParsingError::InvalidQuantity(_) => {
505+
ParsingError::InvalidQuantity(_, _) => {
496506
("Invalid quantity".to_string(), DiagnosticSeverity::ERROR)
497507
}
498-
ParsingError::InvalidQuantityDecimal(_) => (
508+
ParsingError::InvalidQuantityDecimal(_, _) => (
499509
"Invalid quantity decimal".to_string(),
500510
DiagnosticSeverity::ERROR,
501511
),
502-
ParsingError::InvalidQuantityUncertainty(_) => (
512+
ParsingError::InvalidQuantityUncertainty(_, _) => (
503513
"Invalid quantity uncertainty".to_string(),
504514
DiagnosticSeverity::ERROR,
505515
),
506-
ParsingError::InvalidQuantityMagnitude(_) => (
516+
ParsingError::InvalidQuantityMagnitude(_, _) => (
507517
"Invalid quantity magnitude".to_string(),
508518
DiagnosticSeverity::ERROR,
509519
),
510-
ParsingError::InvalidQuantitySymbol(_) => (
520+
ParsingError::InvalidQuantitySymbol(_, _) => (
511521
"Invalid quantity symbol".to_string(),
512522
DiagnosticSeverity::ERROR,
513523
),
514-
ParsingError::UnclosedInterpolation(_) => (
524+
ParsingError::UnclosedInterpolation(_, _) => (
515525
"Unclosed interpolation".to_string(),
516526
DiagnosticSeverity::ERROR,
517527
),
518528
};
519529

520-
let range = Range {
521-
start: position,
522-
end: position, // For now, just point to the error position
523-
};
524-
525530
let diagnostic = Diagnostic {
526531
range,
527532
severity: Some(severity),
@@ -597,17 +602,17 @@ mod tests {
597602
fn test_parsing_error_types() {
598603
// Test that all error types can be converted to messages without panicking
599604
let test_errors = vec![
600-
ParsingError::IllegalParserState(0),
601-
ParsingError::Unimplemented(0),
602-
ParsingError::Unrecognized(0),
603-
ParsingError::UnexpectedEndOfInput(0),
604-
ParsingError::Expected(0, "test"),
605-
ParsingError::ExpectedMatchingChar(0, "test", '(', ')'),
606-
ParsingError::MissingParenthesis(0),
607-
ParsingError::InvalidCharacter(0, 'x'),
608-
ParsingError::InvalidHeader(0),
609-
ParsingError::InvalidIdentifier(0, "test".to_string()),
610-
ParsingError::InvalidDeclaration(0),
605+
ParsingError::IllegalParserState(0, 0),
606+
ParsingError::Unimplemented(0, 0),
607+
ParsingError::Unrecognized(0, 0),
608+
ParsingError::UnexpectedEndOfInput(0, 0),
609+
ParsingError::Expected(0, 0, "test"),
610+
ParsingError::ExpectedMatchingChar(0, 0, "test", '(', ')'),
611+
ParsingError::MissingParenthesis(0, 0),
612+
ParsingError::InvalidCharacter(0, 0, 'x'),
613+
ParsingError::InvalidHeader(0, 0),
614+
ParsingError::InvalidIdentifier(0, 0, "test".to_string()),
615+
ParsingError::InvalidDeclaration(0, 0),
611616
];
612617

613618
// This shouldn't panic - just test that all enum variants are handled
@@ -617,25 +622,25 @@ mod tests {
617622

618623
// Test message generation (this was formerly in convert_parsing_errors)
619624
match &error {
620-
ParsingError::IllegalParserState(_) => {
625+
ParsingError::IllegalParserState(_, _) => {
621626
assert_eq!("Internal parser error", "Internal parser error")
622627
}
623-
ParsingError::Unimplemented(_) => {
628+
ParsingError::Unimplemented(_, _) => {
624629
assert_eq!("Unimplemented feature", "Unimplemented feature")
625630
}
626-
ParsingError::Unrecognized(_) => {
631+
ParsingError::Unrecognized(_, _) => {
627632
assert_eq!("Unrecognized syntax", "Unrecognized syntax")
628633
}
629-
ParsingError::UnexpectedEndOfInput(_) => {
634+
ParsingError::UnexpectedEndOfInput(_, _) => {
630635
assert_eq!("Unexpected end of input", "Unexpected end of input")
631636
}
632-
ParsingError::Expected(_, expected) => assert_eq!(*expected, "test"),
633-
ParsingError::ExpectedMatchingChar(_, subject, start, end) => {
637+
ParsingError::Expected(_, _, expected) => assert_eq!(*expected, "test"),
638+
ParsingError::ExpectedMatchingChar(_, _, subject, start, end) => {
634639
assert_eq!(*subject, "test");
635640
assert_eq!(*start, '(');
636641
assert_eq!(*end, ')');
637642
}
638-
ParsingError::InvalidDeclaration(_) => {
643+
ParsingError::InvalidDeclaration(_, _) => {
639644
assert_eq!("Invalid declaration", "Invalid declaration")
640645
}
641646
_ => {} // Other variants tested implicitly

0 commit comments

Comments
 (0)