tamer: Remove Ix generalization throughout system
This had the writing on the wall all the same as the `'i` interner lifetime that came before it. It was too much of a maintenance burden trying to accommodate both 16-bit and 32-bit symbols generically. There is a situation where we do still want 16-bit symbols---the `Span`. Therefore, I have left generic support for symbol sizes, as well as the different global interners, but `SymbolId` now defaults to 32-bit, as does `Asg`. Further, the size parameter has been removed from the rest of the code, with the exception of `Span`. This cleans things up quite a bit, and is much nicer to work with. If we want 16-bit symbols in the future for packing to increase CPU cache performance, we can handle that situation then in that specific case; it's a premature optimization that's not at all worth the effort here.main
parent
ed245bb099
commit
e91aeef478
|
@ -29,25 +29,15 @@ extern crate test;
|
|||
use test::Bencher;
|
||||
|
||||
mod base {
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::*;
|
||||
use tamer::global;
|
||||
use tamer::ir::asg::{
|
||||
Asg, DataType, DefaultAsg, IdentKind, IdentObject, SortableAsg, Source,
|
||||
};
|
||||
use tamer::sym::{GlobalSymbolIntern, SymbolId, SymbolIndexSize};
|
||||
use tamer::sym::{GlobalSymbolIntern, SymbolId};
|
||||
|
||||
type Sut =
|
||||
DefaultAsg<IdentObject<global::PkgSymSize>, global::PkgIdentSize>;
|
||||
type SutProg<'i> =
|
||||
DefaultAsg<IdentObject<global::ProgSymSize>, global::ProgIdentSize>;
|
||||
type Sut = DefaultAsg<IdentObject>;
|
||||
|
||||
fn interned_n<Ix: SymbolIndexSize>(n: u16) -> Vec<SymbolId<Ix>>
|
||||
where
|
||||
<Ix as TryFrom<usize>>::Error: Debug,
|
||||
{
|
||||
fn interned_n(n: u16) -> Vec<SymbolId> {
|
||||
(0..n).map(|i| i.to_string().intern()).collect()
|
||||
}
|
||||
|
||||
|
@ -75,10 +65,9 @@ mod base {
|
|||
});
|
||||
}
|
||||
|
||||
// The Ix size affects memory, but how about performance?
|
||||
#[bench]
|
||||
fn declare_1_000_prog_ident_size(bench: &mut Bencher) {
|
||||
let mut sut = SutProg::new();
|
||||
let mut sut = Sut::new();
|
||||
let xs = interned_n(1_000);
|
||||
|
||||
bench.iter(|| {
|
||||
|
@ -390,13 +379,12 @@ mod object {
|
|||
|
||||
mod ident {
|
||||
use super::*;
|
||||
use tamer::global;
|
||||
use tamer::ir::asg::{
|
||||
IdentKind, IdentObject, IdentObjectData, IdentObjectState, Source,
|
||||
};
|
||||
use tamer::sym::GlobalSymbolIntern;
|
||||
|
||||
type Sut = IdentObject<global::ProgSymSize>;
|
||||
type Sut = IdentObject;
|
||||
|
||||
#[bench]
|
||||
fn declare_1_000(bench: &mut Bencher) {
|
||||
|
|
|
@ -228,7 +228,7 @@ mod interner {
|
|||
|
||||
bench.iter(|| {
|
||||
strs.iter()
|
||||
.map::<ProgSymbolId, _>(|s| s.intern())
|
||||
.map::<SymbolId, _>(|s| s.intern())
|
||||
.for_each(drop);
|
||||
});
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ mod interner {
|
|||
fn with_one_new_1000(bench: &mut Bencher) {
|
||||
bench.iter(|| {
|
||||
(0..1000)
|
||||
.map::<ProgSymbolId, _>(|_| "onenew".intern())
|
||||
.map::<SymbolId, _>(|_| "onenew".intern())
|
||||
.for_each(drop);
|
||||
});
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ mod interner {
|
|||
fn with_one_new_1000_utf8_unchecked(bench: &mut Bencher) {
|
||||
bench.iter(|| {
|
||||
(0..1000)
|
||||
.map::<ProgSymbolId, _>(|_| unsafe {
|
||||
.map::<SymbolId, _>(|_| unsafe {
|
||||
(b"onenewu8").intern_utf8_unchecked()
|
||||
})
|
||||
.for_each(drop);
|
||||
|
|
|
@ -44,8 +44,6 @@ use tamer::ir::xir::{NCName, QName, Token};
|
|||
use tamer::sym::{GlobalSymbolIntern, GlobalSymbolResolve, SymbolId};
|
||||
use test::Bencher;
|
||||
|
||||
type Ix = tamer::global::PkgSymSize;
|
||||
|
||||
fn gen_strs(n: usize, suffix: &str) -> Vec<String> {
|
||||
(0..n).map(|n| n.to_string() + suffix).collect()
|
||||
}
|
||||
|
@ -62,7 +60,7 @@ mod name {
|
|||
|
||||
bench.iter(|| {
|
||||
strs.iter()
|
||||
.map(|s| s.as_str().intern() as SymbolId<Ix>)
|
||||
.map(|s| s.as_str().intern() as SymbolId)
|
||||
.for_each(drop);
|
||||
});
|
||||
}
|
||||
|
@ -74,9 +72,7 @@ mod name {
|
|||
|
||||
bench.iter(|| {
|
||||
strs.iter()
|
||||
.map(|s| unsafe {
|
||||
NCName::<Ix>::new_unchecked(s.as_str().intern())
|
||||
})
|
||||
.map(|s| unsafe { NCName::new_unchecked(s.as_str().intern()) })
|
||||
.for_each(drop);
|
||||
});
|
||||
}
|
||||
|
@ -100,7 +96,7 @@ mod name {
|
|||
|
||||
bench.iter(|| {
|
||||
strs.iter()
|
||||
.map(|s| NCName::<Ix>::try_from(s.as_str()))
|
||||
.map(|s| NCName::try_from(s.as_str()))
|
||||
.for_each(drop);
|
||||
});
|
||||
}
|
||||
|
@ -115,7 +111,7 @@ mod name {
|
|||
prefixes
|
||||
.iter()
|
||||
.zip(names.iter())
|
||||
.map(|(p, s)| QName::<Ix>::try_from((p.as_str(), s.as_str())))
|
||||
.map(|(p, s)| QName::try_from((p.as_str(), s.as_str())))
|
||||
.for_each(drop);
|
||||
});
|
||||
}
|
||||
|
@ -129,7 +125,7 @@ mod ws {
|
|||
fn whitespace_1000(bench: &mut Bencher) {
|
||||
bench.iter(|| {
|
||||
(0..1000)
|
||||
.map(|_| Whitespace::<Ix>::try_from(" \t "))
|
||||
.map(|_| Whitespace::try_from(" \t "))
|
||||
.for_each(drop);
|
||||
});
|
||||
}
|
||||
|
@ -203,7 +199,7 @@ This is pretend fragment text. We need a lot of it.</fragment>
|
|||
// common values such as these (QNames) will be pre-defined and
|
||||
// reused.
|
||||
let span = Span::from_byte_interval((0, 0), "path".intern());
|
||||
let name = QName::<Ix>::try_from(("test", "foo")).unwrap();
|
||||
let name = QName::try_from(("test", "foo")).unwrap();
|
||||
let attr1 = QName::new_local("first".try_into().unwrap());
|
||||
let attr2 = QName::new_local("second".try_into().unwrap());
|
||||
let val1 = "value".intern();
|
||||
|
@ -233,7 +229,7 @@ This is pretend fragment text. We need a lot of it.</fragment>
|
|||
let buf = Vec::<u8>::with_capacity(FRAGMENT.len() * 50);
|
||||
let mut writer = QuickXmlWriter::new(buf);
|
||||
|
||||
let frag: SymbolId<Ix> = FRAGMENT.intern();
|
||||
let frag: SymbolId = FRAGMENT.intern();
|
||||
|
||||
bench.iter(|| {
|
||||
(0..50).for_each(|_| {
|
||||
|
@ -251,7 +247,7 @@ This is pretend fragment text. We need a lot of it.</fragment>
|
|||
#[bench]
|
||||
fn xir_text_50(bench: &mut Bencher) {
|
||||
let mut buf = Vec::<u8>::with_capacity(FRAGMENT.len() * 50);
|
||||
let frag: SymbolId<Ix> = FRAGMENT.intern();
|
||||
let frag: SymbolId = FRAGMENT.intern();
|
||||
let span = Span::from_byte_interval((0, 0), "path".intern());
|
||||
|
||||
bench.iter(|| {
|
||||
|
|
|
@ -35,19 +35,12 @@
|
|||
|
||||
use std::{mem::size_of, num};
|
||||
|
||||
/// A size capable of representing every interned string in a package.
|
||||
pub type PkgSymSize = u16;
|
||||
const_assert!(size_of::<PkgSymSize>() <= size_of::<ProgSymSize>());
|
||||
|
||||
/// A non-zero equivalent of [`PkgSymSize`];
|
||||
pub type NonZeroPkgSymSize = num::NonZeroU16;
|
||||
/// The initial capacity for global interners.
|
||||
pub const INIT_GLOBAL_INTERNER_CAPACITY: usize = 1024;
|
||||
|
||||
/// A size capable of representing every interned string in a program.
|
||||
pub type ProgSymSize = u32;
|
||||
|
||||
/// The initial capacity for global interners.
|
||||
pub const INIT_GLOBAL_INTERNER_CAPACITY: usize = 1024;
|
||||
|
||||
/// A non-zero equivalent of [`ProgSymSize`];
|
||||
pub type NonZeroProgSymSize = num::NonZeroU32;
|
||||
|
||||
|
@ -66,30 +59,6 @@ pub type SourceFileSize = u32;
|
|||
pub type FrontendTokenLength = u16;
|
||||
const_assert!(size_of::<FrontendTokenLength>() <= size_of::<SourceFileSize>());
|
||||
|
||||
/// A size capable of representing indexes of each individual identifier
|
||||
/// within a single package.
|
||||
///
|
||||
/// Note that,
|
||||
/// since TAME is a metalanguage and can easily expand into a great
|
||||
/// deal of code,
|
||||
/// this must accommodate far more than the user's expectations
|
||||
/// working within the provided level of abstraction.
|
||||
///
|
||||
/// This must be ≥ [`PkgSymSize`].
|
||||
pub type PkgIdentSize = u16;
|
||||
const_assert!(size_of::<PkgIdentSize>() >= size_of::<PkgSymSize>());
|
||||
|
||||
/// A size capable of representing every individual identifier and
|
||||
/// expression within a single package.
|
||||
///
|
||||
/// Note that,
|
||||
/// since TAME is a metalanguage and can easily expand into a great
|
||||
/// deal of code,
|
||||
/// this must accommodate far more than the user's expectations
|
||||
/// working within the provided level of abstraction.
|
||||
pub type PkgIdentExprSize = u32;
|
||||
const_assert!(size_of::<PkgIdentExprSize>() <= size_of::<ProgIdentExprSize>());
|
||||
|
||||
/// A size capable of representing the union of every identifier of every
|
||||
/// package used by an entire program.
|
||||
///
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
|
||||
//! Base concrete [`Asg`] implementation.
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::graph::{
|
||||
Asg, AsgEdge, AsgResult, IndexType, Node, ObjectRef, SortableAsg,
|
||||
SortableAsgError, SortableAsgResult,
|
||||
|
@ -31,7 +28,7 @@ use super::object::{
|
|||
FragmentText, IdentObjectData, IdentObjectState, Source, TransitionResult,
|
||||
};
|
||||
use super::Sections;
|
||||
use crate::sym::{GlobalSymbolResolve, SymbolId, SymbolIndexSize};
|
||||
use crate::sym::{GlobalSymbolResolve, SymbolId};
|
||||
use petgraph::graph::{DiGraph, Graph, NodeIndex};
|
||||
use petgraph::visit::DfsPostOrder;
|
||||
|
||||
|
@ -47,7 +44,7 @@ use petgraph::visit::DfsPostOrder;
|
|||
/// see [`Asg`].
|
||||
pub struct BaseAsg<O, Ix>
|
||||
where
|
||||
Ix: IndexType + SymbolIndexSize,
|
||||
Ix: IndexType,
|
||||
{
|
||||
/// Directed graph on which objects are stored.
|
||||
graph: DiGraph<Node<O>, AsgEdge, Ix>,
|
||||
|
@ -66,9 +63,8 @@ where
|
|||
|
||||
impl<O, Ix> BaseAsg<O, Ix>
|
||||
where
|
||||
Ix: IndexType + SymbolIndexSize,
|
||||
<Ix as TryInto<usize>>::Error: Debug,
|
||||
O: IdentObjectState<Ix, O> + IdentObjectData<Ix>,
|
||||
Ix: IndexType,
|
||||
O: IdentObjectState<O> + IdentObjectData,
|
||||
{
|
||||
/// Create a new ASG.
|
||||
///
|
||||
|
@ -118,7 +114,7 @@ where
|
|||
/// Panics
|
||||
/// ======
|
||||
/// Will panic if unable to allocate more space for the index.
|
||||
fn index_identifier(&mut self, name: SymbolId<Ix>, node: NodeIndex<Ix>) {
|
||||
fn index_identifier(&mut self, name: SymbolId, node: NodeIndex<Ix>) {
|
||||
let i = name.as_usize();
|
||||
|
||||
if i >= self.index.len() {
|
||||
|
@ -141,7 +137,7 @@ where
|
|||
/// reference to it.
|
||||
///
|
||||
/// See [`IdentObjectState::declare`] for more information.
|
||||
fn lookup_or_missing(&mut self, ident: SymbolId<Ix>) -> ObjectRef<Ix> {
|
||||
fn lookup_or_missing(&mut self, ident: SymbolId) -> ObjectRef<Ix> {
|
||||
self.lookup(ident).unwrap_or_else(|| {
|
||||
let index = self.graph.add_node(Some(O::declare(ident)));
|
||||
|
||||
|
@ -161,7 +157,7 @@ where
|
|||
/// value on transition failure.
|
||||
fn with_ident_lookup<F>(
|
||||
&mut self,
|
||||
name: SymbolId<Ix>,
|
||||
name: SymbolId,
|
||||
f: F,
|
||||
) -> AsgResult<ObjectRef<Ix>>
|
||||
where
|
||||
|
@ -206,24 +202,23 @@ where
|
|||
|
||||
impl<O, Ix> Asg<O, Ix> for BaseAsg<O, Ix>
|
||||
where
|
||||
Ix: IndexType + SymbolIndexSize,
|
||||
<Ix as TryInto<usize>>::Error: Debug,
|
||||
O: IdentObjectState<Ix, O> + IdentObjectData<Ix>,
|
||||
Ix: IndexType,
|
||||
O: IdentObjectState<O> + IdentObjectData,
|
||||
{
|
||||
fn declare(
|
||||
&mut self,
|
||||
name: SymbolId<Ix>,
|
||||
name: SymbolId,
|
||||
kind: IdentKind,
|
||||
src: Source<Ix>,
|
||||
src: Source,
|
||||
) -> AsgResult<ObjectRef<Ix>> {
|
||||
self.with_ident_lookup(name, |obj| obj.resolve(kind, src))
|
||||
}
|
||||
|
||||
fn declare_extern(
|
||||
&mut self,
|
||||
name: SymbolId<Ix>,
|
||||
name: SymbolId,
|
||||
kind: IdentKind,
|
||||
src: Source<Ix>,
|
||||
src: Source,
|
||||
) -> AsgResult<ObjectRef<Ix>> {
|
||||
self.with_ident_lookup(name, |obj| obj.extern_(kind, src))
|
||||
}
|
||||
|
@ -231,7 +226,7 @@ where
|
|||
fn set_fragment(
|
||||
&mut self,
|
||||
identi: ObjectRef<Ix>,
|
||||
text: FragmentText<Ix>,
|
||||
text: FragmentText,
|
||||
) -> AsgResult<ObjectRef<Ix>> {
|
||||
self.with_ident(identi, |obj| obj.set_fragment(text))
|
||||
}
|
||||
|
@ -245,7 +240,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn lookup(&self, name: SymbolId<Ix>) -> Option<ObjectRef<Ix>> {
|
||||
fn lookup(&self, name: SymbolId) -> Option<ObjectRef<Ix>> {
|
||||
let i = name.as_usize();
|
||||
|
||||
self.index
|
||||
|
@ -266,8 +261,8 @@ where
|
|||
|
||||
fn add_dep_lookup(
|
||||
&mut self,
|
||||
ident: SymbolId<Ix>,
|
||||
dep: SymbolId<Ix>,
|
||||
ident: SymbolId,
|
||||
dep: SymbolId,
|
||||
) -> (ObjectRef<Ix>, ObjectRef<Ix>) {
|
||||
let identi = self.lookup_or_missing(ident);
|
||||
let depi = self.lookup_or_missing(dep);
|
||||
|
@ -281,9 +276,8 @@ where
|
|||
|
||||
impl<O, Ix> SortableAsg<O, Ix> for BaseAsg<O, Ix>
|
||||
where
|
||||
Ix: IndexType + SymbolIndexSize,
|
||||
<Ix as TryInto<usize>>::Error: Debug,
|
||||
O: IdentObjectData<Ix> + IdentObjectState<Ix, O>,
|
||||
Ix: IndexType,
|
||||
O: IdentObjectData + IdentObjectState<O>,
|
||||
{
|
||||
fn sort<'i>(
|
||||
&'i self,
|
||||
|
@ -345,9 +339,8 @@ where
|
|||
/// they are, we ignore the cycle, otherwise we will return an error.
|
||||
fn check_cycles<O, Ix>(asg: &BaseAsg<O, Ix>) -> SortableAsgResult<(), Ix>
|
||||
where
|
||||
Ix: IndexType + SymbolIndexSize,
|
||||
<Ix as TryInto<usize>>::Error: Debug,
|
||||
O: IdentObjectData<Ix> + IdentObjectState<Ix, O>,
|
||||
Ix: IndexType,
|
||||
O: IdentObjectData + IdentObjectState<O>,
|
||||
{
|
||||
// While `tarjan_scc` does do a topological sort, it does not suit our
|
||||
// needs because we need to filter out some allowed cycles. It would
|
||||
|
@ -403,22 +396,20 @@ mod test {
|
|||
use crate::sym::{GlobalSymbolIntern, SymbolStr};
|
||||
use std::cell::RefCell;
|
||||
|
||||
type Ix = u16;
|
||||
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
struct StubIdentObject {
|
||||
given_declare: Option<SymbolId<Ix>>,
|
||||
given_extern: Option<(IdentKind, Source<Ix>)>,
|
||||
given_resolve: Option<(IdentKind, Source<Ix>)>,
|
||||
given_set_fragment: Option<FragmentText<Ix>>,
|
||||
given_declare: Option<SymbolId>,
|
||||
given_extern: Option<(IdentKind, Source)>,
|
||||
given_resolve: Option<(IdentKind, Source)>,
|
||||
given_set_fragment: Option<FragmentText>,
|
||||
fail_redeclare: RefCell<Option<TransitionError>>,
|
||||
fail_extern: RefCell<Option<TransitionError>>,
|
||||
fail_set_fragment: RefCell<Option<TransitionError>>,
|
||||
fail_resolved: RefCell<Option<UnresolvedError>>,
|
||||
}
|
||||
|
||||
impl<'i> IdentObjectData<Ix> for StubIdentObject {
|
||||
fn name(&self) -> Option<SymbolId<Ix>> {
|
||||
impl<'i> IdentObjectData for StubIdentObject {
|
||||
fn name(&self) -> Option<SymbolId> {
|
||||
self.given_declare
|
||||
}
|
||||
|
||||
|
@ -426,21 +417,21 @@ mod test {
|
|||
self.given_resolve.as_ref().map(|args| &args.0)
|
||||
}
|
||||
|
||||
fn src(&self) -> Option<&Source<Ix>> {
|
||||
fn src(&self) -> Option<&Source> {
|
||||
None
|
||||
}
|
||||
|
||||
fn fragment(&self) -> Option<&FragmentText<Ix>> {
|
||||
fn fragment(&self) -> Option<&FragmentText> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_ident(&self) -> Option<&IdentObject<Ix>> {
|
||||
fn as_ident(&self) -> Option<&IdentObject> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'i> IdentObjectState<Ix, StubIdentObject> for StubIdentObject {
|
||||
fn declare(ident: SymbolId<Ix>) -> Self {
|
||||
impl<'i> IdentObjectState<StubIdentObject> for StubIdentObject {
|
||||
fn declare(ident: SymbolId) -> Self {
|
||||
Self {
|
||||
given_declare: Some(ident),
|
||||
..Default::default()
|
||||
|
@ -450,7 +441,7 @@ mod test {
|
|||
fn resolve(
|
||||
mut self,
|
||||
kind: IdentKind,
|
||||
src: Source<Ix>,
|
||||
src: Source,
|
||||
) -> TransitionResult<StubIdentObject> {
|
||||
if self.fail_redeclare.borrow().is_some() {
|
||||
let err = self.fail_redeclare.replace(None).unwrap();
|
||||
|
@ -472,7 +463,7 @@ mod test {
|
|||
fn extern_(
|
||||
mut self,
|
||||
kind: IdentKind,
|
||||
src: Source<Ix>,
|
||||
src: Source,
|
||||
) -> TransitionResult<StubIdentObject> {
|
||||
if self.fail_extern.borrow().is_some() {
|
||||
let err = self.fail_extern.replace(None).unwrap();
|
||||
|
@ -485,7 +476,7 @@ mod test {
|
|||
|
||||
fn set_fragment(
|
||||
mut self,
|
||||
text: FragmentText<Ix>,
|
||||
text: FragmentText,
|
||||
) -> TransitionResult<StubIdentObject> {
|
||||
if self.fail_set_fragment.borrow().is_some() {
|
||||
let err = self.fail_set_fragment.replace(None).unwrap();
|
||||
|
|
|
@ -25,7 +25,7 @@ use super::object::{
|
|||
UnresolvedError,
|
||||
};
|
||||
use super::Sections;
|
||||
use crate::sym::{SymbolId, SymbolIndexSize};
|
||||
use crate::sym::SymbolId;
|
||||
use petgraph::graph::NodeIndex;
|
||||
use std::fmt::Debug;
|
||||
use std::result::Result;
|
||||
|
@ -48,8 +48,8 @@ impl<T: petgraph::graph::IndexType> IndexType for T {}
|
|||
/// see the [module-level documentation][self].
|
||||
pub trait Asg<O, Ix>
|
||||
where
|
||||
Ix: IndexType + SymbolIndexSize,
|
||||
O: IdentObjectState<Ix, O>,
|
||||
Ix: IndexType,
|
||||
O: IdentObjectState<O>,
|
||||
{
|
||||
/// Declare a concrete identifier.
|
||||
///
|
||||
|
@ -84,9 +84,9 @@ where
|
|||
/// and return an [`ObjectRef`] reference.
|
||||
fn declare(
|
||||
&mut self,
|
||||
name: SymbolId<Ix>,
|
||||
name: SymbolId,
|
||||
kind: IdentKind,
|
||||
src: Source<Ix>,
|
||||
src: Source,
|
||||
) -> AsgResult<ObjectRef<Ix>>;
|
||||
|
||||
/// Declare an abstract identifier.
|
||||
|
@ -111,9 +111,9 @@ where
|
|||
/// compatibility related to extern resolution.
|
||||
fn declare_extern(
|
||||
&mut self,
|
||||
name: SymbolId<Ix>,
|
||||
name: SymbolId,
|
||||
kind: IdentKind,
|
||||
src: Source<Ix>,
|
||||
src: Source,
|
||||
) -> AsgResult<ObjectRef<Ix>>;
|
||||
|
||||
/// Set the fragment associated with a concrete identifier.
|
||||
|
@ -124,7 +124,7 @@ where
|
|||
fn set_fragment(
|
||||
&mut self,
|
||||
identi: ObjectRef<Ix>,
|
||||
text: FragmentText<Ix>,
|
||||
text: FragmentText,
|
||||
) -> AsgResult<ObjectRef<Ix>>;
|
||||
|
||||
/// Retrieve an object from the graph by [`ObjectRef`].
|
||||
|
@ -142,7 +142,7 @@ where
|
|||
/// this method cannot be used to retrieve all possible objects on the
|
||||
/// graph---for
|
||||
/// that, see [`Asg::get`].
|
||||
fn lookup(&self, name: SymbolId<Ix>) -> Option<ObjectRef<Ix>>;
|
||||
fn lookup(&self, name: SymbolId) -> Option<ObjectRef<Ix>>;
|
||||
|
||||
/// Declare that `dep` is a dependency of `ident`.
|
||||
///
|
||||
|
@ -173,8 +173,8 @@ where
|
|||
/// References to both identifiers are returned in argument order.
|
||||
fn add_dep_lookup(
|
||||
&mut self,
|
||||
ident: SymbolId<Ix>,
|
||||
dep: SymbolId<Ix>,
|
||||
ident: SymbolId,
|
||||
dep: SymbolId,
|
||||
) -> (ObjectRef<Ix>, ObjectRef<Ix>);
|
||||
}
|
||||
|
||||
|
@ -184,8 +184,8 @@ where
|
|||
/// used as an `Intermediate Representation`.
|
||||
pub trait SortableAsg<O, Ix>
|
||||
where
|
||||
O: IdentObjectData<Ix>,
|
||||
Ix: IndexType + SymbolIndexSize,
|
||||
O: IdentObjectData,
|
||||
Ix: IndexType,
|
||||
{
|
||||
/// Sort graph into [`Sections`].
|
||||
///
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
|
||||
//! Identifiers (a type of [object][super::object::IdentObject]).
|
||||
|
||||
use crate::global;
|
||||
use crate::ir::legacyir::{SymAttrs, SymDtype, SymType};
|
||||
use crate::sym::{GlobalSymbolIntern, SymbolId, SymbolIndexSize};
|
||||
use crate::sym::{GlobalSymbolIntern, SymbolId};
|
||||
use paste::paste;
|
||||
use std::convert::TryFrom;
|
||||
use std::error::Error;
|
||||
|
@ -148,16 +147,14 @@ pub enum IdentKind {
|
|||
Worksheet,
|
||||
}
|
||||
|
||||
/// Produce [`AsRef`] impls for [`str`], [`global::ProgSymSize`] and
|
||||
/// [`global::PkgSymSize`] for identifier kind strings.
|
||||
/// Produce [`AsRef`] impls for [`str`] and [`global::ProgSymSize`] for
|
||||
/// identifier kind strings.
|
||||
macro_rules! kind_intern {
|
||||
($($variant:ident $($v:pat)? => $str:expr),*) => {
|
||||
paste! {
|
||||
lazy_static! {
|
||||
$(
|
||||
static ref [<PROG_KIND_ $variant:upper>]: SymbolId<global::ProgSymSize>
|
||||
= $str.intern();
|
||||
static ref [<PKG_KIND_ $variant:upper>]: SymbolId<global::PkgSymSize>
|
||||
static ref [<PROG_KIND_ $variant:upper>]: SymbolId
|
||||
= $str.intern();
|
||||
)*
|
||||
}
|
||||
|
@ -172,8 +169,8 @@ macro_rules! kind_intern {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsRef<SymbolId<global::ProgSymSize>> for IdentKind {
|
||||
fn as_ref(&self) -> &SymbolId<global::ProgSymSize> {
|
||||
impl AsRef<SymbolId> for IdentKind {
|
||||
fn as_ref(&self) -> &SymbolId {
|
||||
match self {
|
||||
$(
|
||||
Self::$variant$($v)* => &[<PROG_KIND_ $variant:upper>],
|
||||
|
@ -181,16 +178,6 @@ macro_rules! kind_intern {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<SymbolId<global::PkgSymSize>> for IdentKind {
|
||||
fn as_ref(&self) -> &SymbolId<global::PkgSymSize> {
|
||||
match self {
|
||||
$(
|
||||
Self::$variant$($v)* => &[<PKG_KIND_ $variant:upper>],
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -255,32 +242,26 @@ impl std::fmt::Display for IdentKind {
|
|||
}
|
||||
}
|
||||
|
||||
impl<Ix> TryFrom<SymAttrs<Ix>> for IdentKind
|
||||
where
|
||||
Ix: SymbolIndexSize,
|
||||
{
|
||||
impl TryFrom<SymAttrs> for IdentKind {
|
||||
type Error = IdentKindError;
|
||||
|
||||
/// Attempt to raise [`SymAttrs`] into an [`IdentKind`].
|
||||
///
|
||||
/// Certain [`IdentKind`] require that certain attributes be present,
|
||||
/// otherwise the conversion will fail.
|
||||
fn try_from(attrs: SymAttrs<Ix>) -> Result<Self, Self::Error> {
|
||||
fn try_from(attrs: SymAttrs) -> Result<Self, Self::Error> {
|
||||
Self::try_from(&attrs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Ix> TryFrom<&SymAttrs<Ix>> for IdentKind
|
||||
where
|
||||
Ix: SymbolIndexSize,
|
||||
{
|
||||
impl TryFrom<&SymAttrs> for IdentKind {
|
||||
type Error = IdentKindError;
|
||||
|
||||
/// Attempt to raise [`SymAttrs`] into an [`IdentKind`].
|
||||
///
|
||||
/// Certain [`IdentKind`] require that certain attributes be present,
|
||||
/// otherwise the conversion will fail.
|
||||
fn try_from(attrs: &SymAttrs<Ix>) -> Result<Self, Self::Error> {
|
||||
fn try_from(attrs: &SymAttrs) -> Result<Self, Self::Error> {
|
||||
let ty = attrs.ty.as_ref().ok_or(Self::Error::MissingType)?;
|
||||
|
||||
macro_rules! ident {
|
||||
|
@ -406,8 +387,6 @@ mod test {
|
|||
use super::*;
|
||||
use std::convert::TryInto;
|
||||
|
||||
type Ix = u16;
|
||||
|
||||
#[test]
|
||||
fn dim_from_u8() {
|
||||
let n = 5u8;
|
||||
|
@ -431,7 +410,7 @@ mod test {
|
|||
fn $name() {
|
||||
assert_eq!(
|
||||
Ok($dest),
|
||||
SymAttrs::<Ix> {
|
||||
SymAttrs {
|
||||
ty: Some($src),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -447,7 +426,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
Ok($dest(Dim(dim))),
|
||||
SymAttrs::<Ix> {
|
||||
SymAttrs {
|
||||
ty: Some($src),
|
||||
dim: Some(dim),
|
||||
..Default::default()
|
||||
|
@ -456,7 +435,7 @@ mod test {
|
|||
);
|
||||
|
||||
// no dim
|
||||
let result = IdentKind::try_from(SymAttrs::<Ix> {
|
||||
let result = IdentKind::try_from(SymAttrs {
|
||||
ty: Some($src),
|
||||
..Default::default()
|
||||
})
|
||||
|
@ -473,7 +452,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
Ok($dest(dtype)),
|
||||
SymAttrs::<Ix> {
|
||||
SymAttrs {
|
||||
ty: Some($src),
|
||||
dtype: Some(dtype),
|
||||
..Default::default()
|
||||
|
@ -482,7 +461,7 @@ mod test {
|
|||
);
|
||||
|
||||
// no dtype
|
||||
let result = IdentKind::try_from(SymAttrs::<Ix> {
|
||||
let result = IdentKind::try_from(SymAttrs {
|
||||
ty: Some($src),
|
||||
..Default::default()
|
||||
})
|
||||
|
@ -500,7 +479,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
Ok($dest(Dim(dim), dtype)),
|
||||
SymAttrs::<Ix> {
|
||||
SymAttrs {
|
||||
ty: Some($src),
|
||||
dim: Some(dim),
|
||||
dtype: Some(dtype),
|
||||
|
@ -510,7 +489,7 @@ mod test {
|
|||
);
|
||||
|
||||
// no dim
|
||||
let dim_result = IdentKind::try_from(SymAttrs::<Ix> {
|
||||
let dim_result = IdentKind::try_from(SymAttrs {
|
||||
ty: Some($src),
|
||||
dtype: Some(dtype),
|
||||
..Default::default()
|
||||
|
@ -520,7 +499,7 @@ mod test {
|
|||
assert_eq!(IdentKindError::MissingDim, dim_result);
|
||||
|
||||
// no dtype
|
||||
let dtype_result = IdentKind::try_from(SymAttrs::<Ix> {
|
||||
let dtype_result = IdentKind::try_from(SymAttrs {
|
||||
ty: Some($src),
|
||||
dim: Some(dim),
|
||||
..Default::default()
|
||||
|
|
|
@ -62,17 +62,17 @@
|
|||
//! ```
|
||||
//! use tamer::global;
|
||||
//! use tamer::ir::asg::{Asg, DefaultAsg, IdentKind, IdentObject, Source};
|
||||
//! use tamer::sym::{Interner, DefaultPkgInterner};
|
||||
//! use tamer::sym::{Interner, DefaultProgInterner};
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Be sure to choose size and initial capacities appropriate for your
|
||||
//! // situation.
|
||||
//! let mut asg = DefaultAsg::<IdentObject<_>, global::PkgIdentSize>::with_capacity(
|
||||
//! let mut asg = DefaultAsg::<IdentObject>::with_capacity(
|
||||
//! 1024,
|
||||
//! 1024,
|
||||
//! );
|
||||
//!
|
||||
//! let interner = DefaultPkgInterner::new();
|
||||
//! let interner = DefaultProgInterner::new();
|
||||
//! let identa_sym = interner.intern("identa");
|
||||
//! let identb_sym = interner.intern("identb");
|
||||
//!
|
||||
|
@ -111,14 +111,14 @@
|
|||
//! ```
|
||||
//! # use tamer::global;
|
||||
//! # use tamer::ir::asg::{Asg, DefaultAsg, IdentKind, IdentObject, FragmentText, Source};
|
||||
//! # use tamer::sym::{Interner, DefaultPkgInterner};
|
||||
//! # use tamer::sym::{Interner, DefaultProgInterner};
|
||||
//! #
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! # let mut asg = DefaultAsg::<IdentObject<_>, global::PkgIdentSize>::with_capacity(
|
||||
//! # let mut asg = DefaultAsg::<IdentObject>::with_capacity(
|
||||
//! # 1024,
|
||||
//! # 1024,
|
||||
//! # );
|
||||
//! # let interner = DefaultPkgInterner::new();
|
||||
//! # let interner = DefaultProgInterner::new();
|
||||
//! #
|
||||
//! let identa_sym = interner.intern("identa");
|
||||
//! let identb_sym = interner.intern("identb");
|
||||
|
@ -157,14 +157,14 @@
|
|||
//! ```
|
||||
//! # use tamer::global;
|
||||
//! # use tamer::ir::asg::{Asg, DefaultAsg, IdentKind, IdentObject, FragmentText, Source};
|
||||
//! # use tamer::sym::{Interner, DefaultPkgInterner};
|
||||
//! # use tamer::sym::{Interner, DefaultProgInterner};
|
||||
//! #
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! # let mut asg = DefaultAsg::<IdentObject<_>, global::PkgIdentSize>::with_capacity(
|
||||
//! # let mut asg = DefaultAsg::<IdentObject>::with_capacity(
|
||||
//! # 1024,
|
||||
//! # 1024,
|
||||
//! # );
|
||||
//! # let interner = DefaultPkgInterner::new();
|
||||
//! # let interner = DefaultProgInterner::new();
|
||||
//! #
|
||||
//! // Fragments can be attached to resolved identifiers.
|
||||
//! let ident = asg.declare(
|
||||
|
@ -208,4 +208,4 @@ pub use object::{
|
|||
pub use section::{Section, SectionIter, Sections, SectionsIter};
|
||||
|
||||
/// Default concrete ASG implementation.
|
||||
pub type DefaultAsg<O, Ix> = base::BaseAsg<O, Ix>;
|
||||
pub type DefaultAsg<O, Ix = crate::global::ProgSymSize> = base::BaseAsg<O, Ix>;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
use super::ident::IdentKind;
|
||||
use crate::ir::legacyir::SymAttrs;
|
||||
use crate::sym::{GlobalSymbolResolve, SymbolId, SymbolIndexSize, SymbolStr};
|
||||
use crate::sym::{GlobalSymbolResolve, SymbolId, SymbolStr};
|
||||
use std::result::Result;
|
||||
|
||||
pub type TransitionResult<T> = Result<T, (T, TransitionError)>;
|
||||
|
@ -40,7 +40,7 @@ pub type TransitionResult<T> = Result<T, (T, TransitionError)>;
|
|||
/// `--------------------` `-----------'
|
||||
/// ```
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum IdentObject<Ix: SymbolIndexSize> {
|
||||
pub enum IdentObject {
|
||||
/// An identifier is expected to be defined but is not yet available.
|
||||
///
|
||||
/// This variant contains the symbol representing the name of the
|
||||
|
@ -48,13 +48,13 @@ pub enum IdentObject<Ix: SymbolIndexSize> {
|
|||
/// By defining an object as missing,
|
||||
/// this allows the graph to be built incrementally as objects are
|
||||
/// discovered.
|
||||
Missing(SymbolId<Ix>),
|
||||
Missing(SymbolId),
|
||||
|
||||
/// A resolved identifier.
|
||||
///
|
||||
/// This represents an identifier that has been declared with certain
|
||||
/// type information.
|
||||
Ident(SymbolId<Ix>, IdentKind, Source<Ix>),
|
||||
Ident(SymbolId, IdentKind, Source),
|
||||
|
||||
/// An identifier that has not yet been resolved.
|
||||
///
|
||||
|
@ -68,7 +68,7 @@ pub enum IdentObject<Ix: SymbolIndexSize> {
|
|||
/// Once resolved, however,
|
||||
/// the source will instead represent the location of the concrete
|
||||
/// identifier.
|
||||
Extern(SymbolId<Ix>, IdentKind, Source<Ix>),
|
||||
Extern(SymbolId, IdentKind, Source),
|
||||
|
||||
/// Identifier with associated text.
|
||||
///
|
||||
|
@ -77,7 +77,7 @@ pub enum IdentObject<Ix: SymbolIndexSize> {
|
|||
/// They are produced by the compiler and it is the job of the
|
||||
/// [linker][crate::ld] to put them into the correct order for the
|
||||
/// final executable.
|
||||
IdentFragment(SymbolId<Ix>, IdentKind, Source<Ix>, FragmentText<Ix>),
|
||||
IdentFragment(SymbolId, IdentKind, Source, FragmentText),
|
||||
}
|
||||
|
||||
/// Retrieve information about an [`IdentObject`].
|
||||
|
@ -95,12 +95,12 @@ pub enum IdentObject<Ix: SymbolIndexSize> {
|
|||
/// an [`Option`].
|
||||
/// These methods also provide a convenient alternative to `match`ing on
|
||||
/// data that may not be present in all variants.
|
||||
pub trait IdentObjectData<Ix: SymbolIndexSize> {
|
||||
pub trait IdentObjectData {
|
||||
/// Identifier name.
|
||||
///
|
||||
/// If the object is not an identifier,
|
||||
/// [`None`] is returned.
|
||||
fn name(&self) -> Option<SymbolId<Ix>>;
|
||||
fn name(&self) -> Option<SymbolId>;
|
||||
|
||||
/// Identifier [`IdentKind`].
|
||||
///
|
||||
|
@ -114,13 +114,13 @@ pub trait IdentObjectData<Ix: SymbolIndexSize> {
|
|||
/// If the object does not have source information
|
||||
/// (as is the case with [`IdentObject::Extern`]),
|
||||
/// [`None`] is returned.
|
||||
fn src(&self) -> Option<&Source<Ix>>;
|
||||
fn src(&self) -> Option<&Source>;
|
||||
|
||||
/// Identifier [`FragmentText`].
|
||||
///
|
||||
/// If the object does not have an associated code fragment,
|
||||
/// [`None`] is returned.
|
||||
fn fragment(&self) -> Option<&FragmentText<Ix>>;
|
||||
fn fragment(&self) -> Option<&FragmentText>;
|
||||
|
||||
/// IdentObject as an identifier ([`IdentObject`]).
|
||||
///
|
||||
|
@ -132,14 +132,11 @@ pub trait IdentObjectData<Ix: SymbolIndexSize> {
|
|||
///
|
||||
/// This allows pattern matching on [`IdentObject`] variants regardless
|
||||
/// of the underlying object type.
|
||||
fn as_ident(&self) -> Option<&IdentObject<Ix>>;
|
||||
fn as_ident(&self) -> Option<&IdentObject>;
|
||||
}
|
||||
|
||||
impl<Ix> IdentObjectData<Ix> for IdentObject<Ix>
|
||||
where
|
||||
Ix: SymbolIndexSize,
|
||||
{
|
||||
fn name(&self) -> Option<SymbolId<Ix>> {
|
||||
impl IdentObjectData for IdentObject {
|
||||
fn name(&self) -> Option<SymbolId> {
|
||||
match self {
|
||||
Self::Missing(name)
|
||||
| Self::Ident(name, _, _)
|
||||
|
@ -157,7 +154,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn src(&self) -> Option<&Source<Ix>> {
|
||||
fn src(&self) -> Option<&Source> {
|
||||
match self {
|
||||
Self::Missing(_) | Self::Extern(_, _, _) => None,
|
||||
Self::Ident(_, _, src) | Self::IdentFragment(_, _, src, _) => {
|
||||
|
@ -166,7 +163,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn fragment(&self) -> Option<&FragmentText<Ix>> {
|
||||
fn fragment(&self) -> Option<&FragmentText> {
|
||||
match self {
|
||||
Self::Missing(_) | Self::Ident(_, _, _) | Self::Extern(_, _, _) => {
|
||||
None
|
||||
|
@ -184,28 +181,27 @@ where
|
|||
/// so it's important _not_ to rely on this as an excuse to be lazy
|
||||
/// with unwrapping.
|
||||
#[inline]
|
||||
fn as_ident(&self) -> Option<&IdentObject<Ix>> {
|
||||
fn as_ident(&self) -> Option<&IdentObject> {
|
||||
Some(&self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Objects as a state machine.
|
||||
pub trait IdentObjectState<Ix, T>
|
||||
pub trait IdentObjectState<T>
|
||||
where
|
||||
T: IdentObjectState<Ix, T>,
|
||||
Ix: SymbolIndexSize,
|
||||
T: IdentObjectState<T>,
|
||||
{
|
||||
/// Produce an object representing a missing identifier.
|
||||
///
|
||||
/// This is the base state for all identifiers.
|
||||
fn declare(ident: SymbolId<Ix>) -> T;
|
||||
fn declare(ident: SymbolId) -> T;
|
||||
|
||||
/// 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 resolve(self, kind: IdentKind, src: Source<Ix>) -> TransitionResult<T>;
|
||||
fn resolve(self, kind: IdentKind, src: Source) -> TransitionResult<T>;
|
||||
|
||||
/// Assertion to return self if identifier is resolved,
|
||||
/// otherwise failing with [`UnresolvedError`].
|
||||
|
@ -239,7 +235,7 @@ where
|
|||
/// If no kind is assigned (such as [`IdentObject::Missing`]),
|
||||
/// then a new extern is produced.
|
||||
/// See for example [`IdentObject::Extern`].
|
||||
fn extern_(self, kind: IdentKind, src: Source<Ix>) -> TransitionResult<T>;
|
||||
fn extern_(self, kind: IdentKind, src: Source) -> TransitionResult<T>;
|
||||
|
||||
/// Attach a code fragment (compiled text) to an identifier.
|
||||
///
|
||||
|
@ -249,14 +245,11 @@ where
|
|||
/// Note, however, that an identifier's fragment may be cleared under
|
||||
/// certain circumstances (such as symbol overrides),
|
||||
/// making way for a new fragment to be set.
|
||||
fn set_fragment(self, text: FragmentText<Ix>) -> TransitionResult<T>;
|
||||
fn set_fragment(self, text: FragmentText) -> TransitionResult<T>;
|
||||
}
|
||||
|
||||
impl<Ix> IdentObjectState<Ix, IdentObject<Ix>> for IdentObject<Ix>
|
||||
where
|
||||
Ix: SymbolIndexSize,
|
||||
{
|
||||
fn declare(ident: SymbolId<Ix>) -> Self {
|
||||
impl IdentObjectState<IdentObject> for IdentObject {
|
||||
fn declare(ident: SymbolId) -> Self {
|
||||
IdentObject::Missing(ident)
|
||||
}
|
||||
|
||||
|
@ -291,8 +284,8 @@ where
|
|||
fn resolve(
|
||||
self,
|
||||
kind: IdentKind,
|
||||
mut src: Source<Ix>,
|
||||
) -> TransitionResult<IdentObject<Ix>> {
|
||||
mut src: Source,
|
||||
) -> TransitionResult<IdentObject> {
|
||||
match self {
|
||||
IdentObject::Ident(name, ref orig_kind, ref orig_src)
|
||||
| IdentObject::IdentFragment(
|
||||
|
@ -389,7 +382,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn resolved(&self) -> Result<&IdentObject<Ix>, UnresolvedError> {
|
||||
fn resolved(&self) -> Result<&IdentObject, UnresolvedError> {
|
||||
match self {
|
||||
IdentObject::Missing(name) => Err(UnresolvedError::Missing {
|
||||
name: name.lookup_str(),
|
||||
|
@ -411,8 +404,8 @@ where
|
|||
fn extern_(
|
||||
self,
|
||||
kind: IdentKind,
|
||||
src: Source<Ix>,
|
||||
) -> TransitionResult<IdentObject<Ix>> {
|
||||
src: Source,
|
||||
) -> TransitionResult<IdentObject> {
|
||||
match self.kind() {
|
||||
None => Ok(IdentObject::Extern(self.name().unwrap(), kind, src)),
|
||||
Some(cur_kind) => {
|
||||
|
@ -432,10 +425,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn set_fragment(
|
||||
self,
|
||||
text: FragmentText<Ix>,
|
||||
) -> TransitionResult<IdentObject<Ix>> {
|
||||
fn set_fragment(self, text: FragmentText) -> TransitionResult<IdentObject> {
|
||||
match self {
|
||||
IdentObject::Ident(sym, kind, src) => {
|
||||
Ok(IdentObject::IdentFragment(sym, kind, src, text))
|
||||
|
@ -608,7 +598,7 @@ impl std::error::Error for UnresolvedError {
|
|||
/// Compiled fragment for identifier.
|
||||
///
|
||||
/// This represents the text associated with an identifier.
|
||||
pub type FragmentText<Ix> = SymbolId<Ix>;
|
||||
pub type FragmentText = SymbolId;
|
||||
|
||||
/// Metadata about the source of an object.
|
||||
///
|
||||
|
@ -620,26 +610,26 @@ pub type FragmentText<Ix> = SymbolId<Ix>;
|
|||
/// since the original XSLT-based compiler did not have that capability;
|
||||
/// this will provide that information in the future.
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
pub struct Source<Ix: SymbolIndexSize> {
|
||||
pub struct Source {
|
||||
/// Name of package containing reference to this object.
|
||||
pub pkg_name: Option<SymbolId<Ix>>,
|
||||
pub pkg_name: Option<SymbolId>,
|
||||
|
||||
/// Relative path to the source of this object,
|
||||
/// if not present in the current package.
|
||||
pub src: Option<SymbolId<Ix>>,
|
||||
pub src: Option<SymbolId>,
|
||||
|
||||
/// The identifier from which this one is derived.
|
||||
///
|
||||
/// See [`IdentKind`] for more information on parents.
|
||||
/// For example,
|
||||
/// a [`IdentKind::Cgen`] always has a parent [`IdentKind::Class`].
|
||||
pub parent: Option<SymbolId<Ix>>,
|
||||
pub parent: Option<SymbolId>,
|
||||
|
||||
/// Child identifier associated with this identifier.
|
||||
///
|
||||
/// For [`IdentKind::Class`],
|
||||
/// this represents an associated [`IdentKind::Cgen`].
|
||||
pub yields: Option<SymbolId<Ix>>,
|
||||
pub yields: Option<SymbolId>,
|
||||
|
||||
/// User-friendly identifier description.
|
||||
///
|
||||
|
@ -667,7 +657,7 @@ pub struct Source<Ix: SymbolIndexSize> {
|
|||
///
|
||||
/// TODO: We have `parent`, `yields`, and `from`.
|
||||
/// We should begin to consolodate.
|
||||
pub from: Option<Vec<SymbolId<Ix>>>,
|
||||
pub from: Option<Vec<SymbolId>>,
|
||||
|
||||
/// Whether identifier is virtual (can be overridden).
|
||||
///
|
||||
|
@ -686,14 +676,11 @@ pub struct Source<Ix: SymbolIndexSize> {
|
|||
pub override_: bool,
|
||||
}
|
||||
|
||||
impl<Ix> From<SymAttrs<Ix>> for Source<Ix>
|
||||
where
|
||||
Ix: SymbolIndexSize,
|
||||
{
|
||||
impl From<SymAttrs> for Source {
|
||||
/// Raise Legacy IR [`SymAttrs`].
|
||||
///
|
||||
/// This simply extracts a subset of fields from the source attributes.
|
||||
fn from(attrs: SymAttrs<Ix>) -> Self {
|
||||
fn from(attrs: SymAttrs) -> Self {
|
||||
Source {
|
||||
pkg_name: attrs.pkg_name,
|
||||
src: attrs.src,
|
||||
|
@ -712,7 +699,7 @@ where
|
|||
mod test {
|
||||
use super::super::ident::Dim;
|
||||
use super::*;
|
||||
use crate::sym::{GlobalSymbolIntern, PkgSymbolId};
|
||||
use crate::sym::{GlobalSymbolIntern, SymbolId};
|
||||
|
||||
mod ident_object_data {
|
||||
use super::*;
|
||||
|
@ -720,7 +707,7 @@ mod test {
|
|||
// Note that IdentObject has no variants capable of None
|
||||
#[test]
|
||||
fn ident_object_name() {
|
||||
let sym: PkgSymbolId = "sym".intern();
|
||||
let sym: SymbolId = "sym".intern();
|
||||
|
||||
assert_eq!(Some(sym), IdentObject::Missing(sym).name());
|
||||
|
||||
|
@ -750,7 +737,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn ident_object_kind() {
|
||||
let sym: PkgSymbolId = "sym".intern();
|
||||
let sym: SymbolId = "sym".intern();
|
||||
let kind = IdentKind::Class(Dim::from_u8(5));
|
||||
|
||||
assert_eq!(None, IdentObject::Missing(sym).kind());
|
||||
|
@ -780,7 +767,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn ident_object_src() {
|
||||
let sym: PkgSymbolId = "sym".intern();
|
||||
let sym: SymbolId = "sym".intern();
|
||||
let src = Source {
|
||||
desc: Some("test source".into()),
|
||||
..Default::default()
|
||||
|
@ -812,7 +799,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn ident_object_fragment() {
|
||||
let sym: PkgSymbolId = "sym".intern();
|
||||
let sym: SymbolId = "sym".intern();
|
||||
let text = "foo".into();
|
||||
|
||||
assert_eq!(None, IdentObject::Missing(sym).fragment());
|
||||
|
@ -843,7 +830,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn ident_object_as_ident() {
|
||||
let sym: PkgSymbolId = "sym".intern();
|
||||
let sym: SymbolId = "sym".intern();
|
||||
let ident = IdentObject::Missing(sym);
|
||||
|
||||
// Since we _are_ an IdentObject, we should return a reference
|
||||
|
@ -860,13 +847,13 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn ident_object_missing() {
|
||||
let sym: PkgSymbolId = "missing".intern();
|
||||
let sym: SymbolId = "missing".intern();
|
||||
assert_eq!(IdentObject::Missing(sym), IdentObject::declare(sym));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolved_on_missing() {
|
||||
let sym: PkgSymbolId = "missing".intern();
|
||||
let sym: SymbolId = "missing".intern();
|
||||
|
||||
let result = IdentObject::declare(sym)
|
||||
.resolved()
|
||||
|
@ -882,7 +869,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn ident_object_ident() {
|
||||
let sym: PkgSymbolId = "ident".intern();
|
||||
let sym: SymbolId = "ident".intern();
|
||||
let kind = IdentKind::Meta;
|
||||
let src = Source {
|
||||
desc: Some("ident ctor".into()),
|
||||
|
@ -899,7 +886,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn resolved_on_ident() {
|
||||
let sym: PkgSymbolId = "ident resolve".intern();
|
||||
let sym: SymbolId = "ident resolve".intern();
|
||||
let kind = IdentKind::Meta;
|
||||
let src = Source {
|
||||
desc: Some("ident ctor".into()),
|
||||
|
@ -922,7 +909,7 @@ mod test {
|
|||
// packages have the same local symbol.
|
||||
#[test]
|
||||
fn ident_object_redeclare_same_src() {
|
||||
let sym: PkgSymbolId = "redecl".intern();
|
||||
let sym: SymbolId = "redecl".intern();
|
||||
let kind = IdentKind::Meta;
|
||||
let src = Source::default();
|
||||
|
||||
|
@ -952,7 +939,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn ident_object() {
|
||||
let sym: PkgSymbolId = "extern".intern();
|
||||
let sym: SymbolId = "extern".intern();
|
||||
let kind = IdentKind::Class(Dim::from_u8(1));
|
||||
let src = Source {
|
||||
desc: Some("extern".into()),
|
||||
|
@ -967,9 +954,9 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn resolved_on_extern() {
|
||||
let sym: PkgSymbolId = "extern resolved".intern();
|
||||
let sym: SymbolId = "extern resolved".intern();
|
||||
let kind = IdentKind::Class(Dim::from_u8(1));
|
||||
let pkg_name: PkgSymbolId = "pkg/name".intern();
|
||||
let pkg_name: SymbolId = "pkg/name".intern();
|
||||
let src = Source {
|
||||
pkg_name: Some(pkg_name),
|
||||
desc: Some("extern".into()),
|
||||
|
@ -1034,7 +1021,7 @@ mod test {
|
|||
// Extern first, then identifier
|
||||
#[test]
|
||||
fn redeclare_compatible_resolves() {
|
||||
let sym: PkgSymbolId = "extern_re_pre".intern();
|
||||
let sym: SymbolId = "extern_re_pre".intern();
|
||||
let kind = IdentKind::Class(Dim::from_u8(10));
|
||||
let src = Source {
|
||||
desc: Some("okay".into()),
|
||||
|
@ -1052,7 +1039,7 @@ mod test {
|
|||
// Identifier first, then extern
|
||||
#[test]
|
||||
fn redeclare_compatible_resolves_post() {
|
||||
let sym: PkgSymbolId = "extern_re_post".intern();
|
||||
let sym: SymbolId = "extern_re_post".intern();
|
||||