|
| 1 | +//! Checks that no Fluent messages or attributes end in periods (except ellipses) |
| 2 | +
|
| 3 | +use fluent_syntax::ast::{Entry,PatternElement}; |
| 4 | + |
| 5 | +usecrate::walk::{filter_dirs, walk}; |
| 6 | +use std::path::Path; |
| 7 | + |
| 8 | +fnfilter_fluent(path:&Path) -> bool{ |
| 9 | +ifletSome(ext) = path.extension(){ ext.to_str() != Some("ftl")}else{true} |
| 10 | +} |
| 11 | + |
| 12 | +/// Messages allowed to have `.` at their end. |
| 13 | +/// |
| 14 | +/// These should probably be reworked eventually. |
| 15 | +constALLOWLIST:&[&str] = &[ |
| 16 | +"const_eval_long_running", |
| 17 | +"const_eval_validation_failure_note", |
| 18 | +"driver_impl_ice", |
| 19 | +"incremental_corrupt_file", |
| 20 | +"mir_build_pointer_pattern", |
| 21 | +]; |
| 22 | + |
| 23 | +fncheck_period(filename:&str,contents:&str,bad:&mutbool){ |
| 24 | +if filename.contains("codegen"){ |
| 25 | +// FIXME: Too many codegen messages have periods right now... |
| 26 | +return; |
| 27 | +} |
| 28 | + |
| 29 | +let(Ok(parse) | Err((parse, _))) = fluent_syntax::parser::parse(contents); |
| 30 | +for entry in&parse.body{ |
| 31 | +ifletEntry::Message(m) = entry { |
| 32 | +ifALLOWLIST.contains(&m.id.name){ |
| 33 | +continue; |
| 34 | +} |
| 35 | + |
| 36 | +ifletSome(pat) = &m.value{ |
| 37 | +ifletSome(PatternElement::TextElement{ value }) = pat.elements.last(){ |
| 38 | +// We don't care about ellipses. |
| 39 | +if value.ends_with(".") && !value.ends_with("..."){ |
| 40 | +let ll = find_line(contents,*value); |
| 41 | +let name = m.id.name; |
| 42 | +tidy_error!(bad,"{filename}:{ll}: message `{name}` ends in a period"); |
| 43 | +} |
| 44 | +} |
| 45 | +} |
| 46 | + |
| 47 | +for attr in&m.attributes{ |
| 48 | +// Teach notes usually have long messages. |
| 49 | +if attr.id.name == "teach_note"{ |
| 50 | +continue; |
| 51 | +} |
| 52 | + |
| 53 | +ifletSome(PatternElement::TextElement{ value }) = attr.value.elements.last(){ |
| 54 | +if value.ends_with(".") && !value.ends_with("..."){ |
| 55 | +let ll = find_line(contents,*value); |
| 56 | +let name = attr.id.name; |
| 57 | +tidy_error!(bad,"{filename}:{ll}: attr `{name}` ends in a period"); |
| 58 | +} |
| 59 | +} |
| 60 | +} |
| 61 | +} |
| 62 | +} |
| 63 | +} |
| 64 | + |
| 65 | +/// Evil cursed bad hack. Requires that `value` be a substr (in memory) of `contents`. |
| 66 | +fnfind_line(haystack:&str,needle:&str) -> usize{ |
| 67 | +for(ll, line)in haystack.lines().enumerate(){ |
| 68 | +if line.as_ptr() > needle.as_ptr(){ |
| 69 | +return ll; |
| 70 | +} |
| 71 | +} |
| 72 | + |
| 73 | +1 |
| 74 | +} |
| 75 | + |
| 76 | +pubfncheck(path:&Path,bad:&mutbool){ |
| 77 | +walk( |
| 78 | + path, |
| 79 | + |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), |
| 80 | +&mut |ent, contents| { |
| 81 | +check_period(ent.path().to_str().unwrap(), contents, bad); |
| 82 | +}, |
| 83 | +); |
| 84 | +} |
0 commit comments