2023-01-30 16:51:24 -05:00
|
|
|
|
// Packages represented on ASG
|
|
|
|
|
//
|
|
|
|
|
// Copyright (C) 2014-2023 Ryan Specialty, LLC.
|
|
|
|
|
//
|
|
|
|
|
// This file is part of TAME.
|
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
//! Package object on the ASG.
|
|
|
|
|
|
2023-01-31 16:37:25 -05:00
|
|
|
|
use super::{
|
2023-02-03 15:53:50 -05:00
|
|
|
|
Ident, Object, ObjectIndex, ObjectRel, ObjectRelFrom, ObjectRelTy,
|
2023-01-31 16:37:25 -05:00
|
|
|
|
ObjectRelatable,
|
|
|
|
|
};
|
2023-02-07 12:19:27 -05:00
|
|
|
|
use crate::{asg::Asg, f::Functor, span::Span};
|
2023-02-03 15:53:50 -05:00
|
|
|
|
use std::fmt::Display;
|
|
|
|
|
|
|
|
|
|
#[cfg(doc)]
|
|
|
|
|
use super::ObjectKind;
|
2023-01-30 16:51:24 -05:00
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
|
pub struct Pkg(Span);
|
|
|
|
|
|
|
|
|
|
impl Pkg {
|
|
|
|
|
pub fn new<S: Into<Span>>(span: S) -> Self {
|
|
|
|
|
Self(span.into())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
|
match self {
|
|
|
|
|
Self(span) => *span,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Display for Pkg {
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
|
write!(f, "package")
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-31 16:37:25 -05:00
|
|
|
|
|
2023-02-07 12:19:27 -05:00
|
|
|
|
impl Functor<Span> for Pkg {
|
|
|
|
|
fn map(self, f: impl FnOnce(Span) -> Span) -> Self::Target {
|
|
|
|
|
match self {
|
|
|
|
|
Self(span) => Self(f(span)),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-31 16:37:25 -05:00
|
|
|
|
/// Subset of [`ObjectKind`]s that are valid targets for edges from
|
|
|
|
|
/// [`Ident`].
|
|
|
|
|
///
|
|
|
|
|
/// See [`ObjectRel`] for more information.
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
|
pub enum PkgRel {
|
|
|
|
|
Ident(ObjectIndex<Ident>),
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-03 15:53:50 -05:00
|
|
|
|
impl ObjectRel<Pkg> for PkgRel {
|
|
|
|
|
fn narrow<OB: ObjectRelFrom<Pkg> + ObjectRelatable>(
|
2023-01-31 16:37:25 -05:00
|
|
|
|
self,
|
|
|
|
|
) -> Option<ObjectIndex<OB>> {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Ident(oi) => oi.filter_rel(),
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-03 15:53:50 -05:00
|
|
|
|
|
|
|
|
|
/// Whether this is a cross edge to another package tree.
|
|
|
|
|
///
|
|
|
|
|
/// Packages serve as a root for all identifiers defined therein,
|
|
|
|
|
/// and so an edge to [`Ident`] will never be a cross edge.
|
|
|
|
|
///
|
|
|
|
|
/// Imported [`Ident`]s do not have edges from this package.
|
|
|
|
|
fn is_cross_edge(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
2023-01-31 16:37:25 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ObjectRelatable for Pkg {
|
|
|
|
|
type Rel = PkgRel;
|
|
|
|
|
|
|
|
|
|
fn rel_ty() -> ObjectRelTy {
|
|
|
|
|
ObjectRelTy::Pkg
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_rel_dyn(ty: ObjectRelTy, oi: ObjectIndex<Object>) -> Option<PkgRel> {
|
|
|
|
|
match ty {
|
|
|
|
|
ObjectRelTy::Root => None,
|
2023-01-31 22:00:51 -05:00
|
|
|
|
ObjectRelTy::Pkg => None,
|
2023-01-31 16:37:25 -05:00
|
|
|
|
ObjectRelTy::Ident => Some(PkgRel::Ident(oi.must_narrow_into())),
|
|
|
|
|
ObjectRelTy::Expr => None,
|
2023-02-24 23:54:01 -05:00
|
|
|
|
ObjectRelTy::Tpl => None,
|
2023-01-31 16:37:25 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<ObjectIndex<Ident>> for PkgRel {
|
|
|
|
|
fn from(value: ObjectIndex<Ident>) -> Self {
|
|
|
|
|
Self::Ident(value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ObjectIndex<Pkg> {
|
|
|
|
|
/// Indicate that the given identifier `oi` is defined in this package.
|
2023-01-31 22:00:51 -05:00
|
|
|
|
pub fn defines(self, asg: &mut Asg, oi: ObjectIndex<Ident>) -> Self {
|
tamer: asg::graph: Formalize dynamic relationships (edges)
The `TreePreOrderDfs` iterator needed to expose additional edge context to
the caller (specifically, the `Span`). This was getting a bit messy, so
this consolodates everything into a new `DynObjectRel`, which also
emphasizes that it is in need of narrowing.
Packing everything up like that also allows us to return more information to
the caller without complicating the API, since the caller does not need to
be concerned with all of those values individually.
Depth is kept separate, since that is a property of the traversal and is not
stored on the graph. (Rather, it _is_ a property of the graph, but it's not
calculated until traversal. But, depth will also vary for a given node
because of cross edges, and so we cannot store any concrete depth on the
graph for a given node. Not even a canonical one, because once we start
doing inlining and common subexpression elimination, there will be shared
edges that are _not_ cross edges (the node is conceptually part of _both_
trees). Okay, enough of this rambling parenthetical.)
DEV-13708
2023-02-09 13:11:27 -05:00
|
|
|
|
self.add_edge_to(asg, oi, None)
|
2023-01-31 16:37:25 -05:00
|
|
|
|
}
|
2023-02-07 12:19:27 -05:00
|
|
|
|
|
|
|
|
|
/// Complete the definition of a package.
|
|
|
|
|
pub fn close(self, asg: &mut Asg, span: Span) -> Self {
|
|
|
|
|
self.map_obj(asg, Pkg::fmap(|open| open.merge(span).unwrap_or(open)))
|
|
|
|
|
}
|
2023-01-31 16:37:25 -05:00
|
|
|
|
}
|