|
1 | | -use crate::core::ConstLookup; |
2 | | -use rusty_common::CaseInsensitiveString; |
3 | | -use rusty_parser::BareName; |
4 | | -use rusty_variant::Variant; |
5 | 1 | use std::collections::HashMap; |
6 | 2 |
|
| 3 | +use rusty_common::{AtPos, CaseInsensitiveString, Positioned}; |
| 4 | +use rusty_parser::{BareName, Constant, Name}; |
| 5 | +use rusty_variant::Variant; |
| 6 | + |
| 7 | +use crate::core::*; |
| 8 | + |
7 | 9 | pub type ConstantMap = HashMap<BareName, Variant>; |
8 | 10 |
|
9 | 11 | impl ConstLookup for ConstantMap { |
10 | 12 | fn get_resolved_constant(&self, name: &CaseInsensitiveString) -> Option<&Variant> { |
11 | 13 | self.get(name) |
12 | 14 | } |
13 | 15 | } |
| 16 | + |
| 17 | +impl Visitor<Constant> for ConstantMap { |
| 18 | + // calculate global constant values |
| 19 | + fn visit(&mut self, element: &Constant) -> VisitResult { |
| 20 | + let (name_pos, expression_pos) = element.into(); |
| 21 | + let Positioned { element: name, pos } = name_pos; |
| 22 | + let bare_name: &BareName = name.bare_name(); |
| 23 | + (match self.get(bare_name) { |
| 24 | + Some(_) => Err(LintError::DuplicateDefinition.at(pos)), |
| 25 | + _ => Ok(()), |
| 26 | + }) |
| 27 | + .and_then(|_| self.resolve_const(expression_pos)) |
| 28 | + .and_then(|v| match name { |
| 29 | + Name::Bare(_) => Ok(v), |
| 30 | + Name::Qualified(_, qualifier) => v.cast(*qualifier).map_err(|e| e.at(expression_pos)), |
| 31 | + }) |
| 32 | + .map(|casted| { |
| 33 | + self.insert(bare_name.clone(), casted); |
| 34 | + }) |
| 35 | + } |
| 36 | +} |
0 commit comments