[DEV-7087] TAMER: Remote optional Source from ASG and Object
This undoes work I did earlier today...but now we'll be able to support a Source on an extern. There is duplicate code between `BaseAsg::declare{,_extern}` that will be resolved in an upcoming commit. Upcoming commits will also simplify terminology and clean up methods on ObjectState.master
parent
7dd8717f2f
commit
40eaeb3dc8
|
@ -199,38 +199,24 @@ where
|
|||
&mut self,
|
||||
name: &'i Symbol<'i>,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
src: Source<'i>,
|
||||
) -> AsgResult<ObjectRef<Ix>, Ix> {
|
||||
if src.is_none() {
|
||||
panic!("TODO: remove optional src");
|
||||
}
|
||||
let identi = self.lookup_or_missing(name);
|
||||
let node = self.graph.node_weight_mut(identi.0).unwrap();
|
||||
|
||||
if let Some(existing) = self.lookup(name) {
|
||||
let node = self.graph.node_weight_mut(existing.0).unwrap();
|
||||
let obj = node
|
||||
.take()
|
||||
.expect(&format!("internal error: missing object for {}", name));
|
||||
|
||||
let obj = node.take().expect(&format!(
|
||||
"internal error: missing object for {}",
|
||||
name
|
||||
));
|
||||
|
||||
// TODO: test inconsistent state (fixed)
|
||||
return obj
|
||||
.redeclare(kind, src)
|
||||
.and_then(|obj| {
|
||||
node.replace(obj);
|
||||
Ok(existing)
|
||||
})
|
||||
.or_else(|(orig, err)| {
|
||||
node.replace(orig);
|
||||
Err(err.into())
|
||||
});
|
||||
}
|
||||
|
||||
let node = self.graph.add_node(Some(O::ident(name, kind, src)));
|
||||
|
||||
self.index_identifier(name, node);
|
||||
|
||||
Ok(ObjectRef(node))
|
||||
obj.redeclare(kind, src)
|
||||
.and_then(|obj| {
|
||||
node.replace(obj);
|
||||
Ok(identi)
|
||||
})
|
||||
.or_else(|(orig, err)| {
|
||||
node.replace(orig);
|
||||
Err(err.into())
|
||||
})
|
||||
}
|
||||
|
||||
fn declare_extern(
|
||||
|
@ -427,9 +413,9 @@ mod test {
|
|||
#[derive(Debug, Default, PartialEq)]
|
||||
struct StubIdentObject<'i> {
|
||||
given_missing: Option<&'i Symbol<'i>>,
|
||||
given_ident: Option<(&'i Symbol<'i>, IdentKind, Option<Source<'i>>)>,
|
||||
given_ident: Option<(&'i Symbol<'i>, IdentKind, Source<'i>)>,
|
||||
given_extern: Option<(IdentKind, Source<'i>)>,
|
||||
given_redeclare: Option<(IdentKind, Option<Source<'i>>)>,
|
||||
given_redeclare: Option<(IdentKind, Source<'i>)>,
|
||||
given_set_fragment: Option<FragmentText>,
|
||||
fail_redeclare: RefCell<Option<TransitionError>>,
|
||||
fail_extern: RefCell<Option<TransitionError>>,
|
||||
|
@ -472,7 +458,7 @@ mod test {
|
|||
fn ident(
|
||||
name: &'i Symbol<'i>,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
src: Source<'i>,
|
||||
) -> Self {
|
||||
Self {
|
||||
given_ident: Some((name, kind, src)),
|
||||
|
@ -483,7 +469,7 @@ mod test {
|
|||
fn redeclare(
|
||||
mut self,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
src: Source<'i>,
|
||||
) -> TransitionResult<StubIdentObject<'i>> {
|
||||
if self.fail_redeclare.borrow().is_some() {
|
||||
let err = self.fail_redeclare.replace(None).unwrap();
|
||||
|
@ -549,45 +535,45 @@ mod test {
|
|||
let nodea = sut.declare(
|
||||
&syma,
|
||||
IdentKind::Meta,
|
||||
Some(Source {
|
||||
Source {
|
||||
desc: Some("a".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let nodeb = sut.declare(
|
||||
&symb,
|
||||
IdentKind::Worksheet,
|
||||
Some(Source {
|
||||
Source {
|
||||
desc: Some("b".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
assert_ne!(nodea, nodeb);
|
||||
|
||||
assert_eq!(Some(&syma), sut.get(nodea).unwrap().given_missing);
|
||||
assert_eq!(
|
||||
Some((
|
||||
&syma,
|
||||
IdentKind::Meta,
|
||||
Some(Source {
|
||||
Source {
|
||||
desc: Some("a".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)),
|
||||
sut.get(nodea).unwrap().given_ident
|
||||
sut.get(nodea).unwrap().given_redeclare
|
||||
);
|
||||
|
||||
assert_eq!(Some(&symb), sut.get(nodeb).unwrap().given_missing);
|
||||
assert_eq!(
|
||||
Some((
|
||||
&symb,
|
||||
IdentKind::Worksheet,
|
||||
Some(Source {
|
||||
Source {
|
||||
desc: Some("b".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)),
|
||||
sut.get(nodeb).unwrap().given_ident
|
||||
sut.get(nodeb).unwrap().given_redeclare
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
@ -601,10 +587,10 @@ mod test {
|
|||
let node = sut.declare(
|
||||
&sym,
|
||||
IdentKind::Meta,
|
||||
Some(Source {
|
||||
Source {
|
||||
generated: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
assert_eq!(Some(node), sut.lookup(&sym));
|
||||
|
@ -618,7 +604,7 @@ mod test {
|
|||
|
||||
let sym = symbol_dummy!(1, "symdup");
|
||||
let src = Source::default();
|
||||
let node = sut.declare(&sym, IdentKind::Meta, Some(src.clone()))?;
|
||||
let node = sut.declare(&sym, IdentKind::Meta, src.clone())?;
|
||||
|
||||
// Remember that our stub does not care about compatibility.
|
||||
let rekind = IdentKind::Class(Dim::from_u8(3));
|
||||
|
@ -626,15 +612,14 @@ mod test {
|
|||
desc: Some("redeclare".into()),
|
||||
..Default::default()
|
||||
};
|
||||
let redeclare =
|
||||
sut.declare(&sym, rekind.clone(), Some(resrc.clone()))?;
|
||||
let redeclare = sut.declare(&sym, rekind.clone(), resrc.clone())?;
|
||||
|
||||
// We don't care what the objects are for this test, just that the
|
||||
// same node is referenced.
|
||||
assert_eq!(node, redeclare);
|
||||
|
||||
assert_eq!(
|
||||
Some((rekind, Some(resrc))),
|
||||
Some((rekind, resrc)),
|
||||
sut.get(node).unwrap().given_redeclare,
|
||||
);
|
||||
|
||||
|
@ -653,19 +638,18 @@ mod test {
|
|||
};
|
||||
|
||||
// Set up an object to fail redeclaration.
|
||||
let node = sut.declare(&sym, IdentKind::Meta, Some(src.clone()))?;
|
||||
let node = sut.declare(&sym, IdentKind::Meta, src.clone())?;
|
||||
let obj = sut.get(node).unwrap();
|
||||
let terr = TransitionError::Incompatible(String::from("test fail"));
|
||||
obj.fail_redeclare.replace(Some(terr.clone()));
|
||||
|
||||
// Should invoke StubIdentObject::redeclare on the above `obj`.
|
||||
let result =
|
||||
sut.declare(&sym, IdentKind::Meta, Some(Source::default()));
|
||||
let result = sut.declare(&sym, IdentKind::Meta, Source::default());
|
||||
|
||||
if let Err(err) = result {
|
||||
// The node should have been restored.
|
||||
let obj = sut.get(node).unwrap();
|
||||
assert_eq!(Some(src), obj.given_ident.as_ref().unwrap().2);
|
||||
assert_eq!(src, obj.given_redeclare.as_ref().unwrap().1);
|
||||
|
||||
assert_eq!(AsgError::ObjectTransition(terr), err);
|
||||
|
||||
|
@ -746,7 +730,7 @@ mod test {
|
|||
generated: true,
|
||||
..Default::default()
|
||||
};
|
||||
let node = sut.declare(&sym, IdentKind::Meta, Some(src.clone()))?;
|
||||
let node = sut.declare(&sym, IdentKind::Meta, src.clone())?;
|
||||
|
||||
let fragment = "a fragment".to_string();
|
||||
let node_with_frag = sut.set_fragment(node, fragment.clone())?;
|
||||
|
@ -760,7 +744,8 @@ mod test {
|
|||
|
||||
let obj = sut.get(node).unwrap();
|
||||
|
||||
assert_eq!(Some((&sym, IdentKind::Meta, Some(src))), obj.given_ident);
|
||||
assert_eq!(Some(&sym), obj.given_missing);
|
||||
assert_eq!(Some((IdentKind::Meta, src)), obj.given_redeclare);
|
||||
assert_eq!(Some(fragment), obj.given_set_fragment);
|
||||
|
||||
Ok(())
|
||||
|
@ -775,10 +760,8 @@ mod test {
|
|||
let sym = symbol_dummy!(1, "sym");
|
||||
let dep = symbol_dummy!(2, "dep");
|
||||
|
||||
let symnode =
|
||||
sut.declare(&sym, IdentKind::Meta, Some(Source::default()))?;
|
||||
let depnode =
|
||||
sut.declare(&dep, IdentKind::Meta, Some(Source::default()))?;
|
||||
let symnode = sut.declare(&sym, IdentKind::Meta, Source::default())?;
|
||||
let depnode = sut.declare(&dep, IdentKind::Meta, Source::default())?;
|
||||
|
||||
sut.add_dep(symnode, depnode);
|
||||
assert!(sut.has_dep(symnode, depnode));
|
||||
|
@ -798,8 +781,8 @@ mod test {
|
|||
let sym = symbol_dummy!(1, "sym");
|
||||
let dep = symbol_dummy!(2, "dep");
|
||||
|
||||
let _ = sut.declare(&sym, IdentKind::Meta, Some(Source::default()))?;
|
||||
let _ = sut.declare(&dep, IdentKind::Meta, Some(Source::default()))?;
|
||||
let _ = sut.declare(&sym, IdentKind::Meta, Source::default())?;
|
||||
let _ = sut.declare(&dep, IdentKind::Meta, Source::default())?;
|
||||
|
||||
let (symnode, depnode) = sut.add_dep_lookup(&sym, &dep);
|
||||
assert!(sut.has_dep(symnode, depnode));
|
||||
|
@ -840,14 +823,14 @@ mod test {
|
|||
};
|
||||
|
||||
// Check with a declared value
|
||||
let declared = sut.declare(&sym, IdentKind::Meta, Some(src.clone()))?;
|
||||
let declared = sut.declare(&sym, IdentKind::Meta, src.clone())?;
|
||||
|
||||
assert_eq!(symnode, declared);
|
||||
|
||||
let obj = sut.get(declared).unwrap();
|
||||
|
||||
assert_eq!(Some(&sym), obj.given_missing);
|
||||
assert_eq!(Some((IdentKind::Meta, Some(src))), obj.given_redeclare);
|
||||
assert_eq!(Some((IdentKind::Meta, src)), obj.given_redeclare);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -873,7 +856,7 @@ mod test {
|
|||
|
||||
let sym = symbol_dummy!(i, stringify!($name));
|
||||
|
||||
$sut.declare(&sym, $kind, Some(Source::default()))?;
|
||||
$sut.declare(&sym, $kind, Source::default())?;
|
||||
let (_, _) = $sut.add_dep_lookup($base, &sym);
|
||||
|
||||
$dest.push(sym);
|
||||
|
@ -892,7 +875,7 @@ mod test {
|
|||
|
||||
let base = symbol_dummy!(1, "sym1");
|
||||
let base_node =
|
||||
sut.declare(&base, IdentKind::Map, Some(Source::default()))?;
|
||||
sut.declare(&base, IdentKind::Map, Source::default())?;
|
||||
|
||||
add_syms!(sut, &base, {
|
||||
meta <- meta1: IdentKind::Meta,
|
||||
|
@ -935,10 +918,10 @@ mod test {
|
|||
let sym_node = sut.declare(
|
||||
&sym,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym_node, FragmentText::from("foo"))?;
|
||||
|
@ -982,19 +965,19 @@ mod test {
|
|||
let sym_node = sut.declare(
|
||||
&sym,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let dep_node = sut.declare(
|
||||
&dep,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym_node, FragmentText::from("foo"))?;
|
||||
|
@ -1028,37 +1011,37 @@ mod test {
|
|||
let sym_node = sut.declare(
|
||||
&sym,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym2_node = sut.declare(
|
||||
&sym2,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let dep_node = sut.declare(
|
||||
&dep,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let dep2_node = sut.declare(
|
||||
&dep2,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym_node, FragmentText::from("foo"))?;
|
||||
|
@ -1096,19 +1079,19 @@ mod test {
|
|||
let sym_node = sut.declare(
|
||||
&sym,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let dep_node = sut.declare(
|
||||
&dep,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym_node, FragmentText::from("foo"))?;
|
||||
|
@ -1138,28 +1121,28 @@ mod test {
|
|||
let sym1_node = sut.declare(
|
||||
&sym1,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym2_node = sut.declare(
|
||||
&sym2,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym3_node = sut.declare(
|
||||
&sym3,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym1_node, FragmentText::from("foo"))?;
|
||||
|
@ -1195,28 +1178,28 @@ mod test {
|
|||
let sym1_node = sut.declare(
|
||||
&sym1,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym2_node = sut.declare(
|
||||
&sym2,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym3_node = sut.declare(
|
||||
&sym3,
|
||||
IdentKind::Func(Dim::default(), SymDtype::Empty),
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym1_node, FragmentText::from("foo"))?;
|
||||
|
@ -1251,28 +1234,28 @@ mod test {
|
|||
let sym1_node = sut.declare(
|
||||
&sym1,
|
||||
IdentKind::Func(Dim::default(), SymDtype::Empty),
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym2_node = sut.declare(
|
||||
&sym2,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym3_node = sut.declare(
|
||||
&sym3,
|
||||
IdentKind::Func(Dim::default(), SymDtype::Empty),
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym1_node, FragmentText::from("foo"))?;
|
||||
|
@ -1306,19 +1289,19 @@ mod test {
|
|||
let sym_node = sut.declare(
|
||||
&sym,
|
||||
IdentKind::Func(Dim::default(), SymDtype::Empty),
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let dep_node = sut.declare(
|
||||
&dep,
|
||||
IdentKind::Func(Dim::default(), SymDtype::Empty),
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym_node, FragmentText::from("foo"))?;
|
||||
|
@ -1348,28 +1331,28 @@ mod test {
|
|||
let sym1_node = sut.declare(
|
||||
&sym1,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym2_node = sut.declare(
|
||||
&sym2,
|
||||
IdentKind::Func(Dim::default(), SymDtype::Empty),
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let sym3_node = sut.declare(
|
||||
&sym3,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym1_node, FragmentText::from("foo"))?;
|
||||
|
@ -1404,28 +1387,28 @@ mod test {
|
|||
let sym_node = sut.declare(
|
||||
&sym,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let dep_node = sut.declare(
|
||||
&dep,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
let ignored_node = sut.declare(
|
||||
&ignored,
|
||||
IdentKind::Tpl,
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)?;
|
||||
|
||||
sut.set_fragment(sym_node, FragmentText::from("foo"))?;
|
||||
|
|
|
@ -63,12 +63,6 @@ where
|
|||
/// otherwise,
|
||||
/// the existing identifier will be returned.
|
||||
///
|
||||
/// If `src` is omitted,
|
||||
/// then an abstract identifier (an _extern_) is declared.
|
||||
/// Externs are identifiers that are expected to be defined somewhere
|
||||
/// else ("externally"),
|
||||
/// and are resolved at [link-time][crate::ld].
|
||||
///
|
||||
/// If a concrete identifier has already been declared (see
|
||||
/// [`Asg::declare`]),
|
||||
/// then extern declarations will be compared and,
|
||||
|
@ -87,7 +81,7 @@ where
|
|||
&mut self,
|
||||
name: &'i Symbol<'i>,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
src: Source<'i>,
|
||||
) -> AsgResult<ObjectRef<Ix>, Ix>;
|
||||
|
||||
/// Declare an abstract identifier.
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
//! let identa_sym = interner.intern("identa");
|
||||
//! let identb_sym = interner.intern("identb");
|
||||
//!
|
||||
//! let identa = asg.declare(identa_sym, IdentKind::Meta, Some(Source::default()))?;
|
||||
//! let identa = asg.declare(identa_sym, IdentKind::Meta, Source::default())?;
|
||||
//! let identb = asg.declare_extern(identb_sym, IdentKind::Meta, Source::default())?;
|
||||
//!
|
||||
//! assert_eq!(
|
||||
|
@ -133,7 +133,7 @@
|
|||
//!
|
||||
//! // Once declared, the missing identifier changes state and dependencies
|
||||
//! // are retained.
|
||||
//! asg.declare(identa_sym, IdentKind::Meta, Some(Source::default()))?;
|
||||
//! asg.declare(identa_sym, IdentKind::Meta, Source::default())?;
|
||||
//!
|
||||
//! assert_eq!(
|
||||
//! Some(&IdentObject::Ident(identa_sym, IdentKind::Meta, Source::default())),
|
||||
|
@ -168,7 +168,7 @@
|
|||
//! #
|
||||
//! // Fragments can be attached to resolved identifiers.
|
||||
//! let ident = asg.declare(
|
||||
//! interner.intern("ident"), IdentKind::Meta, Some(Source::default())
|
||||
//! interner.intern("ident"), IdentKind::Meta, Source::default()
|
||||
//! )?;
|
||||
//! asg.set_fragment(ident, FragmentText::from("test fragment"))?;
|
||||
//!
|
||||
|
|
|
@ -189,22 +189,15 @@ where
|
|||
fn missing(ident: &'i Symbol<'i>) -> T;
|
||||
|
||||
/// Produce an object representing a concrete identifier.
|
||||
fn ident(
|
||||
name: &'i Symbol<'i>,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
) -> T;
|
||||
fn ident(name: &'i Symbol<'i>, kind: IdentKind, src: Source<'i>) -> T;
|
||||
|
||||
/// Attempt to redeclare an identifier with additional information.
|
||||
///
|
||||
/// For specific information on compatibility rules,
|
||||
/// see implementers of this trait,
|
||||
/// since rules may vary between implementations.
|
||||
fn redeclare(
|
||||
self,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
) -> TransitionResult<T>;
|
||||
fn redeclare(self, kind: IdentKind, src: Source<'i>)
|
||||
-> TransitionResult<T>;
|
||||
|
||||
/// Resolve identifier against an extern declaration.
|
||||
///
|
||||
|
@ -238,15 +231,8 @@ impl<'i> IdentObjectState<'i, IdentObject<'i>> for IdentObject<'i> {
|
|||
IdentObject::Missing(ident)
|
||||
}
|
||||
|
||||
fn ident(
|
||||
name: &'i Symbol<'i>,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
) -> Self {
|
||||
match src {
|
||||
Some(s) => IdentObject::Ident(name, kind, s),
|
||||
None => IdentObject::Extern(name, kind),
|
||||
}
|
||||
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.
|
||||
|
@ -270,48 +256,44 @@ impl<'i> IdentObjectState<'i, IdentObject<'i>> for IdentObject<'i> {
|
|||
fn redeclare(
|
||||
mut self,
|
||||
kind: IdentKind,
|
||||
src: Option<Source<'i>>,
|
||||
src: Source<'i>,
|
||||
) -> TransitionResult<IdentObject<'i>> {
|
||||
match src {
|
||||
// TODO: remove
|
||||
None => self.extern_(kind, Source::default()),
|
||||
Some(new_src) => match self {
|
||||
IdentObject::Ident(_, _, ref mut orig_src)
|
||||
if orig_src.virtual_ && new_src.override_ =>
|
||||
{
|
||||
*orig_src = new_src;
|
||||
Ok(self)
|
||||
match self {
|
||||
IdentObject::Ident(_, _, ref mut orig_src)
|
||||
if orig_src.virtual_ && src.override_ =>
|
||||
{
|
||||
*orig_src = src;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
IdentObject::Extern(name, ref orig_kind) => {
|
||||
if orig_kind != &kind {
|
||||
let err = TransitionError::ExternResolution {
|
||||
name: name.to_string(),
|
||||
expected: orig_kind.clone(),
|
||||
given: kind.clone(),
|
||||
};
|
||||
|
||||
return Err((self, err));
|
||||
}
|
||||
|
||||
IdentObject::Extern(name, ref orig_kind) => {
|
||||
if orig_kind != &kind {
|
||||
let err = TransitionError::ExternResolution {
|
||||
name: name.to_string(),
|
||||
expected: orig_kind.clone(),
|
||||
given: kind.clone(),
|
||||
};
|
||||
Ok(IdentObject::Ident(name, kind, src))
|
||||
}
|
||||
|
||||
return Err((self, err));
|
||||
}
|
||||
// TODO: no override-override
|
||||
IdentObject::IdentFragment(name, _, orig_src, _)
|
||||
if orig_src.virtual_ && src.override_ =>
|
||||
{
|
||||
// clears fragment, which is no longer applicable
|
||||
Ok(IdentObject::Ident(name, kind, src))
|
||||
}
|
||||
|
||||
Ok(IdentObject::Ident(name, kind, new_src))
|
||||
}
|
||||
IdentObject::Missing(name) | IdentObject::Ident(name, _, _) => {
|
||||
Ok(IdentObject::Ident(name, kind, src))
|
||||
}
|
||||
|
||||
// TODO: no override-override
|
||||
IdentObject::IdentFragment(name, _, orig_src, _)
|
||||
if orig_src.virtual_ && new_src.override_ =>
|
||||
{
|
||||
// clears fragment, which is no longer applicable
|
||||
Ok(IdentObject::Ident(name, kind, new_src))
|
||||
}
|
||||
|
||||
IdentObject::Missing(name) | IdentObject::Ident(name, _, _) => {
|
||||
Ok(IdentObject::Ident(name, kind, new_src))
|
||||
}
|
||||
|
||||
// TODO
|
||||
_ => Ok(self),
|
||||
},
|
||||
// TODO
|
||||
_ => Ok(self),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,7 +705,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
IdentObject::Ident(&sym, kind.clone(), src.clone()),
|
||||
IdentObject::ident(&sym, kind.clone(), Some(src.clone())),
|
||||
IdentObject::ident(&sym, kind.clone(), src.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -758,7 +740,7 @@ mod test {
|
|||
// Compatible kind, should resolve.
|
||||
let result = IdentObject::missing(&sym)
|
||||
.extern_(kind.clone(), Source::default())
|
||||
.and_then(|o| o.redeclare(kind.clone(), Some(src.clone())));
|
||||
.and_then(|o| o.redeclare(kind.clone(), src.clone()));
|
||||
|
||||
assert_eq!(Ok(IdentObject::Ident(&sym, kind, src)), result,);
|
||||
}
|
||||
|
@ -775,7 +757,7 @@ mod test {
|
|||
|
||||
// Compatible kind, should resolve.
|
||||
let result =
|
||||
IdentObject::ident(&sym, kind.clone(), Some(src.clone()))
|
||||
IdentObject::ident(&sym, kind.clone(), src.clone())
|
||||
.extern_(kind.clone(), Source::default());
|
||||
|
||||
assert_eq!(Ok(IdentObject::Ident(&sym, kind, src)), result,);
|
||||
|
@ -809,8 +791,7 @@ mod test {
|
|||
|
||||
// Incompatible kind
|
||||
let kind_bad = IdentKind::Meta;
|
||||
let result =
|
||||
orig.clone().redeclare(kind_bad.clone(), Some(src));
|
||||
let result = orig.clone().redeclare(kind_bad.clone(), src);
|
||||
|
||||
match result {
|
||||
Err((given_orig, err @ _)) => {
|
||||
|
@ -848,11 +829,8 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let orig = IdentObject::ident(
|
||||
&sym,
|
||||
kind_given.clone(),
|
||||
Some(src.clone()),
|
||||
);
|
||||
let orig =
|
||||
IdentObject::ident(&sym, kind_given.clone(), src.clone());
|
||||
|
||||
// Extern with incompatible kind.
|
||||
let kind_extern = IdentKind::Meta;
|
||||
|
@ -892,18 +870,15 @@ mod test {
|
|||
fn redeclare_returns_existing_compatible() {
|
||||
let sym = symbol_dummy!(1, "symdup");
|
||||
|
||||
let first = IdentObject::ident(
|
||||
&sym,
|
||||
IdentKind::Meta,
|
||||
Some(Source::default()),
|
||||
);
|
||||
let first =
|
||||
IdentObject::ident(&sym, IdentKind::Meta, Source::default());
|
||||
|
||||
// Same declaration a second time
|
||||
assert_eq!(
|
||||
Ok(first.clone()),
|
||||
first.clone().redeclare(
|
||||
first.kind().unwrap().clone(),
|
||||
Some(first.src().unwrap().clone()),
|
||||
first.src().unwrap().clone(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -917,8 +892,7 @@ mod test {
|
|||
};
|
||||
|
||||
let kind = IdentKind::Meta;
|
||||
let ident =
|
||||
IdentObject::ident(&sym, kind.clone(), Some(src.clone()));
|
||||
let ident = IdentObject::ident(&sym, kind.clone(), src.clone());
|
||||
let text = FragmentText::from("a fragment");
|
||||
let ident_with_frag = ident.set_fragment(text.clone());
|
||||
|
||||
|
@ -931,11 +905,8 @@ mod test {
|
|||
#[test]
|
||||
fn add_fragment_to_fragment_fails() {
|
||||
let sym = symbol_dummy!(1, "badsym");
|
||||
let ident = IdentObject::ident(
|
||||
&sym,
|
||||
IdentKind::Meta,
|
||||
Some(Source::default()),
|
||||
);
|
||||
let ident =
|
||||
IdentObject::ident(&sym, IdentKind::Meta, Source::default());
|
||||
|
||||
let ident_with_frag = ident
|
||||
.set_fragment("orig fragment".into())
|
||||
|
@ -970,10 +941,10 @@ mod test {
|
|||
let virt = IdentObject::ident(
|
||||
&sym,
|
||||
kind.clone(),
|
||||
Some(Source {
|
||||
Source {
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
let over_src = Source {
|
||||
|
@ -982,7 +953,7 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let result = virt.redeclare(kind.clone(), Some(over_src.clone()));
|
||||
let result = virt.redeclare(kind.clone(), over_src.clone());
|
||||
|
||||
assert_eq!(Ok(IdentObject::Ident(&sym, kind, over_src)), result);
|
||||
}
|
||||
|
@ -999,8 +970,7 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let virt =
|
||||
IdentObject::ident(&sym, kind.clone(), Some(virt_src.clone()));
|
||||
let virt = IdentObject::ident(&sym, kind.clone(), virt_src.clone());
|
||||
let text = FragmentText::from("remove me");
|
||||
let virt_frag = virt.set_fragment(text.clone());
|
||||
|
||||
|
@ -1020,9 +990,8 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let result = virt_frag
|
||||
.unwrap()
|
||||
.redeclare(kind.clone(), Some(over_src.clone()));
|
||||
let result =
|
||||
virt_frag.unwrap().redeclare(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
|
||||
|
@ -1038,7 +1007,7 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let obj = IdentObject::ident(&sym, given, Some(src.clone()));
|
||||
let obj = IdentObject::ident(&sym, given, src.clone());
|
||||
|
||||
let fragment = "a fragment".to_string();
|
||||
let obj_with_frag = obj.set_fragment(fragment.clone());
|
||||
|
|
|
@ -201,11 +201,8 @@ fn load_xmlo<'a, 'i, I: Interner<'i>>(
|
|||
if extern_ {
|
||||
depgraph.declare_extern(sym, kindval, src)?;
|
||||
} else {
|
||||
let node = depgraph.declare(
|
||||
sym,
|
||||
kindval,
|
||||
Some(src),
|
||||
)?;
|
||||
let node =
|
||||
depgraph.declare(sym, kindval, src)?;
|
||||
|
||||
if link_root {
|
||||
roots.push(node);
|
||||
|
|
Loading…
Reference in New Issue