Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3149180
slots in the condition of template
alanwang67 Jul 29, 2025
4934e51
fixed + added testcases
alanwang67 Jul 29, 2025
e3a96b5
improved comments
alanwang67 Jul 29, 2025
b0e6683
fmt
alanwang67 Jul 29, 2025
41804ab
added has_slot for est & refactored
alanwang67 Jul 30, 2025
4a7e2f5
added missing match arm
alanwang67 Jul 30, 2025
d2967de
added linking with slots in the condition for the EST data structure
alanwang67 Jul 30, 2025
a0436e7
first step
alanwang67 Jul 30, 2025
85e8dd5
adding a new field to Policy
alanwang67 Jul 31, 2025
0b23d86
removed repeated line
alanwang67 Jul 31, 2025
73da541
typechecker + parser + tests + evaluator
alanwang67 Jul 31, 2025
30c18df
added api functions + est format
alanwang67 Aug 1, 2025
3f40da2
updates to naming
alanwang67 Aug 1, 2025
e35cac5
more naming changes
alanwang67 Aug 1, 2025
48ad73c
changes
alanwang67 Aug 1, 2025
2616a35
naming changes
alanwang67 Aug 5, 2025
c458e3e
fixed typo
alanwang67 Aug 5, 2025
d279fa6
changed display
alanwang67 Aug 7, 2025
8e725ec
use only one field for values of slots
alanwang67 Aug 7, 2025
5913651
updates to use restricted expr as type for slots for EST format
alanwang67 Aug 8, 2025
d83ee15
Revert "changes"
alanwang67 Aug 8, 2025
92f3c36
Revert "Revert "changes""
alanwang67 Aug 8, 2025
4b4ed2a
Revert "updates to use restricted expr as type for slots for EST format"
alanwang67 Aug 8, 2025
905db6c
Revert "Revert "updates to use restricted expr as type for slots for …
alanwang67 Aug 8, 2025
15c1804
Revert "Revert "Revert "changes"""
alanwang67 Aug 8, 2025
613d171
Revert "Revert "changes""
alanwang67 Aug 8, 2025
bb0b339
Revert "updates to use restricted expr as type for slots for EST format"
alanwang67 Aug 8, 2025
bd272da
Revert "use only one field for values of slots"
alanwang67 Aug 8, 2025
c86dd88
validate incorrect entity types in generalized slots + removed confus…
alanwang67 Aug 8, 2025
c855f82
Merge branch 'generalized_templates_branch' into generalized_template…
alanwang67 Aug 8, 2025
6ddfce1
changed API so we do not need to provide two hashmap's
alanwang67 Aug 8, 2025
10c245e
fixed test cases for experimental features
alanwang67 Aug 11, 2025
3887b34
included better comment
alanwang67 Aug 12, 2025
7bd456a
changed name for generalized_slots_declaration because it was mislead
alanwang67 Aug 13, 2025
edbc791
moved checking if there is no type annotation to validation and made …
alanwang67 Aug 15, 2025
64483b7
cleaned up repeated code
alanwang67 Aug 15, 2025
df8bdba
case for without schemas
alanwang67 Aug 15, 2025
65a62a3
test cases
alanwang67 Aug 15, 2025
d733e9d
removed redundant line
alanwang67 Aug 15, 2025
1433581
fixed inconsistency
alanwang67 Aug 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cedar-language-server/src/schema/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub(crate) fn fold_schema(schema_info: &SchemaInfo) -> Option<Vec<FoldingRange>>
.filter_map(|et| et.loc.as_loc_ref());
let action_locs = validator.action_ids().filter_map(|a| a.loc());
let common_types = validator
.common_types()
.common_types_extended()
.filter_map(|ct| ct.type_loc.as_loc_ref());

// Combine all locations and create folding ranges
Expand Down
2 changes: 1 addition & 1 deletion cedar-language-server/src/schema/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub(crate) fn schema_symbols(schema_info: &SchemaInfo) -> Option<Vec<DocumentSym

