Skip to content

Commit

Permalink
small meeting update, removed org dir, some small tooltips, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinleroy committed Dec 19, 2022
1 parent 8a66f6b commit 1639e59
Show file tree
Hide file tree
Showing 42 changed files with 126 additions and 2,006 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ node_modules/
/org/meeting*
/org/*.png
/org/media/
sample-book/

# Rust things
target/
Expand Down
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1 @@
# Aquascope

This README will remain unhelpful until Aquascope is in a semi-decent state.

For current information about what is getting worked on, design decisions, and other project related information, see the `org/` directory. In particular, see the [aquauscope.org](/org/aquascope.org) file which is a good starting place.

:beers:

Gavin
49 changes: 24 additions & 25 deletions crates/aquascope/src/analysis/ir_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub enum GatherDepth {
#[derive(Debug)]
pub struct MirOrderedLocations {
entry_block: BasicBlock,
exit_block: BasicBlock,
exit_block: Option<BasicBlock>,
// associated indices must remain sorted
locations: HashMap<BasicBlock, Vec<usize>>,
}
Expand All @@ -85,24 +85,26 @@ impl MirOrderedLocations {
}
}

fn maximum(&self) -> Location {
let block = self.exit_block;
let statement_index = *self
.locations
.get(&block)
.expect("Block with no associated locations")
.last()
.unwrap();
Location {
block,
statement_index,
}
fn maximum(&self) -> Option<Location> {
self.exit_block.map(|block| {
let statement_index = *self
.locations
.get(&block)
.expect("Block with no associated locations")
.last()
.unwrap();
Location {
block,
statement_index,
}
})
}

pub fn get_entry_exit_locations(&self) -> (Location, Location) {
let m = self.minimum();
let mx = self.maximum();
(m, mx)
pub fn get_entry_exit_locations(&self) -> Option<(Location, Location)> {
self.maximum().map(|mx| {
let m = self.minimum();
(m, mx)
})
}

fn values(&self) -> impl Iterator<Item = Location> + Captures<'_> {
Expand Down Expand Up @@ -235,20 +237,17 @@ where
})
.unwrap();

let exit_block = basic_blocks
.iter()
.find(|&&&b1| {
basic_blocks.iter().all(|&&b2| {
b1 == b2 || self.post_dominators.is_postdominated_by(b1, b2)
})
let exit_block = basic_blocks.iter().find(|&&&b1| {
basic_blocks.iter().all(|&&b2| {
b1 == b2 || self.post_dominators.is_postdominated_by(b1, b2)
})
.unwrap();
});

log::debug!("Entry: {entry_block:?} Exit {exit_block:?}");

Some(MirOrderedLocations {
entry_block: **entry_block,
exit_block: **exit_block,
exit_block: exit_block.map(|b| **b),
locations: total_location_map,
})
}
Expand Down
91 changes: 55 additions & 36 deletions crates/aquascope/src/analysis/permissions/permission_stepper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use flowistry::mir::utils::PlaceExt as FlowistryPlaceExt;
use flowistry::mir::utils::{PlaceExt as FlowistryPlaceExt, SpanExt};
use rustc_data_structures::fx::FxHashMap as HashMap;
use rustc_hir::{
self as hir,
Expand Down Expand Up @@ -97,6 +97,10 @@ fn prettify_permission_steps<'tcx>(
.filter_map(|(id, place_to_diffs)| {
let span = hir.span(id);

let span = span
.as_local(ctxt.body_with_facts.body.span)
.unwrap_or(span);

let range = span_to_range(span);
let mut entries = place_to_diffs.into_iter().collect::<Vec<_>>();

Expand Down Expand Up @@ -165,16 +169,17 @@ macro_rules! in_visibility_scope_context {
// represents all the places where a permissions change was visible. Specifically,
// this is the difference in PermissionsDomain @ (after_point - before_point).
let mut visibility_here =
$this.ir_mapper.get_mir_locations($id, GatherDepth::Nested).map(|mir_order| {
let (loc1, loc2) = mir_order.get_entry_exit_locations();
let before_point = $this.ctxt.location_to_point(loc1);
let after_point = $this.ctxt.location_to_point(loc2);
let dmn_before = &$this.ctxt.permissions_domain_at_point(before_point);
let dmn_after = &$this
.ctxt
.permissions_domain_after_point_effect(after_point)
.unwrap_or_else(|| $this.ctxt.permissions_domain_at_point(after_point));
dmn_before.diff(dmn_after)
$this.ir_mapper.get_mir_locations($id, GatherDepth::Nested).and_then(|mir_order| {
mir_order.get_entry_exit_locations().map(|(loc1, loc2)| {
let before_point = $this.ctxt.location_to_point(loc1);
let after_point = $this.ctxt.location_to_point(loc2);
let dmn_before = &$this.ctxt.permissions_domain_at_point(before_point);
let dmn_after = &$this
.ctxt
.permissions_domain_after_point_effect(after_point)
.unwrap_or_else(|| $this.ctxt.permissions_domain_at_point(after_point));
dmn_before.diff(dmn_after)
})
}).unwrap_or_else(|| HashMap::default());
filter_exec_commit!($this, $id, visibility_here, $inner);
};
Expand All @@ -183,21 +188,21 @@ macro_rules! in_visibility_scope_context {
macro_rules! with_seamless_branching {
($this:tt, $k:ident, $targets:expr, $branch_cnd:expr) => {
let id = $branch_cnd.hir_id;
let hir = $this.ctxt.tcx.hir();
log::debug!("Visiting EXPR CND: {}", hir.node_to_string(id));
// From the beginning to the point *after* the end location of `id`, `visibility_here`
// represents all the places where a permissions change was visible. Specifically,
// this is the difference in PermissionsDomain @ (after_point - before_point).
let (mut visibility_here, after_branch_point) =
$this.ir_mapper.get_mir_locations(id, GatherDepth::Nested).map(|mir_order| {
let (loc1, loc2) = mir_order.get_entry_exit_locations();
let before_point = $this.ctxt.location_to_point(loc1);
let after_point = $this.ctxt.location_to_point(loc2);
let dmn_before = &$this.ctxt.permissions_domain_at_point(before_point);
let dmn_after = &$this.ctxt.permissions_domain_at_point(after_point);
(dmn_before.diff(dmn_after), after_point)
}).unwrap_or_else(|| {
// FIXME
panic!("this shouldn't ever ever ever happen")
});
let (mut visibility_here, after_branch_point_opt) =
$this.ir_mapper.get_mir_locations(id, GatherDepth::Nested).and_then(|mir_order| {
mir_order.get_entry_exit_locations().map(|(loc1, loc2)| {
let before_point = $this.ctxt.location_to_point(loc1);
let after_point = $this.ctxt.location_to_point(loc2);
let dmn_before = &$this.ctxt.permissions_domain_at_point(before_point);
let dmn_after = &$this.ctxt.permissions_domain_at_point(after_point);
(dmn_before.diff(dmn_after), Some(after_point))
})
}).unwrap_or_else(|| (HashMap::default(), None));
filter_exec_commit!($this, id, visibility_here, {
intravisit::walk_expr($this, $branch_cnd);
});
Expand All @@ -210,19 +215,22 @@ macro_rules! with_seamless_branching {
// represents all the places where a permissions change was visible. Specifically,
// this is the difference in PermissionsDomain @ (after_point - before_point).
let mut visibility_here =
$this.ir_mapper.get_mir_locations(id, GatherDepth::Nested).map(|mir_order| {
let (_, loc2) = mir_order.get_entry_exit_locations();
let before_point = after_branch_point;
let after_point = $this.ctxt.location_to_point(loc2);
let dmn_before = &$this.ctxt.permissions_domain_at_point(before_point);
let dmn_after = &$this
.ctxt
.permissions_domain_after_point_effect(after_point)
.unwrap_or_else(|| $this.ctxt.permissions_domain_at_point(after_point));
dmn_before.diff(dmn_after)
$this.ir_mapper.get_mir_locations(id, GatherDepth::Nested).and_then(|mir_order| {
mir_order.get_entry_exit_locations().map(|(loc1, loc2)| {
let before_point = after_branch_point_opt.unwrap_or_else(|| {
$this.ctxt.location_to_point(loc1)
});
let after_point = $this.ctxt.location_to_point(loc2);
let dmn_before = &$this.ctxt.permissions_domain_at_point(before_point);
let dmn_after = &$this
.ctxt
.permissions_domain_after_point_effect(after_point)
.unwrap_or_else(|| $this.ctxt.permissions_domain_at_point(after_point));
dmn_before.diff(dmn_after)
})
}).unwrap_or_else(|| {
// FIXME
panic!("this shouldn't ever ever ever happen")
panic!("this should not happen!")
});
filter_exec_commit!($this, id, visibility_here, {
intravisit::$k($this, target);
Expand Down Expand Up @@ -257,6 +265,18 @@ impl<'a, 'tcx: 'a> HirVisitor<'tcx> for HirPermDiffFlow<'a, 'tcx> {
}

fn visit_body(&mut self, body: &'tcx hir::Body) {
// TODO: I can see a version of this analysis that maps
// permission differences to Spans, instead of HirIds. This
// has a few advantages, but this case here is a good example.
// For a function which takes parameters, there's nowhere in
// the pointwise analysis that says "HERE is where that is live",
// they are just live coming in.
// Therefore, currently, there isn't a HirId we can attach this liveness to.
// What we could do, is split the body up into different spans, one of the
// spans being the entry `fn foo(...) {` and we can attach these differences
// there explicitly. This could also make conditionals slightly more accurate
// because the current version attaches differences to the expression itself,
// which isn't really what we want visually.
intravisit::walk_body(self, body);
}

Expand Down Expand Up @@ -385,8 +405,7 @@ impl<'a, 'tcx: 'a> HirVisitor<'tcx> for HirPermDiffFlow<'a, 'tcx> {
}

// - Variants I'd need to think more about.
EK::Closure(..) => unimplemented!("CLOSURES"),

// EK::Closure(..) => unimplemented!("CLOSURES"),
_ => {
intravisit::walk_expr(self, expr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,6 @@ class SinglePermIcon implements Icon {

const refinedRegion = this.onHover as RefinementRegion;

console.log(
`${refinedRegion.refiner_point.char_start} -- ${refinedRegion.refiner_point.char_end}`
);

let loanDeco = Decoration.mark({
class: "aquascope-loan",
tagName: this.loanTag,
Expand All @@ -115,23 +111,23 @@ class SinglePermIcon implements Icon {
return highlightedRange;
});

// TODO: you can probably get rid of the start / end as
// soon as you feel confident enough about the spans
// being generated.

// The start and end are the colored braces which used
// to indicate the start and end of a refinement region.
// We aren't using them currently but who knows if they'll
// be wanted in the future for anything.
let start = this.start;
let charStart = refinedRegion.start.char_start;
let startDeco = Decoration.widget({
let _startDeco = Decoration.widget({
widget: new RegionEnd(start),
}).range(charStart);

let end = this.end;
let charEnd = refinedRegion.end.char_end;
let endDeco = Decoration.widget({
let _endDeco = Decoration.widget({
widget: new RegionEnd(end),
}).range(charEnd);

let extraDecos = [loanDeco, /* startDeco, endDeco, */ ...regionDecos];
let extraDecos = [loanDeco, ...regionDecos];

