Skip to content

Commit

Permalink
Allow error expressions in AST and handle empty When error (#1470)
Browse files Browse the repository at this point in the history
Signed-off-by: Jonathan Eidelman <jeid@amazon.com>
Co-authored-by: Craig Disselkoen <craigdissel@gmail.com>
  • Loading branch information
eidelmanjonathan and cdisselkoen authored Feb 21, 2025
1 parent b5d2eee commit 9f6d06c
Show file tree
Hide file tree
Showing 25 changed files with 977 additions and 32 deletions.
1 change: 1 addition & 0 deletions cedar-policy-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ test-util = []

# Experimental features.
partial-eval = []
tolerant-ast = []
wasm = ["serde-wasm-bindgen", "tsify", "wasm-bindgen"]

[build-dependencies]
Expand Down
2 changes: 2 additions & 0 deletions cedar-policy-core/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
//! This module contains the AST datatypes.
mod expr;
#[cfg(feature = "tolerant-ast")]
pub(crate) mod expr_allows_errors;
pub use expr::*;
mod entity;
pub use entity::*;
Expand Down
25 changes: 24 additions & 1 deletion cedar-policy-core/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

#[cfg(feature = "tolerant-ast")]
use super::expr_allows_errors::AstExprErrorKind;
use crate::{
ast::*,
expr_builder::{self, ExprBuilder as _},
Expand Down Expand Up @@ -155,6 +157,12 @@ pub enum ExprKind<T = ()> {
Set(Arc<Vec<Expr<T>>>),
/// Anonymous record (whose elements may be arbitrary expressions)
Record(Arc<BTreeMap<SmolStr, Expr<T>>>),
#[cfg(feature = "tolerant-ast")]
/// Error expression - allows us to continue parsing even when we have errors
Error {
/// Type of error that led to the failure
error_kind: AstExprErrorKind,
},
}

impl From<Value> for Expr {
Expand Down Expand Up @@ -191,7 +199,7 @@ impl From<PartialValue> for Expr {
}

impl<T> Expr<T> {
fn new(expr_kind: ExprKind<T>, source_loc: Option<Loc>, data: T) -> Self {
pub(crate) fn new(expr_kind: ExprKind<T>, source_loc: Option<Loc>, data: T) -> Self {
Self {
expr_kind,
source_loc,
Expand Down Expand Up @@ -385,6 +393,8 @@ impl<T> Expr<T> {
ExprKind::Is { .. } => Some(Type::Bool),
ExprKind::Set(_) => Some(Type::Set),
ExprKind::Record(_) => Some(Type::Record),
#[cfg(feature = "tolerant-ast")]
ExprKind::Error { .. } => None,
}
}
}
Expand Down Expand Up @@ -717,6 +727,8 @@ impl Expr {
expr.substitute_general::<T>(definitions)?,
entity_type.clone(),
)),
#[cfg(feature = "tolerant-ast")]
ExprKind::Error { .. } => Ok(self.clone()),
}
}
}
Expand Down Expand Up @@ -857,6 +869,9 @@ impl<T: Default + Clone> expr_builder::ExprBuilder for ExprBuilder<T> {

type Data = T;

#[cfg(feature = "tolerant-ast")]
type ErrorType = ParseErrors;

fn loc(&self) -> Option<&Loc> {
self.source_loc.as_ref()
}
Expand Down Expand Up @@ -1168,6 +1183,12 @@ impl<T: Default + Clone> expr_builder::ExprBuilder for ExprBuilder<T> {
entity_type,
})
}

/// Don't support AST Error nodes - return the error right back
#[cfg(feature = "tolerant-ast")]
fn error(self, parse_errors: ParseErrors) -> Result<Self::Expr, Self::ErrorType> {
Err(parse_errors)
}
}

impl<T> ExprBuilder<T> {
Expand Down Expand Up @@ -1482,6 +1503,8 @@ impl<T> Expr<T> {
expr.hash_shape(state);
entity_type.hash(state);
}
#[cfg(feature = "tolerant-ast")]
ExprKind::Error { error_kind, .. } => error_kind.hash(state),
}
}
}
Expand Down
Loading

0 comments on commit 9f6d06c

Please sign in to comment.