// Create common type symbols
let common_type_symbols: Vec<DocumentSymbol> = validator
.common_types()
.common_types_extended()
.filter_map(|ct| {
ct.name_loc
.as_ref()
Expand Down
1 change: 1 addition & 0 deletions cedar-policy-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ wasm = ["serde-wasm-bindgen", "tsify", "wasm-bindgen"]
experimental = ["tpe", "tolerant-ast", "extended-schema", "entity-manifest", "partial-validate", "partial-eval"]
extended-schema = []
tpe = []
generalized-templates = []

# Feature for raw parsing
raw-parsing = []
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 @@ -54,5 +54,7 @@ mod expr_iterator;
pub use expr_iterator::*;
mod annotation;
pub use annotation::*;
mod slots_type_declaration;
pub use slots_type_declaration::*;
mod expr_visitor;
pub use expr_visitor::*;
18 changes: 16 additions & 2 deletions cedar-policy-core/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,27 @@ impl<T> Expr<T> {
self.subexpressions()
.filter_map(|exp| match &exp.expr_kind {
ExprKind::Slot(slotid) => Some(Slot {
id: *slotid,
id: slotid.clone(),
loc: exp.source_loc().into_maybe_loc(),
}),
_ => None,
})
}

/// Iterate over all of the principal and resource slots in this policy AST
pub fn principal_and_resource_slots(&self) -> impl Iterator<Item = Slot> + '_ {
self.subexpressions()
.filter_map(|exp| match &exp.expr_kind {
ExprKind::Slot(slotid) if slotid.is_principal() || slotid.is_resource() => {
Some(Slot {
id: slotid.clone(),
loc: exp.source_loc().into_maybe_loc(),
})
}
_ => None,
})
}

/// Determine if the expression is projectable under partial evaluation
/// An expression is projectable if it's guaranteed to never error on evaluation
/// This is true if the expression is entirely composed of values or unknowns
Expand Down Expand Up @@ -1842,7 +1856,7 @@ mod test {
let e = Expr::slot(SlotId::principal());
let p = SlotId::principal();
let r = SlotId::resource();
let set: HashSet<SlotId> = HashSet::from_iter([p]);
let set: HashSet<SlotId> = HashSet::from_iter([p.clone()]);
assert_eq!(set, e.slots().map(|slot| slot.id).collect::<HashSet<_>>());
let e = Expr::or(
Expr::slot(SlotId::principal()),
Expand Down
2 changes: 1 addition & 1 deletion cedar-policy-core/src/ast/expr_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub trait ExprVisitor {
match expr.expr_kind() {
ExprKind::Lit(lit) => self.visit_literal(lit, loc),
ExprKind::Var(var) => self.visit_var(*var, loc),
ExprKind::Slot(slot) => self.visit_slot(*slot, loc),
ExprKind::Slot(slot) => self.visit_slot(slot.clone(), loc),
ExprKind::Unknown(unknown) => self.visit_unknown(unknown, loc),
ExprKind::If {
test_expr,
Expand Down
54 changes: 41 additions & 13 deletions cedar-policy-core/src/ast/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use miette::Diagnostic;
use ref_cast::RefCast;
use regex::Regex;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_with::{serde_as, DisplayFromStr};
use smol_str::ToSmolStr;
use std::collections::HashSet;
use std::fmt::Display;
Expand Down Expand Up @@ -283,9 +284,10 @@ impl<'de> Deserialize<'de> for InternalName {
/// Clone is O(1).
// This simply wraps a separate enum -- currently [`ValidSlotId`] -- in case we
// want to generalize later
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde_as]
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct SlotId(pub(crate) ValidSlotId);
pub struct SlotId(#[serde_as(as = "DisplayFromStr")] pub(crate) ValidSlotId);

impl SlotId {
/// Get the slot for `principal`
Expand All @@ -298,6 +300,11 @@ impl SlotId {
Self(ValidSlotId::Resource)
}

/// Create a `generalized slot`
pub fn generalized_slot(id: Id) -> Self {
Self(ValidSlotId::GeneralizedSlot(id))
}

/// Check if a slot represents a principal
pub fn is_principal(&self) -> bool {
matches!(self, Self(ValidSlotId::Principal))
Expand All @@ -307,6 +314,11 @@ impl SlotId {
pub fn is_resource(&self) -> bool {
matches!(self, Self(ValidSlotId::Resource))
}

/// Check if a slot represents a generalized slot
pub fn is_generalized_slot(&self) -> bool {
matches!(self, Self(ValidSlotId::GeneralizedSlot(_)))
}
}

impl From<PrincipalOrResource> for SlotId {
Expand All @@ -318,28 +330,44 @@ impl From<PrincipalOrResource> for SlotId {
}
}

impl std::fmt::Display for ValidSlotId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
ValidSlotId::Principal => "principal",
ValidSlotId::Resource => "resource",
ValidSlotId::GeneralizedSlot(id) => id.as_ref(),
};
write!(f, "?{s}")
}
}

impl FromStr for SlotId {
type Err = ParseErrors;

fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse().map(SlotId)
}
}

impl std::fmt::Display for SlotId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

/// Two possible variants for Slots
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
/// Three possible variants for Slots
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub(crate) enum ValidSlotId {
#[serde(rename = "?principal")]
Principal,
#[serde(rename = "?resource")]
Resource,
GeneralizedSlot(Id), // Slots for generalized templates, for more info see [RFC 98](https://github.com/cedar-policy/rfcs/pull/98).
}

impl std::fmt::Display for ValidSlotId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
ValidSlotId::Principal => "principal",
ValidSlotId::Resource => "resource",
};
write!(f, "?{s}")
impl FromStr for ValidSlotId {
type Err = ParseErrors;

fn from_str(s: &str) -> Result<Self, Self::Err> {
crate::parser::parse_slot(s)
}
}

Expand Down
Loading