difftreelog
feat allow both parsers at the same time
in: master
4 files changed
crates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth18explaining-traces = ["annotate-snippets", "hi-doc"]18explaining-traces = ["annotate-snippets", "hi-doc"]19# Allows library authors to throw custom errors19# Allows library authors to throw custom errors20anyhow-error = ["anyhow"]20anyhow-error = ["anyhow"]21# Use hand-written recursive descent parser instead of PEG parser21# Use hand-written recursive descent parser22ir-parser = ["dep:jrsonnet-ir-parser"]22ir-parser = ["dep:jrsonnet-ir-parser"]23# Use PEG parser24peg-parser = ["dep:jrsonnet-peg-parser"]232524# Allows to preserve field order in objects26# Allows to preserve field order in objects25exp-preserve-order = []27exp-preserve-order = []26# Implements field destructuring28# Implements field destructuring27exp-destruct = ["jrsonnet-peg-parser/exp-destruct"]29exp-destruct = ["jrsonnet-peg-parser?/exp-destruct", "jrsonnet-ir-parser?/exp-destruct"]28# Iteration over objects yields [key, value] elements30# Iteration over objects yields [key, value] elements29exp-object-iteration = []31exp-object-iteration = []30# Bigint type32# Bigint type31exp-bigint = ["num-bigint", "jrsonnet-types/exp-bigint"]33exp-bigint = ["num-bigint", "jrsonnet-types/exp-bigint"]32# obj?.field, obj?.['field']34# obj?.field, obj?.['field']33exp-null-coaelse = ["jrsonnet-peg-parser/exp-null-coaelse", "jrsonnet-ir-parser?/exp-null-coaelse"]35exp-null-coaelse = ["jrsonnet-peg-parser?/exp-null-coaelse", "jrsonnet-ir-parser?/exp-null-coaelse"]343635[dependencies]37[dependencies]36jrsonnet-interner.workspace = true38jrsonnet-interner.workspace = true37jrsonnet-ir.workspace = true39jrsonnet-ir.workspace = true38jrsonnet-peg-parser.workspace = true40jrsonnet-peg-parser = { workspace = true, optional = true }39jrsonnet-ir-parser = { workspace = true, optional = true }41jrsonnet-ir-parser = { workspace = true, optional = true }40jrsonnet-types.workspace = true42jrsonnet-types.workspace = true41jrsonnet-macros.workspace = true43jrsonnet-macros.workspace = truecrates/jrsonnet-evaluator/src/async_import.rsdiffbeforeafterboth7 FieldMember, FieldName, ForSpecData, IfElse, IfSpecData, ImportKind, ObjBody, Slice, SliceDesc,7 FieldMember, FieldName, ForSpecData, IfElse, IfSpecData, ImportKind, ObjBody, Slice, SliceDesc,8 Source, SourcePath, Spanned,8 Source, SourcePath, Spanned,9};9};10#[cfg(feature = "ir-parser")]11use jrsonnet_ir_parser::ParserSettings;12#[cfg(not(feature = "ir-parser"))]13use jrsonnet_peg_parser::ParserSettings;14use rustc_hash::FxHashMap;10use rustc_hash::FxHashMap;151116use crate::{AsPathLike, FileData, ImportResolver, ResolvePathOwned, State};12use crate::{AsPathLike, FileData, ImportResolver, ResolvePathOwned, State};326 };322 };327 let source = Source::new(path.clone(), code.clone());323 let source = Source::new(path.clone(), code.clone());328 // If failed - then skip import324 // If failed - then skip import329 file.parsed = crate::parse_jsonnet(&code, &ParserSettings { source })325 file.parsed = crate::parse_jsonnet(&code, source)330 .map(Rc::new)326 .map(Rc::new)331 .ok();327 .ok();332 if let Some(parsed) = &file.parsed {328 if let Some(parsed) = &file.parsed {crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth14 ObjValue, ResolvePathOwned,14 ObjValue, ResolvePathOwned,15};15};1617#[derive(Debug, Clone)]18pub struct SyntaxErrorLocation {19 pub offset: usize,20}2122#[derive(Debug, Clone)]23pub struct SyntaxError {24 pub message: String,25 pub location: SyntaxErrorLocation,26}27impl fmt::Display for SyntaxError {28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {29 write!(f, "{}", self.message)30 }31}163217pub(crate) fn format_found(list: &[IStr], what: &str) -> String {33pub(crate) fn format_found(list: &[IStr], what: &str) -> String {18 if list.is_empty() {34 if list.is_empty() {154 ImportNotSupported(SourcePath, ResolvePathOwned),170 ImportNotSupported(SourcePath, ResolvePathOwned),155 #[error("can't import from virtual file")]171 #[error("can't import from virtual file")]156 CantImportFromVirtualFile,172 CantImportFromVirtualFile,157 #[cfg(not(feature = "ir-parser"))]158 #[error(159 "syntax error: {}",160 // Peg has no fancier way to handle critical parsing errors https://github.com/kevinmehall/rust-peg/issues/225161 {.error.expected.tokens().find(|t| t.starts_with("!!!")).map_or_else(|| {162 format!(163 "expected {}, got {:?}",164 .error.expected,165 .path.code().chars().nth(error.location.offset)166 .map_or_else(|| "EOF".into(), |c| c.to_string())167 )168 }, |v| v[3..].into())}169 )]170 ImportSyntaxError {171 path: Source,172 #[trace(skip)]173 error: Box<jrsonnet_peg_parser::ParseError>,174 },175176 #[cfg(feature = "ir-parser")]177 #[error("syntax error: {error}")]173 #[error("syntax error: {error}")]178 ImportSyntaxError {174 ImportSyntaxError {179 path: Source,175 path: Source,180 #[trace(skip)]176 #[trace(skip)]181 error: Box<jrsonnet_ir_parser::ParseError>,177 error: Box<SyntaxError>,182 },178 },183179184 #[error("runtime error: {}", format_empty_str(.0))]180 #[error("runtime error: {}", format_empty_str(.0))]crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth47#[doc(hidden)]47#[doc(hidden)]48pub use jrsonnet_macros;48pub use jrsonnet_macros;4949#[cfg(feature = "ir-parser")]50#[cfg(not(any(feature = "ir-parser", feature = "peg-parser")))]50use jrsonnet_ir_parser::ParserSettings;51compile_error!("at least one of `ir-parser` or `peg-parser` features must be enabled");51#[cfg(not(feature = "ir-parser"))]5252use jrsonnet_peg_parser::ParserSettings;53pub use error::{SyntaxError, SyntaxErrorLocation};53pub use obj::*;54pub use obj::*;54pub use rustc_hash;55pub use rustc_hash;55use rustc_hash::FxHashMap;56use rustc_hash::FxHashMap;596060use crate::gc::WithCapacityExt as _;61use crate::gc::WithCapacityExt as _;6263pub(crate) fn parse_jsonnet(code: &str, source: Source) -> Result<Expr, SyntaxError> {64 #[cfg(all(feature = "ir-parser", feature = "peg-parser"))]65 {66 if std::env::var_os("JRSONNET_LEGACY_PARSER").is_some() {67 return parse_peg(code, source);68 }69 return parse_ir(code, source);70 }71 #[cfg(all(feature = "ir-parser", not(feature = "peg-parser")))]72 {73 return parse_ir(code, source);74 }75 #[cfg(all(feature = "peg-parser", not(feature = "ir-parser")))]76 {77 return parse_peg(code, source);78 }79}618062#[cfg(feature = "ir-parser")]81#[cfg(feature = "ir-parser")]63pub(crate) fn parse_jsonnet(82fn parse_ir(code: &str, source: Source) -> Result<Expr, SyntaxError> {64 code: &str,65 settings: &ParserSettings,66) -> Result<Expr, jrsonnet_ir_parser::ParseError> {67 jrsonnet_ir_parser::parse(code, settings)83 jrsonnet_ir_parser::parse(code, &jrsonnet_ir_parser::ParserSettings { source }).map_err(84 |e| SyntaxError {85 message: e.message,86 location: SyntaxErrorLocation {87 offset: e.location.offset,88 },89 },90 )68}91}699270#[cfg(not(feature = "ir-parser"))]93#[cfg(feature = "peg-parser")]71pub(crate) fn parse_jsonnet(94fn parse_peg(code: &str, source: Source) -> Result<Expr, SyntaxError> {72 code: &str,73 settings: &ParserSettings,74) -> Result<Expr, jrsonnet_peg_parser::ParseError> {75 jrsonnet_peg_parser::parse(code, settings)95 jrsonnet_peg_parser::parse(code, &jrsonnet_peg_parser::ParserSettings { source }).map_err(96 |e| {97 let message = e98 .expected99 .tokens()100 .find(|t| t.starts_with("!!!"))101 .map_or_else(102 || {103 format!(104 "expected {}, got {:?}",105 e.expected,106 code.chars()107 .nth(e.location.offset)108 .map_or_else(|| "EOF".into(), |c: char| c.to_string())109 )110 },111 |v| v[3..].into(),112 );113 SyntaxError {114 message,115 location: SyntaxErrorLocation {116 offset: e.location.offset,117 },118 }119 },120 )76}121}7712278cc_dyn!(123cc_dyn!(366 file.parsed = Some(411 file.parsed = Some(367 parse_jsonnet(412 parse_jsonnet(&code, file_name.clone())368 &code,369 &ParserSettings {370 source: file_name.clone(),371 },372 )373 .map(Rc::new)413 .map(Rc::new)374 .map_err(|e| ImportSyntaxError {414 .map_err(|e| ImportSyntaxError {482 let source = Source::new_virtual(name.into(), code.clone());522 let source = Source::new_virtual(name.into(), code.clone());483 let parsed = parse_jsonnet(523 let parsed = parse_jsonnet(&code, source.clone())484 &code,485 &ParserSettings {486 source: source.clone(),487 },488 )489 .map_err(|e| ImportSyntaxError {524 .map_err(|e| ImportSyntaxError {490 path: source.clone(),525 path: source.clone(),503 let source = Source::new_virtual(name.into(), code.clone());538 let source = Source::new_virtual(name.into(), code.clone());504 let parsed = parse_jsonnet(539 let parsed = parse_jsonnet(&code, source.clone())505 &code,506 &ParserSettings {507 source: source.clone(),508 },509 )510 .map_err(|e| ImportSyntaxError {540 .map_err(|e| ImportSyntaxError {511 path: source.clone(),541 path: source.clone(),