Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
path: root/tamer
diff options
context:
space:
mode:
authorMike Gerwitz <mike.gerwitz@ryansg.com>2020-03-26 00:43:04 -0400
committerMike Gerwitz <mike.gerwitz@ryansg.com>2020-03-26 09:22:17 -0400
commitf44549d73083836e3d3c67a96c71e4995dff7692 (patch)
tree5862048f20865fe109d184e741aea09235a7d56d /tamer
parentd3ecd7b228f2e34f8ea2e9af7d6f4cbe488b06ce (diff)
downloadtame-f44549d73083836e3d3c67a96c71e4995dff7692.tar.gz
tame-f44549d73083836e3d3c67a96c71e4995dff7692.tar.bz2
tame-f44549d73083836e3d3c67a96c71e4995dff7692.zip
[DEV-7087] TAMER: Object{State,Data}: API representative of state transitions
The API now enforces beginning at Missing and transitioning through states. Methods have been renamed to reflect this.
Diffstat (limited to 'tamer')
-rw-r--r--tamer/src/ir/asg/base.rs65
-rw-r--r--tamer/src/ir/asg/graph.rs6
-rw-r--r--tamer/src/ir/asg/object.rs101
3 files changed, 80 insertions, 92 deletions
diff --git a/tamer/src/ir/asg/base.rs b/tamer/src/ir/asg/base.rs
index 65d4b31..cdf3cd5 100644
--- a/tamer/src/ir/asg/base.rs
+++ b/tamer/src/ir/asg/base.rs
@@ -130,10 +130,10 @@ where
/// Lookup `ident` or add a missing identifier to the graph and return a
/// reference to it.
///
- /// See [`IdentObjectState::missing`] for more information.
+ /// See [`IdentObjectState::declare`] for more information.
fn lookup_or_missing(&mut self, ident: &'i Symbol<'i>) -> ObjectRef<Ix> {
self.lookup(ident).unwrap_or_else(|| {
- let index = self.graph.add_node(Some(O::missing(ident)));
+ let index = self.graph.add_node(Some(O::declare(ident)));
self.index_identifier(ident, index);
ObjectRef(index)
@@ -237,7 +237,7 @@ where
kind: IdentKind,
src: Source<'i>,
) -> AsgResult<ObjectRef<Ix>, Ix> {
- self.with_ident(name, |obj| obj.redeclare(kind, src))
+ self.with_ident(name, |obj| obj.resolve(kind, src))
}
fn declare_extern(
@@ -418,10 +418,9 @@ mod test {
#[derive(Debug, Default, PartialEq)]
struct StubIdentObject<'i> {
- given_missing: Option<&'i Symbol<'i>>,
- given_ident: Option<(&'i Symbol<'i>, IdentKind, Source<'i>)>,
+ given_declare: Option<&'i Symbol<'i>>,
given_extern: Option<(IdentKind, Source<'i>)>,
- given_redeclare: Option<(IdentKind, Source<'i>)>,
+ given_resolve: Option<(IdentKind, Source<'i>)>,
given_set_fragment: Option<FragmentText>,
fail_redeclare: RefCell<Option<TransitionError>>,
fail_extern: RefCell<Option<TransitionError>>,
@@ -429,15 +428,11 @@ mod test {
impl<'i> IdentObjectData<'i> for StubIdentObject<'i> {
fn name(&self) -> Option<&'i Symbol<'i>> {
- self.given_missing
- .or(self.given_ident.as_ref().map(|args| args.0))
+ self.given_declare
}
fn kind(&self) -> Option<&IdentKind> {
- self.given_ident
- .as_ref()
- .map(|args| &args.1)
- .or(self.given_redeclare.as_ref().map(|args| &args.0))
+ self.given_resolve.as_ref().map(|args| &args.0)
}
fn src(&self) -> Option<&Source<'i>> {
@@ -454,25 +449,14 @@ mod test {
}
impl<'i> IdentObjectState<'i, StubIdentObject<'i>> for StubIdentObject<'i> {
- fn missing(ident: &'i Symbol<'i>) -> Self {
+ fn declare(ident: &'i Symbol<'i>) -> Self {
Self {
- given_missing: Some(ident),
+ given_declare: Some(ident),
..Default::default()
}
}
- fn ident(
- name: &'i Symbol<'i>,
- kind: IdentKind,
- src: Source<'i>,
- ) -> Self {
- Self {
- given_ident: Some((name, kind, src)),
- ..Default::default()
- }
- }
-
- fn redeclare(
+ fn resolve(
mut self,
kind: IdentKind,
src: Source<'i>,
@@ -482,7 +466,7 @@ mod test {
return Err((self, err));
}
- self.given_redeclare = Some((kind, src));
+ self.given_resolve = Some((kind, src));
Ok(self)
}
@@ -558,7 +542,7 @@ mod test {
assert_ne!(nodea, nodeb);
- assert_eq!(Some(&syma), sut.get(nodea).unwrap().given_missing);
+ assert_eq!(Some(&syma), sut.get(nodea).unwrap().given_declare);
assert_eq!(
Some((
IdentKind::Meta,
@@ -567,10 +551,10 @@ mod test {
..Default::default()
},
)),
- sut.get(nodea).unwrap().given_redeclare
+ sut.get(nodea).unwrap().given_resolve
);
- assert_eq!(Some(&symb), sut.get(nodeb).unwrap().given_missing);
+ assert_eq!(Some(&symb), sut.get(nodeb).unwrap().given_declare);
assert_eq!(
Some((
IdentKind::Worksheet,
@@ -579,7 +563,7 @@ mod test {
..Default::default()
},
)),
- sut.get(nodeb).unwrap().given_redeclare
+ sut.get(nodeb).unwrap().given_resolve
);
Ok(())
@@ -624,10 +608,7 @@ mod test {
// same node is referenced.
assert_eq!(node, redeclare);
- assert_eq!(
- Some((rekind, resrc)),
- sut.get(node).unwrap().given_redeclare,
- );
+ assert_eq!(Some((rekind, resrc)), sut.get(node).unwrap().given_resolve,);
Ok(())
}
@@ -655,7 +636,7 @@ mod test {
if let Err(err) = result {
// The node should have been restored.
let obj = sut.get(node).unwrap();
- assert_eq!(src, obj.given_redeclare.as_ref().unwrap().1);
+ assert_eq!(src, obj.given_resolve.as_ref().unwrap().1);
assert_eq!(AsgError::ObjectTransition(terr), err);
@@ -750,8 +731,8 @@ mod test {
let obj = sut.get(node).unwrap();
- assert_eq!(Some(&sym), obj.given_missing);
- assert_eq!(Some((IdentKind::Meta, src)), obj.given_redeclare);
+ assert_eq!(Some(&sym), obj.given_declare);
+ assert_eq!(Some((IdentKind::Meta, src)), obj.given_resolve);
assert_eq!(Some(fragment), obj.given_set_fragment);
Ok(())
@@ -807,8 +788,8 @@ mod test {
let (symnode, depnode) = sut.add_dep_lookup(&sym, &dep);
assert!(sut.has_dep(symnode, depnode));
- assert_eq!(Some(&sym), sut.get(symnode).unwrap().given_missing);
- assert_eq!(Some(&dep), sut.get(depnode).unwrap().given_missing);
+ assert_eq!(Some(&sym), sut.get(symnode).unwrap().given_declare);
+ assert_eq!(Some(&dep), sut.get(depnode).unwrap().given_declare);
Ok(())
}
@@ -835,8 +816,8 @@ mod test {
let obj = sut.get(declared).unwrap();
- assert_eq!(Some(&sym), obj.given_missing);
- assert_eq!(Some((IdentKind::Meta, src)), obj.given_redeclare);
+ assert_eq!(Some(&sym), obj.given_declare);
+ assert_eq!(Some((IdentKind::Meta, src)), obj.given_resolve);
Ok(())
}
diff --git a/tamer/src/ir/asg/graph.rs b/tamer/src/ir/asg/graph.rs
index 3924ef3..52078ed 100644
--- a/tamer/src/ir/asg/graph.rs
+++ b/tamer/src/ir/asg/graph.rs
@@ -73,7 +73,7 @@ where
///
/// For more information on state transitions that can occur when
/// redeclaring an identifier that already exists,
- /// see [`IdentObjectState::redeclare`].
+ /// see [`IdentObjectState::resolve`].
///
/// A successful declaration will add an identifier to the graph
/// and return an [`ObjectRef`] reference.
@@ -102,7 +102,7 @@ where
/// Resolution will otherwise fail in error.
///
/// See [`IdentObjectState::extern_`] and
- /// [`IdentObjectState::redeclare`] for more information on
+ /// [`IdentObjectState::resolve`] for more information on
/// compatibility related to extern resolution.
fn declare_extern(
&mut self,
@@ -163,7 +163,7 @@ where
/// a missing identifier will be added as a placeholder,
/// allowing the ASG to be built with partial information as
/// identifiers continue to be discovered.
- /// See [`IdentObjectState::missing`] for more information.
+ /// See [`IdentObjectState::declare`] for more information.
///
/// References to both identifiers are returned in argument order.
fn add_dep_lookup(
diff --git a/tamer/src/ir/asg/object.rs b/tamer/src/ir/asg/object.rs
index 24f0f31..1765665 100644
--- a/tamer/src/ir/asg/object.rs
+++ b/tamer/src/ir/asg/object.rs
@@ -80,7 +80,7 @@ pub enum IdentObject<'i> {
/// as [`IdentObject`];
/// this allows other representations to be used,
/// while still permitting the use of matching on [`IdentObject`]
-/// through the use of [`ident`](IdentObjectState::ident).
+/// through the use of [`ident`](IdentObjectData::as_ident).
///
/// Since an object implementing this trait may not be an identifier
/// (e.g. an expression),
@@ -186,20 +186,19 @@ where
T: IdentObjectState<'i, T>,
{
/// Produce an object representing a missing identifier.
- fn missing(ident: &'i Symbol<'i>) -> T;
-
- /// Produce an object representing a concrete identifier.
- fn ident(name: &'i Symbol<'i>, kind: IdentKind, src: Source<'i>) -> T;
+ ///
+ /// This is the base state for all identifiers.
+ fn declare(ident: &'i Symbol<'i>) -> T;
- /// Attempt to redeclare an identifier with additional information.
+ /// Attempt to transition to a concrete identifier.
///
/// For specific information on compatibility rules,
/// see implementers of this trait,
/// since rules may vary between implementations.
- fn redeclare(self, kind: IdentKind, src: Source<'i>)
- -> TransitionResult<T>;
+ fn resolve(self, kind: IdentKind, src: Source<'i>) -> TransitionResult<T>;
- /// Resolve identifier against an extern declaration.
+ /// Resolve identifier against an extern declaration or produce an
+ /// extern.
///
/// If the existing identifier has an assigned [`IdentKind`],
/// then it will be compared for equality against the given `kind`.
@@ -227,14 +226,10 @@ where
}
impl<'i> IdentObjectState<'i, IdentObject<'i>> for IdentObject<'i> {
- fn missing(ident: &'i Symbol<'i>) -> Self {
+ fn declare(ident: &'i Symbol<'i>) -> Self {
IdentObject::Missing(ident)
}
- fn ident(name: &'i Symbol<'i>, kind: IdentKind, src: Source<'i>) -> Self {
- IdentObject::Ident(name, kind, src)
- }
-
/// Attempt to redeclare an identifier with additional information.
///
/// If an existing identifier is an [`IdentObject::Extern`],
@@ -253,7 +248,7 @@ impl<'i> IdentObjectState<'i, IdentObject<'i>> for IdentObject<'i> {
/// The kind of identifier cannot change,
/// but the argument is provided here for convenience so that the
/// caller does not need to perform such a check itself.
- fn redeclare(
+ fn resolve(
mut self,
kind: IdentKind,
src: Source<'i>,
@@ -393,7 +388,7 @@ pub enum TransitionError {
/// has failed because the provided information was not compatible
/// with the original declaration.
///
- /// See [`IdentObjectState::redeclare`].
+ /// See [`IdentObjectState::resolve`].
Incompatible(String),
/// Extern resolution failure.
@@ -691,7 +686,7 @@ mod test {
#[test]
fn ident_object_missing() {
let sym = symbol_dummy!(1, "missing");
- assert_eq!(IdentObject::Missing(&sym), IdentObject::missing(&sym));
+ assert_eq!(IdentObject::Missing(&sym), IdentObject::declare(&sym));
}
#[test]
@@ -705,7 +700,9 @@ mod test {
assert_eq!(
IdentObject::Ident(&sym, kind.clone(), src.clone()),
- IdentObject::ident(&sym, kind.clone(), src.clone()),
+ IdentObject::declare(&sym)
+ .resolve(kind.clone(), src.clone())
+ .unwrap(),
);
}
@@ -723,7 +720,7 @@ mod test {
assert_eq!(
Ok(IdentObject::Extern(&sym, kind.clone())),
- IdentObject::missing(&sym).extern_(kind, src),
+ IdentObject::declare(&sym).extern_(kind, src),
);
}
@@ -738,9 +735,9 @@ mod test {
};
// Compatible kind, should resolve.
- let result = IdentObject::missing(&sym)
+ let result = IdentObject::declare(&sym)
.extern_(kind.clone(), Source::default())
- .and_then(|o| o.redeclare(kind.clone(), src.clone()));
+ .and_then(|o| o.resolve(kind.clone(), src.clone()));
assert_eq!(Ok(IdentObject::Ident(&sym, kind, src)), result,);
}
@@ -756,9 +753,9 @@ mod test {
};
// Compatible kind, should resolve.
- let result =
- IdentObject::ident(&sym, kind.clone(), src.clone())
- .extern_(kind.clone(), Source::default());
+ let result = IdentObject::declare(&sym)
+ .resolve(kind.clone(), src.clone())
+ .and_then(|o| o.extern_(kind.clone(), Source::default()));
assert_eq!(Ok(IdentObject::Ident(&sym, kind, src)), result,);
}
@@ -768,7 +765,7 @@ mod test {
let sym = symbol_dummy!(1, "extern_extern");
let kind = IdentKind::Class(Dim::from_u8(20));
- let result = IdentObject::missing(&sym)
+ let result = IdentObject::declare(&sym)
.extern_(kind.clone(), Source::default())
.and_then(|o| o.extern_(kind.clone(), Source::default()));
@@ -785,13 +782,13 @@ mod test {
..Default::default()
};
- let orig = IdentObject::missing(&sym)
+ let orig = IdentObject::declare(&sym)
.extern_(kind.clone(), Source::default())
.unwrap();
// Incompatible kind
let kind_bad = IdentKind::Meta;
- let result = orig.clone().redeclare(kind_bad.clone(), src);
+ let result = orig.clone().resolve(kind_bad.clone(), src);
match result {
Err((given_orig, err @ _)) => {
@@ -829,8 +826,9 @@ mod test {
..Default::default()
};
- let orig =
- IdentObject::ident(&sym, kind_given.clone(), src.clone());
+ let orig = IdentObject::declare(&sym)
+ .resolve(kind_given.clone(), src.clone())
+ .unwrap();
// Extern with incompatible kind.
let kind_extern = IdentKind::Meta;
@@ -870,13 +868,14 @@ mod test {
fn redeclare_returns_existing_compatible() {
let sym = symbol_dummy!(1, "symdup");
- let first =
- IdentObject::ident(&sym, IdentKind::Meta, Source::default());
+ let first = IdentObject::declare(&sym)
+ .resolve(IdentKind::Meta, Source::default())
+ .unwrap();
// Same declaration a second time
assert_eq!(
Ok(first.clone()),
- first.clone().redeclare(
+ first.clone().resolve(
first.kind().unwrap().clone(),
first.src().unwrap().clone(),
)
@@ -892,7 +891,9 @@ mod test {
};
let kind = IdentKind::Meta;
- let ident = IdentObject::ident(&sym, kind.clone(), src.clone());
+ let ident = IdentObject::declare(&sym)
+ .resolve(kind.clone(), src.clone())
+ .unwrap();
let text = FragmentText::from("a fragment");
let ident_with_frag = ident.set_fragment(text.clone());
@@ -905,8 +906,9 @@ mod test {
#[test]
fn add_fragment_to_fragment_fails() {
let sym = symbol_dummy!(1, "badsym");
- let ident =
- IdentObject::ident(&sym, IdentKind::Meta, Source::default());
+ let ident = IdentObject::declare(&sym)
+ .resolve(IdentKind::Meta, Source::default())
+ .unwrap();
let ident_with_frag = ident
.set_fragment("orig fragment".into())
@@ -938,14 +940,15 @@ mod test {
let over_src = symbol_dummy!(2, "src");
let kind = IdentKind::Meta;
- let virt = IdentObject::ident(
- &sym,
- kind.clone(),
- Source {
- virtual_: true,
- ..Default::default()
- },
- );
+ let virt = IdentObject::declare(&sym)
+ .resolve(
+ kind.clone(),
+ Source {
+ virtual_: true,
+ ..Default::default()
+ },
+ )
+ .unwrap();
let over_src = Source {
override_: true,
@@ -953,7 +956,7 @@ mod test {
..Default::default()
};
- let result = virt.redeclare(kind.clone(), over_src.clone());
+ let result = virt.resolve(kind.clone(), over_src.clone());
assert_eq!(Ok(IdentObject::Ident(&sym, kind, over_src)), result);
}
@@ -970,7 +973,9 @@ mod test {
..Default::default()
};
- let virt = IdentObject::ident(&sym, kind.clone(), virt_src.clone());
+ let virt = IdentObject::declare(&sym)
+ .resolve(kind.clone(), virt_src.clone())
+ .unwrap();
let text = FragmentText::from("remove me");
let virt_frag = virt.set_fragment(text.clone());
@@ -991,7 +996,7 @@ mod test {
};
let result =
- virt_frag.unwrap().redeclare(kind.clone(), over_src.clone());
+ virt_frag.unwrap().resolve(kind.clone(), over_src.clone());
// The act of overriding the object should have cleared any
// existing fragment, making way for a new fragment to take its
@@ -1007,7 +1012,9 @@ mod test {
..Default::default()
};
- let obj = IdentObject::ident(&sym, given, src.clone());
+ let obj = IdentObject::declare(&sym)
+ .resolve(given, src.clone())
+ .unwrap();
let fragment = "a fragment".to_string();
let obj_with_frag = obj.set_fragment(fragment.clone());