return extraDecos;
}
Expand Down Expand Up @@ -226,10 +222,13 @@ class BoundaryPointWidget extends WidgetType {
let fillColor: Color = icoI.actual ? icoI.color : whiteColor;
ico.setAttribute("fill", fillColor.toString());
ico.setAttribute("stroke", icoI.color.toString());
ico.dataset.bufferPos = this.pos.toString();
if (icoI.wasCopied) {
ico.classList.add("copied-permission");
ico.dataset.bufferPos = this.pos.toString();
ico.classList.add("copied-tip");
} else if (icoI.onHover?.type === "InsufficientType") {
ico.classList.add("insufficient-type-tip");
}
// TODO: we also need to include a tooltip for moves.
wrap.appendChild(ico);
});

Expand Down Expand Up @@ -302,7 +301,7 @@ let boundaryStateField = genStateField<Array<BoundaryPoint>>(
export const copiedValueHover = hoverTooltip(
(_view, pos: number, side: number) => {
let copyPoints = Array.from(
document.querySelectorAll<HTMLElement>(".copied-permission")
document.querySelectorAll<HTMLElement>(".copied-tip")
);

let sPos = pos.toString();
Expand All @@ -318,7 +317,34 @@ export const copiedValueHover = hoverTooltip(
arrow: true,
create(_view) {
let dom = document.createElement("div");
dom.textContent = "Value was copied: creating 'Own' permission";
dom.textContent = "Value was copied: creating 'O' permission";
dom.classList.add("cm-tooltip-cursor");
return { dom };
},
};
}
);

export const insufficientTypeHover = hoverTooltip(
(_view, pos: number, side: number) => {
let copyPoints = Array.from(
document.querySelectorAll<HTMLElement>(".insufficient-type-tip")
);

let sPos = pos.toString();
let hovered = copyPoints.find(s => s.dataset.bufferPos == sPos);
if (hovered == undefined || hovered == null || side >= 0) {
return null;
}

let perm = hovered.textContent!;
return {
pos: pos,
above: true,
arrow: true,
create(_view) {
let dom = document.createElement("div");
dom.textContent = `Declared type does not allow for permission '${perm}'`;
dom.classList.add("cm-tooltip-cursor");
return { dom };
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ let stateStepToPermissions = (
let permDiffStateField = genStateField(
permissionsDiffIcoType,
(ts: Array<PermissionStepTable>) =>
ts.map(([diffs, from]) => makeDecorationWithDiffs(diffs, from).range(from))
ts.map(([diffs, pos]) => makeDecorationWithDiffs(diffs, pos).range(pos))
);

let makeDecorationWithDiffs = (
Expand Down
2 changes: 2 additions & 0 deletions frontend/packages/aquascope-editor/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DecorationSet, EditorView } from "@codemirror/view";
import { IconField } from "./editor-utils/misc";
import {
copiedValueHover,
insufficientTypeHover,
receiverPermissionsField,
} from "./editor-utils/permission-boundaries";
import { coarsePermissionDiffs } from "./editor-utils/permission-steps";
Expand Down Expand Up @@ -137,6 +138,7 @@ export class Editor {
rust(),
indentUnit.of(" "),
copiedValueHover,
insufficientTypeHover,
...supportedFields,
],
});
Expand Down
4 changes: 2 additions & 2 deletions frontend/packages/aquascope-standalone/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ nav {
height: 100%;
width: 100%;
max-height: 700px;
max-width: 900px;
max-width: 1200px;

/* position: relative; */
/* padding-left: 25px; */
Expand Down Expand Up @@ -95,4 +95,4 @@ nav {
border-color: #bbb;

background-color: white;
}
}
Loading

0 comments on commit 1639e59

Please sign in to comment.