(index<- )        ./libsyntax/parse/obsolete.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012 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.
   4  //
   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.
  10  
  11  /*!
  12  Support for parsing unsupported, old syntaxes, for the
  13  purpose of reporting errors. Parsing of these syntaxes
  14  is tested by compile-test/obsolete-syntax.rs.
  15  
  16  Obsolete syntax that becomes too hard to parse can be
  17  removed.
  18  */
  19  
  20  use ast::{Expr, ExprLit, LitNil};
  21  use codemap::{Span, respan};
  22  use parse::parser::Parser;
  23  use parse::token;
  24  
  25  /// The specific types of unsupported syntax
  26  #[deriving(Eq, TotalEq, Hash)]
  27  pub enum ObsoleteSyntax {
  28      ObsoleteSwap,
  29      ObsoleteUnsafeBlock,
  30      ObsoleteBareFnType,
  31      ObsoleteMultipleLocalDecl,
  32      ObsoleteUnsafeExternFn,
  33      ObsoleteTraitFuncVisibility,
  34      ObsoleteConstPointer,
  35      ObsoleteLoopAsContinue,
  36      ObsoleteEnumWildcard,
  37      ObsoleteStructWildcard,
  38      ObsoleteVecDotDotWildcard,
  39      ObsoleteMultipleImport,
  40      ObsoleteManagedPattern,
  41      ObsoleteManagedString,
  42      ObsoleteManagedVec,
  43      ObsoleteOwnedType,
  44      ObsoleteOwnedExpr,
  45      ObsoleteOwnedPattern,
  46  }
  47  
  48  pub trait ParserObsoleteMethods {
  49      /// Reports an obsolete syntax non-fatal error.
  50      fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
  51      // Reports an obsolete syntax non-fatal error, and returns
  52      // a placeholder expression
  53      fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr;
  54      fn report(&mut self,
  55                sp: Span,
  56                kind: ObsoleteSyntax,
  57                kind_str: &str,
  58                desc: &str);
  59      fn is_obsolete_ident(&mut self, ident: &str) -> bool;
  60      fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
  61  }
  62  
  63  impl<'a> ParserObsoleteMethods for Parser<'a> {
  64      /// Reports an obsolete syntax non-fatal error.
  65      fn obsolete(&mut self, spSpan, kindObsoleteSyntax) {
  66          let (kind_str, desc) = match kind {
  67              ObsoleteSwap => (
  68                  "swap",
  69                  "use std::mem::{swap, replace} instead"
  70              ),
  71              ObsoleteUnsafeBlock => (
  72                  "non-standalone unsafe block",
  73                  "use an inner `unsafe { ... }` block instead"
  74              ),
  75              ObsoleteBareFnType => (
  76                  "bare function type",
  77                  "use `|A| -> B` or `extern fn(A) -> B` instead"
  78              ),
  79              ObsoleteMultipleLocalDecl => (
  80                  "declaration of multiple locals at once",
  81                  "instead of e.g. `let a = 1, b = 2`, write \
  82                   `let (a, b) = (1, 2)`."
  83              ),
  84              ObsoleteUnsafeExternFn => (
  85                  "unsafe external function",
  86                  "external functions are always unsafe; remove the `unsafe` \
  87                   keyword"
  88              ),
  89              ObsoleteTraitFuncVisibility => (
  90                  "visibility not necessary",
  91                  "trait functions inherit the visibility of the trait itself"
  92              ),
  93              ObsoleteConstPointer => (
  94                  "const pointer",
  95                  "instead of `&const Foo` or `@const Foo`, write `&Foo` or \
  96                   `@Foo`"
  97              ),
  98              ObsoleteLoopAsContinue => (
  99                  "`loop` instead of `continue`",
 100                  "`loop` is now only used for loops and `continue` is used for \
 101                   skipping iterations"
 102              ),
 103              ObsoleteEnumWildcard => (
 104                  "enum wildcard",
 105                  "use `..` instead of `*` for matching all enum fields"
 106              ),
 107              ObsoleteStructWildcard => (
 108                  "struct wildcard",
 109                  "use `..` instead of `_` for matching trailing struct fields"
 110              ),
 111              ObsoleteVecDotDotWildcard => (
 112                  "vec slice wildcard",
 113                  "use `..` instead of `.._` for matching slices"
 114              ),
 115              ObsoleteMultipleImport => (
 116                  "multiple imports",
 117                  "only one import is allowed per `use` statement"
 118              ),
 119              ObsoleteManagedPattern => (
 120                  "managed pointer pattern",
 121                  "use a nested `match` expression instead of a managed box \
 122                   pattern"
 123              ),
 124              ObsoleteManagedString => (
 125                  "managed string",
 126                  "use `Rc<StrBuf>` instead of a managed string"
 127              ),
 128              ObsoleteManagedVec => (
 129                  "managed vector",
 130                  "use `Rc<~[T]>` instead of a managed vector"
 131              ),
 132              ObsoleteOwnedType => (
 133                  "`~` notation for owned pointers",
 134                  "use `Box<T>` in `std::owned` instead"
 135              ),
 136              ObsoleteOwnedExpr => (
 137                  "`~` notation for owned pointer allocation",
 138                  "use the `box` operator instead of `~`"
 139              ),
 140              ObsoleteOwnedPattern => (
 141                  "`~` notation for owned pointer patterns",
 142                  "use the `box` operator instead of `~`"
 143              ),
 144          };
 145  
 146          self.report(sp, kind, kind_str, desc);
 147      }
 148  
 149      // Reports an obsolete syntax non-fatal error, and returns
 150      // a placeholder expression
 151      fn obsolete_expr(&mut self, spSpan, kindObsoleteSyntax) -> @Expr {
 152          self.obsolete(sp, kind);
 153          self.mk_expr(sp.lo, sp.hi, ExprLit(@respan(sp, LitNil)))
 154      }
 155  
 156      fn report(&mut self,
 157                spSpan,
 158                kindObsoleteSyntax,
 159                kind_str&str,
 160                desc&str) {
 161          self.span_err(sp, format!("obsolete syntax: {}", kind_str));
 162  
 163          if !self.obsolete_set.contains(&kind) {
 164              self.sess.span_diagnostic.handler().note(format!("{}", desc));
 165              self.obsolete_set.insert(kind);
 166          }
 167      }
 168  
 169      fn is_obsolete_ident(&mut self, ident&str) -> bool {
 170          match self.token {
 171              token::IDENT(sid, _) => {
 172                  token::get_ident(sid).equiv(&ident)
 173              }
 174              _ => false
 175          }
 176      }
 177  
 178      fn eat_obsolete_ident(&mut self, ident&str) -> bool {
 179          if self.is_obsolete_ident(ident) {
 180              self.bump();
 181              true
 182          } else {
 183              false
 184          }
 185      }
 186  }