1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Original file: "Node.hs"
// File auto-generated using Corollary.

#[macro_use]
use corollary_support::*;

use std::fmt;

use data::name::Name;
use data::position::{Pos, Position, PosLength};

// a class for convenient access to the attributes of an attributed object
pub trait CNode {
    fn node_info(&self) -> &NodeInfo;
    fn into_node_info(self) -> NodeInfo;
}

impl CNode for NodeInfo {
    fn node_info(&self) -> &NodeInfo {
        self
    }
    fn into_node_info(self) -> NodeInfo {
        self
    }
}

impl<T: CNode> Pos for T {
    fn pos(&self) -> &Position {
        NodeInfo::pos(self.node_info())
    }
    fn into_pos(self) -> Position {
        NodeInfo::into_pos(self.into_node_info())
    }
}

#[derive(Clone, Eq, Ord, PartialEq, PartialOrd, Hash)]
pub enum NodeInfo {
    OnlyPos(Position, PosLength),
    NodeInfo(Position, PosLength, Name),
}
pub use self::NodeInfo::*;

// TODO This should be replaced with a better impl
impl fmt::Debug for NodeInfo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "..")
    }
}

impl NodeInfo {
    pub fn internal() -> NodeInfo {
        Self::undef()
    }

    pub fn undef() -> NodeInfo {
        OnlyPos(Position::none(), (Position::none(), -1))
    }

    pub fn new(pos: Position, lasttok: PosLength, name: Name) -> NodeInfo {
        NodeInfo(pos, lasttok, name)
    }

    pub fn with_only_pos(pos: Position) -> NodeInfo {
        OnlyPos(pos, (Position::none(), -1))
    }

    pub fn with_pos_len(a: Position, b: PosLength) -> NodeInfo {
        OnlyPos(a, b)
    }

    pub fn with_pos_name(pos: Position, name: Name) -> NodeInfo {
        NodeInfo(pos, (Position::none(), -1), name)
    }

    pub fn len(&self) -> Option<isize> {
        match *self {
            NodeInfo(ref firstPos, (ref lastPos, lastTokLen), _) |
            OnlyPos( ref firstPos, (ref lastPos, lastTokLen)) => if lastTokLen < 0 {
                None
            } else {
                Some(lastPos.offset() + lastTokLen - firstPos.offset())
            }
        }
    }

    pub fn get_last_token_pos(&self) -> &PosLength {
        match *self {
            NodeInfo(_, ref last, _) => last,
            OnlyPos(_, ref last) => last,
        }
    }

    pub fn name(&self) -> Option<Name> {
        match *self {
            OnlyPos(_, _) => None,
            NodeInfo(_, _, name) => Some(name),
        }
    }

    // NOTE: these are not an impl of Pos because that impl is automatic
    // for all CNodes and falls back to these inherent methods!

    fn pos(&self) -> &Position {
        match *self {
            OnlyPos(ref pos, _) => pos,
            NodeInfo(ref pos, _, _) => pos,
        }
    }

    fn into_pos(self) -> Position {
        match self {
            OnlyPos(pos, _) => pos,
            NodeInfo(pos, _, _) => pos,
        }
    }
}

// TODO borrow
pub fn fileOfNode<A: CNode>(obj: A) -> Option<FilePath> {
    let pos = obj.into_pos();
    if pos.isSource() {
        Some(FilePath { path: (*pos.file()).clone() })
    } else {
        None
    }
}

pub fn eqByName<A: CNode>(obj1: A, obj2: A) -> bool {
    obj1.node_info() == obj2.node_info()
}