From 506f69aed7e2f5dfdd2134ae0c74e47559e1c649 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 31 Aug 2013 17:13:57 +1000 Subject: Implement support for indicating the stability of items. There are 6 new compiler recognised attributes: deprecated, experimental, unstable, stable, frozen, locked (these levels are taken directly from Node's "stability index"[1]). These indicate the stability of the item to which they are attached; e.g. `#[deprecated] fn foo() { .. }` says that `foo` is deprecated. This comes with 3 lints for the first 3 levels (with matching names) that will detect the use of items marked with them (the `unstable` lint includes items with no stability attribute). The attributes can be given a short text note that will be displayed by the lint. An example: #[warn(unstable)]; // `allow` by default #[deprecated="use `bar`"] fn foo() { } #[stable] fn bar() { } fn baz() { } fn main() { foo(); // "warning: use of deprecated item: use `bar`" bar(); // all fine baz(); // "warning: use of unmarked item" } The lints currently only check the "edges" of the AST: i.e. functions, methods[2], structs and enum variants. Any stability attributes on modules, enums, traits and impls are not checked. [1]: http://nodejs.org/api/documentation.html [2]: the method check is currently incorrect and doesn't work. --- src/libsyntax/ast_map.rs | 20 ++++++++++++++++++++ src/libsyntax/attr.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index ccaadcbad4d..e3023b919f8 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -80,6 +80,26 @@ pub enum ast_node { node_callee_scope(@Expr) } +impl ast_node { + pub fn with_attrs(&self, f: &fn(Option<&[Attribute]>) -> T) -> T { + let attrs = match *self { + node_item(i, _) => Some(i.attrs.as_slice()), + node_foreign_item(fi, _, _, _) => Some(fi.attrs.as_slice()), + node_trait_method(tm, _, _) => match *tm { + required(ref type_m) => Some(type_m.attrs.as_slice()), + provided(m) => Some(m.attrs.as_slice()) + }, + node_method(m, _, _) => Some(m.attrs.as_slice()), + node_variant(ref v, _, _) => Some(v.node.attrs.as_slice()), + // unit/tuple structs take the attributes straight from + // the struct definition. + node_struct_ctor(_, strct, _) => Some(strct.attrs.as_slice()), + _ => None + }; + f(attrs) + } +} + pub type map = @mut HashMap; pub struct Ctx { diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 2ed03040fa1..fd0887de722 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -313,6 +313,44 @@ pub fn test_cfg> no_cfgs || some_cfg_matches } +/// Represents the #[deprecated="foo"] (etc) attributes. +pub struct Stability { + level: StabilityLevel, + text: Option<@str> +} + +/// The available stability levels. +#[deriving(Eq,Ord,Clone)] +pub enum StabilityLevel { + Deprecated, + Experimental, + Unstable, + Stable, + Frozen, + Locked +} + +/// Find the first stability attribute. `None` if none exists. +pub fn find_stability>(mut metas: It) -> Option { + for m in metas { + let level = match m.name().as_slice() { + "deprecated" => Deprecated, + "experimental" => Experimental, + "unstable" => Unstable, + "stable" => Stable, + "frozen" => Frozen, + "locked" => Locked, + _ => loop // not a stability level + }; + + return Some(Stability { + level: level, + text: m.value_str() + }); + } + None +} + pub fn require_unique_names(diagnostic: @mut span_handler, metas: &[@MetaItem]) { let mut set = HashSet::new(); -- cgit 1.4.1-3-g733a5