]>
git.proxmox.com Git - rustc.git/blob - src/tools/tidy/src/features.rs
0b989d92b3d1d0df4cdb104efda8186671f7c44a
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Tidy check to ensure that unstable features are all in order
13 //! This check will ensure properties like:
15 //! * All stability attributes look reasonably well formed
16 //! * The set of library features is disjoint from the set of language features
17 //! * Library features have at most one stability level
18 //! * Library features have at most one `since` value
20 use std
::collections
::HashMap
;
22 use std
::io
::prelude
::*;
25 const STATUSES
: &'
static [&'
static str] = &[
26 "Active", "Deprecated", "Removed", "Accepted",
40 pub fn check(path
: &Path
, bad
: &mut bool
) {
41 let features
= collect_lang_features(&path
.join("libsyntax/feature_gate.rs"));
42 let mut lib_features
= HashMap
::<String
, LibFeature
>::new();
44 let mut contents
= String
::new();
46 &mut |path
| super::filter_dirs(path
) || path
.ends_with("src/test"),
48 let filename
= file
.file_name().unwrap().to_string_lossy();
49 if !filename
.ends_with(".rs") || filename
== "features.rs" {
54 t
!(t
!(File
::open(file
)).read_to_string(&mut contents
));
56 for (i
, line
) in contents
.lines().enumerate() {
57 let mut err
= |msg
: &str| {
58 println
!("{}:{}: {}", file
.display(), i
+ 1, msg
);
61 let level
= if line
.contains("[unstable(") {
63 } else if line
.contains("[stable(") {
68 let feature_name
= match find_attr_val(line
, "feature") {
71 err("malformed stability attribute");
75 let since
= match find_attr_val(line
, "since") {
77 None
if level
== "stable" => {
78 err("malformed stability attribute");
84 if features
.iter().any(|f
| f
.name
== feature_name
) {
85 err("duplicating a lang feature");
87 if let Some(ref s
) = lib_features
.get(feature_name
) {
89 err("different stability level than before");
92 err("different `since` than before");
96 lib_features
.insert(feature_name
.to_owned(), LibFeature
{
97 level
: level
.to_owned(),
98 since
: since
.to_owned(),
107 let mut lines
= Vec
::new();
108 for feature
in features
{
109 lines
.push(format
!("{:<32} {:<8} {:<12} {:<8}",
110 feature
.name
, "lang", feature
.status
, feature
.since
));
112 for (name
, feature
) in lib_features
{
113 lines
.push(format
!("{:<32} {:<8} {:<12} {:<8}",
114 name
, "lib", feature
.level
, feature
.since
));
119 println
!("* {}", line
);
123 fn find_attr_val
<'a
>(line
: &'a
str, attr
: &str) -> Option
<&'a
str> {
124 line
.find(attr
).and_then(|i
| {
125 line
[i
..].find("\"").map(|j
| i
+ j
+ 1)
127 line
[i
..].find("\"").map(|j
| (i
, i
+ j
))
133 fn collect_lang_features(path
: &Path
) -> Vec
<Feature
> {
134 let mut contents
= String
::new();
135 t
!(t
!(File
::open(path
)).read_to_string(&mut contents
));
137 let mut features
= Vec
::new();
138 for line
in contents
.lines().map(|l
| l
.trim()) {
139 if !STATUSES
.iter().any(|s
| line
.starts_with(&format
!("({}", s
))) {
142 let mut parts
= line
.split(",");
143 let status
= match &parts
.next().unwrap().trim().replace("(", "")[..] {
144 "active" => "unstable",
145 "removed" => "unstable",
146 "accepted" => "stable",
147 s
=> panic
!("unknown status: {}", s
),
149 let name
= parts
.next().unwrap().trim().to_owned();
150 let since
= parts
.next().unwrap().trim().replace("\"", "");
152 features
.push(Feature
{
155 status
: status
.to_owned(),