easter 0.0.5

Type definitions for ECMAScript abstract syntax trees.
Documentation
use joker::track::*;

use id::Id;
use expr::Expr;
use obj::{PropKey, DotKey};

#[derive(Debug, PartialEq)]
pub enum CompoundPatt<T> {
    Arr(Option<Span>, Vec<Option<Patt<T>>>),
    Obj(Option<Span>, Vec<PropPatt<T>>)
}

impl<T> TrackingRef for CompoundPatt<T> {
    fn tracking_ref(&self) -> &Option<Span> {
        match *self {
            CompoundPatt::Arr(ref location, _)
          | CompoundPatt::Obj(ref location, _) => location
        }
    }
}

impl<T> TrackingMut for CompoundPatt<T> {
    fn tracking_mut(&mut self) -> &mut Option<Span> {
        match *self {
            CompoundPatt::Arr(ref mut location, _)
          | CompoundPatt::Obj(ref mut location, _) => { location }
        }
    }
}

impl<T: Untrack> Untrack for CompoundPatt<T> {
    fn untrack(&mut self) {
        match *self {
            CompoundPatt::Arr(ref mut location, ref mut patts) => {
                *location = None;
                patts.untrack();
            }
            CompoundPatt::Obj(ref mut location, ref mut props) => {
                *location = None;
                props.untrack();
            }
        }
    }
}

#[derive(Debug, PartialEq)]
pub struct PropPatt<T> {
    pub location: Option<Span>,
    pub key: PropKey,
    pub patt: Patt<T>
}

impl<T> TrackingRef for PropPatt<T> {
    fn tracking_ref(&self) -> &Option<Span> { &self.location }
}

impl<T> TrackingMut for PropPatt<T> {
    fn tracking_mut(&mut self) -> &mut Option<Span> { &mut self.location }
}

impl<T: Untrack> Untrack for PropPatt<T> {
    fn untrack(&mut self) {
        self.location = None;
        self.key.untrack();
        self.patt.untrack();
    }
}

#[derive(Debug, PartialEq)]
pub enum Patt<T> {
    Simple(T),
    Compound(CompoundPatt<T>)
}

impl<T> Patt<T> {
    pub fn is_simple(&self) -> bool {
        match *self {
            Patt::Simple(_)   => true,
            Patt::Compound(_) => false
        }
    }
}

impl<T: TrackingRef> TrackingRef for Patt<T> {
    fn tracking_ref(&self) -> &Option<Span> {
        match *self {
            Patt::Simple(ref simple) => simple.tracking_ref(),
            Patt::Compound(ref patt) => patt.tracking_ref()
        }
    }
}

impl<T: TrackingMut> TrackingMut for Patt<T> {
    fn tracking_mut(&mut self) -> &mut Option<Span> {
        match *self {
            Patt::Simple(ref mut simple) => simple.tracking_mut(),
            Patt::Compound(ref mut patt) => patt.tracking_mut()
        }
    }
}

impl<T: Untrack> Untrack for Patt<T> {
    fn untrack(&mut self) {
        match *self {
            Patt::Simple(ref mut simple) => { simple.untrack(); }
            Patt::Compound(ref mut patt) => { patt.untrack(); }
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum AssignTarget {
    Id(Id),
    Dot(Option<Span>, Box<Expr>, DotKey),
    Brack(Option<Span>, Box<Expr>, Box<Expr>)
}

impl TrackingRef for AssignTarget {
    fn tracking_ref(&self) -> &Option<Span> {
        match *self {
            AssignTarget::Id(ref id) => id.tracking_ref(),
            AssignTarget::Dot(ref location, _, _)
          | AssignTarget::Brack(ref location, _, _) => location
        }
    }
}

impl TrackingMut for AssignTarget {
    fn tracking_mut(&mut self) -> &mut Option<Span> {
        match *self {
            AssignTarget::Id(ref mut id) => id.tracking_mut(),
            AssignTarget::Dot(ref mut location, _, _)
          | AssignTarget::Brack(ref mut location, _, _) => location
        }
    }
}

impl Untrack for AssignTarget {
    fn untrack(&mut self) {
        match *self {
            AssignTarget::Id(ref mut id) => {
                id.untrack();
            }
            AssignTarget::Dot(ref mut location, ref mut obj, ref mut prop) => {
                *location = None;
                obj.untrack();
                prop.untrack();
            }
            AssignTarget::Brack(ref mut location, ref mut obj, ref mut prop) => {
                *location = None;
                obj.untrack();
                prop.untrack();
            }
        }
    }
}