git.delta.rocks / jrsonnet / refs/commits / 8885f2169203

difftreelog

feat show full error range instead of just start

sonopmszLach2026-04-04parent: #75beb61.patch.diff
in: master

4 files changed

modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -15,14 +15,9 @@
 };
 
 #[derive(Debug, Clone)]
-pub struct SyntaxErrorLocation {
-	pub offset: usize,
-}
-
-#[derive(Debug, Clone)]
 pub struct SyntaxError {
 	pub message: String,
-	pub location: SyntaxErrorLocation,
+	pub location: (u32, u32),
 }
 impl fmt::Display for SyntaxError {
 	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -50,7 +50,7 @@
 #[cfg(not(any(feature = "ir-parser", feature = "peg-parser")))]
 compile_error!("at least one of `ir-parser` or `peg-parser` features must be enabled");
 
-pub use error::{SyntaxError, SyntaxErrorLocation};
+pub use error::SyntaxError;
 pub use obj::*;
 pub use rustc_hash;
 use rustc_hash::FxHashMap;
@@ -87,9 +87,7 @@
 	jrsonnet_ir_parser::parse(code, &jrsonnet_ir_parser::ParserSettings { source }).map_err(|e| {
 		SyntaxError {
 			message: e.message,
-			location: SyntaxErrorLocation {
-				offset: e.location.offset,
-			},
+			location: (e.location.0, e.location.1),
 		}
 	})
 }
@@ -107,7 +105,7 @@
 						"expected {}, got {:?}",
 						e.expected,
 						code.chars()
-							.nth(e.location.offset)
+							.nth(e.location.0)
 							.map_or_else(|| "EOF".into(), |c: char| c.to_string())
 					)
 				},
@@ -115,9 +113,7 @@
 			);
 		SyntaxError {
 			message,
-			location: SyntaxErrorLocation {
-				offset: e.location.offset,
-			},
+			location: e.location,
 		}
 	})
 }
modifiedcrates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth
122 || path.source_path().to_string(),122 || path.source_path().to_string(),
123 |r| self.resolver.resolve(r),123 |r| self.resolver.resolve(r),
124 );124 );
125 let mut offset = error.location.offset;125 let mut offset = error.location.0 as usize;
126 let is_eof = if offset >= path.code().len() {126 let is_eof = if offset >= path.code().len() {
127 offset = path.code().len().saturating_sub(1);127 offset = path.code().len().saturating_sub(1);
128 true128 true
263 write!(out, "{}", error.error())?;263 write!(out, "{}", error.error())?;
264 if let ErrorKind::ImportSyntaxError { path, error } = error.error() {264 if let ErrorKind::ImportSyntaxError { path, error } = error.error() {
265 writeln!(out)?;265 writeln!(out)?;
266 let offset = error.location.offset;266 let mut offset = error.location;
267 // To inclusive range
268 if offset.1 > offset.0 {
269 offset.1 -= 1;
270 }
267 let mut builder = SnippetBuilder::new(path.code());271 let mut builder = SnippetBuilder::new(path.code());
268 builder272 builder
269 .error(Text::fragment("syntax error", Formatting::default()))273 .error(Text::fragment("syntax error", Formatting::default()))
270 .range(offset..=offset)274 .range(offset.0 as usize..=offset.1 as usize)
271 .build();275 .build();
272 let source = builder.build();276 let source = builder.build();
273 let ansi = source_to_ansi(&source);277 let ansi = source_to_ansi(&source);
modifiedcrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-ir-parser/src/lib.rs
+++ b/crates/jrsonnet-ir-parser/src/lib.rs
@@ -7,21 +7,16 @@
 	ImportKind, IndexPart, LiteralType, Member, ObjBody, ObjComp, ObjMembers, Slice, SliceDesc,
 	Source, Span, Spanned, UnaryOpType, Visibility, unescape,
 };
-use jrsonnet_lexer::{Lexeme, Lexer, SyntaxKind, T, collect_lexed_str_block};
+use jrsonnet_lexer::{Lexeme, Lexer, Span as LexSpan, SyntaxKind, T, collect_lexed_str_block};
 
 pub struct ParserSettings {
 	pub source: Source,
-}
-
-#[derive(Debug, Clone)]
-pub struct ParseErrorLocation {
-	pub offset: usize,
 }
 
 #[derive(Debug, Clone)]
 pub struct ParseError {
 	pub message: String,
-	pub location: ParseErrorLocation,
+	pub location: LexSpan,
 }
 
 impl std::fmt::Display for ParseError {
@@ -131,9 +126,7 @@
 
 	fn error(&self, message: String) -> ParseError {
 		ParseError {
-			location: ParseErrorLocation {
-				offset: self.span_start() as usize,
-			},
+			location: self.lexemes[self.offset].range,
 			message,
 		}
 	}
@@ -143,9 +136,6 @@
 			return Err(self.error(format!("expected identifier, got {}", self.current_desc())));
 		}
 		let text = self.text();
-		if is_reserved(text) {
-			return Err(self.error(format!("expected identifier, got reserved word '{text}'")));
-		}
 		let s: IStr = text.into();
 		self.eat_any();
 		Ok(s)
@@ -156,23 +146,6 @@
 	}
 }
 
-fn is_reserved(s: &str) -> bool {
-	matches!(
-		s,
-		"assert"
-			| "else" | "error"
-			| "false" | "for"
-			| "function"
-			| "if" | "import"
-			| "importstr"
-			| "importbin"
-			| "in" | "local"
-			| "null" | "tailstrict"
-			| "then" | "self"
-			| "super" | "true"
-	)
-}
-
 fn spanned<T: Acyclic>(
 	p: &mut Parser<'_>,
 	cb: impl FnOnce(&mut Parser<'_>) -> Result<T>,
@@ -1040,9 +1013,7 @@
 		if let Some(desc) = lexeme.kind.error_description() {
 			return Err(ParseError {
 				message: desc.to_owned(),
-				location: ParseErrorLocation {
-					offset: lexeme.range.0 as usize,
-				},
+				location: lexeme.range,
 			});
 		}
 	}