#[non_exhaustive]pub enum Error {
Show 13 variants
InvalidRegex {
path: String,
error: RegexError,
},
EmptyRegex {
path: String,
},
InvalidScope {
path: String,
scope: String,
offset: usize,
reason: &'static str,
},
InvalidSelector {
path: String,
selector: String,
offset: usize,
reason: &'static str,
},
InvalidName {
path: String,
name: String,
reason: &'static str,
},
DuplicateRepository {
name: String,
},
DuplicateInjection {
selector: String,
},
DuplicateCapture {
path: String,
group: u32,
},
CaptureOutOfRange {
path: String,
group: u32,
groups: u32,
},
ShadowedCaptures {
path: String,
},
UndefinedInclude {
path: String,
name: String,
},
IncludeCycle {
cycle: Vec<String>,
},
TooDeep {
path: String,
},
}Expand description
Why Grammar refused to emit a grammar.
Emitting validates the whole grammar first and reports the first problem.
Every variant that has a path locates the problem with a
JSON Pointer into the JSON that
would have been emitted: /patterns/2/begin, /repository/string/captures/1/name.
Repository and injection entries are addressed by name, so a path is the
same whatever order the entries were added in.
The checks run in this order: the grammar’s scopeName, fileTypes,
firstLineMatch, and injectionSelector; repository names and injection
selectors (and their uniqueness); then every rule — the top-level
patterns, the repository in name order, the injections in selector order
— each checked before the rules nested in it; finally include cycles.
Within a rule, its regular expressions are checked first, then its scope
names, then its captures.
§Examples
use textmate_lang::{Error, Grammar, Rule};
let grammar = Grammar::new("source.demo").pattern(Rule::include("strings"));
match grammar.to_json() {
Err(Error::UndefinedInclude { path, name }) => {
assert_eq!(path, "/patterns/0/include");
assert_eq!(name, "strings");
}
other => panic!("unexpected {other:?}"),
}Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
InvalidRegex
A regular expression is outside the supported Oniguruma subset; see
validate_regex and
RegexErrorKind for the fix.
Fields
error: RegexErrorThe byte offset in the pattern and what is wrong there.
EmptyRegex
A match, begin, end, while, or firstLineMatch pattern is
empty. An empty pattern matches everywhere without consuming text,
which tokenizers either loop on or detect and skip.
Give the pattern something to match; to end a region at once, use a
look-ahead such as (?=.) or $.
InvalidScope
A scope name is malformed: empty, with an empty segment, with a
character outside ASCII letters, digits, _, +, and -, with a
malformed $n substitution, or with a substitution where none is
allowed (scopeName, external includes).
Scopes are dot-separated segments such as keyword.control.demo; a
rule’s name may list several separated by single spaces.
Fields
InvalidSelector
A scope selector (injectionSelector or an injections key) is
malformed, in the syntax VS Code’s vscode-textmate reads: scopes
combined with ,, | (inside parentheses), -, and (...), each
top-level entry optionally prefixed with L: or R:.
Fields
InvalidName
A repository name (defined or included) or a file type is
malformed. Repository names are non-empty ASCII letters, digits, _,
-, and .; file types are non-empty.
Fields
DuplicateRepository
Two repository entries share a name. The JSON object could hold only one, so the second would silently replace the first.
DuplicateInjection
Two injections share a selector.
DuplicateCapture
A captures map sets the same group twice.
CaptureOutOfRange
A capture or a $n substitution names a group the pattern does not
have. For captures on a region, the group must exist in every
pattern the captures apply to (begin, and end or while, unless
those have their own captures); for a region’s name and
contentName, in begin.
Fields
ShadowedCaptures
A region’s captures can never apply: the region has both
beginCaptures and endCaptures (or whileCaptures), which take
precedence. Move the captures into those, or remove them.
UndefinedInclude
An include names a repository entry this grammar does not define.
IncludeCycle
Includes form a cycle in which no rule consumes text: an entry that
is only a list of patterns (or one include) includes itself through
other such entries, or through $self / $base from the top-level
patterns. Tokenizers expand these lists when building their scanners
and recurse forever: vscode-textmate collects them with a recursion
that keeps no record of lists already visited.
Recursion through a region is fine — a begin/end rule whose
patterns include the entry that contains it is how nested
constructs are written — and so is recursion through captures.
cycle lists the entries on the cycle, $self for the top-level
patterns and #name for repository entries, starting and ending with
the same one.
TooDeep
Rules nest more than MAX_RULE_DEPTH deep
(regions and captures inside regions and captures). Editors build
their rule tables recursively, so a deeper grammar can crash them;
use repository entries and includes instead.
Trait Implementations§
impl Eq for Error
Source§impl Error for Error
impl Error for Error
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()