-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Documentation, refactoring and convenience (#123)
## What Changed? Moves the annotations into `paralegal-flow` Provides basic documentation for `paralegal-spdg` Now requires documentation for `paralegal-spdg` in CI Adds convenience functions to `Context` ## Why Does It Need To? Adds convenience methods to `Context` to improve ergonomics of the policies. Adds missing documentation to the spdg crate also now enables the missing documentation warning, which makes it an error in CI. The annotations are moved because they aren't in the SPDG anyway and thus not accessible to consumers in this form. ## Checklist - [x] Above description has been filled out so that upon quash merge we have a good record of what changed. - [x] New functions, methods, types are documented. Old documentation is updated if necessary - [x] Documentation in Notion has been updated - [x] Tests for new behaviors are provided - [x] New test suites (if any) ave been added to the CI tests (in `.github/workflows/rust.yml`) either as compiler test or integration test. *Or* justification for their omission from CI has been provided in this PR description.
- Loading branch information
1 parent
33d2a8f
commit ff2601d
Showing
14 changed files
with
316 additions
and
169 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use paralegal_spdg::{rustc_proxies, tiny_bitset_pretty, Identifier, TinyBitSet, TypeId}; | ||
|
||
pub mod parse; | ||
|
||
/// Types of annotations we support. | ||
/// | ||
/// Usually you'd expect one of those annotation types in any given situation. | ||
/// For convenience the match methods [`Self::as_marker`], [`Self::as_otype`] | ||
/// and [`Self::as_exception`] are provided. These are particularly useful in | ||
/// conjunction with e.g. [`Iterator::filter_map`] | ||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Deserialize, Serialize, strum::EnumIs)] | ||
pub enum Annotation { | ||
Marker(MarkerAnnotation), | ||
OType(#[serde(with = "rustc_proxies::DefId")] TypeId), | ||
Exception(ExceptionAnnotation), | ||
} | ||
|
||
impl Annotation { | ||
/// If this is an [`Annotation::Marker`], returns the underlying [`MarkerAnnotation`]. | ||
pub fn as_marker(&self) -> Option<&MarkerAnnotation> { | ||
match self { | ||
Annotation::Marker(l) => Some(l), | ||
_ => None, | ||
} | ||
} | ||
|
||
/// If this is an [`Annotation::OType`], returns the underlying [`TypeId`]. | ||
pub fn as_otype(&self) -> Option<TypeId> { | ||
match self { | ||
Annotation::OType(t) => Some(*t), | ||
_ => None, | ||
} | ||
} | ||
|
||
/// If this is an [`Annotation::Exception`], returns the underlying [`ExceptionAnnotation`]. | ||
pub fn as_exception(&self) -> Option<&ExceptionAnnotation> { | ||
match self { | ||
Annotation::Exception(e) => Some(e), | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
pub type VerificationHash = u128; | ||
|
||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Serialize, Deserialize)] | ||
pub struct ExceptionAnnotation { | ||
/// The value of the verification hash we found in the annotation. Is `None` | ||
/// if there was no verification hash in the annotation. | ||
pub verification_hash: Option<VerificationHash>, | ||
} | ||
|
||
/// A marker annotation and its refinements. | ||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Serialize, Deserialize)] | ||
pub struct MarkerAnnotation { | ||
/// The (unchanged) name of the marker as provided by the user | ||
pub marker: Identifier, | ||
#[serde(flatten)] | ||
pub refinement: MarkerRefinement, | ||
} | ||
|
||
fn const_false() -> bool { | ||
false | ||
} | ||
|
||
/// Refinements in the marker targeting. The default (no refinement provided) is | ||
/// `on_argument == vec![]` and `on_return == false`, which is also what is | ||
/// returned from [`Self::empty`]. | ||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Deserialize, Serialize)] | ||
pub struct MarkerRefinement { | ||
#[serde(default, with = "tiny_bitset_pretty")] | ||
on_argument: TinyBitSet, | ||
#[serde(default = "const_false")] | ||
on_return: bool, | ||
} | ||
|
||
/// Disaggregated version of [`MarkerRefinement`]. Can be added to an existing | ||
/// refinement [`MarkerRefinement::merge_kind`]. | ||
#[derive(Clone, Deserialize, Serialize)] | ||
pub enum MarkerRefinementKind { | ||
Argument(#[serde(with = "tiny_bitset_pretty")] TinyBitSet), | ||
Return, | ||
} | ||
|
||
impl MarkerRefinement { | ||
/// The default, empty aggregate refinement `Self { on_argument: vec![], | ||
/// on_return: false }` | ||
pub fn empty() -> Self { | ||
Self { | ||
on_argument: Default::default(), | ||
on_return: false, | ||
} | ||
} | ||
|
||
/// Merge the aggregate refinement with another discovered refinement and | ||
/// check that they do not overwrite each other. | ||
pub fn merge_kind(mut self, k: MarkerRefinementKind) -> Result<Self, String> { | ||
match k { | ||
MarkerRefinementKind::Argument(a) => { | ||
if self.on_argument.is_empty() { | ||
self.on_argument = a; | ||
Ok(self) | ||
} else { | ||
Err(format!( | ||
"Double argument annotation {:?} and {a:?}", | ||
self.on_argument | ||
)) | ||
} | ||
} | ||
MarkerRefinementKind::Return => { | ||
if !self.on_return { | ||
self.on_return = true; | ||
Ok(self) | ||
} else { | ||
Err("Double on-return annotation".to_string()) | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Get the refinements on arguments | ||
pub fn on_argument(&self) -> TinyBitSet { | ||
self.on_argument | ||
} | ||
|
||
/// Is this refinement targeting the return value? | ||
pub fn on_return(&self) -> bool { | ||
self.on_return | ||
} | ||
|
||
/// True if this refinement is empty, i.e. the annotation is targeting the | ||
/// item itself. | ||
pub fn on_self(&self) -> bool { | ||
self.on_argument.is_empty() && !self.on_return | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.