• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pomsky-lang / pomsky / 12301483439

12 Dec 2024 05:19PM UTC coverage: 80.275% (-0.2%) from 80.471%
12301483439

push

github

Aloso
feat: test command

360 of 593 new or added lines in 11 files covered. (60.71%)

20 existing lines in 7 files now uncovered.

4607 of 5739 relevant lines covered (80.28%)

374427.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.7
/pomsky-lib/src/validation.rs
1
use pomsky_syntax::{exprs, Span};
2

3
use crate::{
4
    diagnose::{CompileError, CompileErrorKind, Feature},
5
    features::PomskyFeatures as Feat,
6
    options::{CompileOptions, RegexFlavor},
7
    visitor::{NestingKind, RuleVisitor},
8
};
9

10
#[derive(Clone)]
11
pub(crate) struct Validator {
12
    pub(crate) options: CompileOptions,
13
    pub(crate) layer: u32,
14
}
15

16
impl Validator {
17
    pub(crate) fn new(options: CompileOptions) -> Self {
275✔
18
        Validator { options, layer: 0 }
275✔
19
    }
275✔
20

21
    fn require(&self, feature: u16, span: Span) -> Result<(), CompileError> {
370✔
22
        self.options.allowed_features.require(feature, span)
370✔
23
    }
370✔
24

25
    fn flavor(&self) -> RegexFlavor {
167✔
26
        self.options.flavor
167✔
27
    }
167✔
28
}
29

30
impl RuleVisitor<CompileError> for Validator {
31
    fn down(&mut self, kind: NestingKind) {
696✔
32
        if !matches!(kind, NestingKind::StmtExpr) {
696✔
33
            self.layer += 1;
619✔
34
        }
619✔
35
    }
696✔
36

37
    fn up(&mut self, kind: NestingKind) {
694✔
38
        if !matches!(kind, NestingKind::StmtExpr) {
694✔
39
            self.layer -= 1;
617✔
40
        }
617✔
41
    }
694✔
42

43
    fn visit_repetition(&mut self, repetition: &exprs::Repetition) -> Result<(), CompileError> {
125✔
44
        if let (RegexFlavor::RE2, Some(1001..)) = (self.flavor(), repetition.kind.upper_bound) {
125✔
45
            return Err(CompileErrorKind::Unsupported(Feature::RepetitionAbove1000, self.flavor())
1✔
46
                .at(repetition.span));
1✔
47
        }
124✔
48
        Ok(())
124✔
49
    }
125✔
50

51
    fn visit_intersection(&mut self, int: &exprs::Intersection) -> Result<(), CompileError> {
7✔
52
        self.require(Feat::INTERSECTION, int.span)
7✔
53
    }
7✔
54

55
    fn visit_group(&mut self, group: &exprs::Group) -> Result<(), CompileError> {
306✔
56
        match &group.kind {
306✔
57
            exprs::GroupKind::Atomic => {
58
                self.require(Feat::ATOMIC_GROUPS, group.span)?;
2✔
59

60
                if let RegexFlavor::JavaScript | RegexFlavor::Rust | RegexFlavor::RE2 =
61
                    self.flavor()
2✔
62
                {
63
                    return Err(CompileErrorKind::Unsupported(
1✔
64
                        Feature::AtomicGroups,
1✔
65
                        self.flavor(),
1✔
66
                    )
1✔
67
                    .at(group.span));
1✔
68
                }
1✔
69
            }
70
            exprs::GroupKind::Capturing(c) => {
86✔
71
                let feature = match &c.name {
86✔
72
                    Some(_) => Feat::NAMED_GROUPS,
51✔
73
                    None => Feat::NUMBERED_GROUPS,
35✔
74
                };
75

76
                self.require(feature, group.span)?;
86✔
77
            }
78
            _ => (),
218✔
79
        }
80

81
        Ok(())
304✔
82
    }
306✔
83

84
    fn visit_boundary(&mut self, boundary: &exprs::Boundary) -> Result<(), CompileError> {
59✔
85
        self.require(Feat::BOUNDARIES, boundary.span)
59✔
86
    }
59✔
87

88
    fn visit_lookaround(&mut self, lookaround: &exprs::Lookaround) -> Result<(), CompileError> {
34✔
89
        use exprs::LookaroundKind;
90
        let feature = match lookaround.kind {
34✔
91
            LookaroundKind::Ahead | LookaroundKind::AheadNegative => Feat::LOOKAHEAD,
19✔
92
            LookaroundKind::Behind | LookaroundKind::BehindNegative => Feat::LOOKBEHIND,
15✔
93
        };
94
        self.require(feature, lookaround.span)?;
34✔
95

96
        if let flavor @ (RegexFlavor::Rust | RegexFlavor::RE2) = self.flavor() {
34✔
97
            Err(CompileErrorKind::Unsupported(Feature::Lookaround, flavor).at(lookaround.span))
1✔
98
        } else {
99
            Ok(())
33✔
100
        }
101
    }
34✔
102

103
    fn visit_reference(&mut self, reference: &exprs::Reference) -> Result<(), CompileError> {
61✔
104
        self.require(Feat::REFERENCES, reference.span)
61✔
105
    }
61✔
106

107
    fn visit_range(&mut self, range: &exprs::Range) -> Result<(), CompileError> {
22✔
108
        self.require(Feat::RANGES, range.span)?;
22✔
109

110
        if range.end.len() <= self.options.max_range_size as usize {
22✔
111
            Ok(())
21✔
112
        } else {
113
            Err(CompileErrorKind::RangeIsTooBig(self.options.max_range_size).at(range.span))
1✔
114
        }
115
    }
22✔
116

117
    fn visit_statement(&mut self, statement: &exprs::Stmt) -> Result<(), CompileError> {
79✔
118
        use exprs::{BooleanSetting as BS, Stmt};
119
        match statement {
7✔
120
            Stmt::Enable(BS::Lazy, span) => self.require(Feat::LAZY_MODE, *span),
5✔
121
            Stmt::Disable(BS::Unicode, span) => self.require(Feat::ASCII_MODE, *span),
16✔
122
            Stmt::Let(l) => self.require(Feat::VARIABLES, l.name_span),
40✔
123
            Stmt::Test(t) if self.layer > 0 => Err(CompileErrorKind::NestedTest.at(t.span)),
15✔
124
            _ => Ok(()),
16✔
125
        }
126
    }
79✔
127

128
    fn visit_regex(&mut self, regex: &exprs::Regex) -> Result<(), CompileError> {
10✔
129
        self.require(Feat::REGEXES, regex.span)
10✔
130
    }
10✔
131

132
    fn visit_recursion(&mut self, recursion: &exprs::Recursion) -> Result<(), CompileError> {
3✔
133
        self.require(Feat::RECURSION, recursion.span)?;
3✔
134

135
        if let RegexFlavor::Pcre | RegexFlavor::Ruby = self.flavor() {
3✔
136
            Ok(())
2✔
137
        } else {
138
            Err(CompileErrorKind::Unsupported(Feature::Recursion, self.flavor()).at(recursion.span))
1✔
139
        }
140
    }
3✔
141

UNCOV
142
    fn visit_grapheme(&mut self) -> Result<(), CompileError> {
×
UNCOV
143
        self.require(Feat::GRAPHEME, Span::empty())
×
UNCOV
144
    }
×
145

146
    fn visit_dot(&mut self) -> Result<(), CompileError> {
25✔
147
        self.require(Feat::DOT, Span::empty())
25✔
148
    }
25✔
149
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc