rust/src/libsyntax/parse/obsolete.rs

206 lines
6.9 KiB
Rust
Raw Normal View History

// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
Support for parsing unsupported, old syntaxes, for the
purpose of reporting errors. Parsing of these syntaxes
is tested by compile-test/obsolete-syntax.rs.
Obsolete syntax that becomes too hard to parse can be
removed.
*/
use ast::{Expr, ExprLit, LitNil};
use codemap::{Span, respan};
use parse::parser::Parser;
use parse::token;
2013-06-24 20:40:33 -04:00
use std::to_bytes;
/// The specific types of unsupported syntax
#[deriving(Eq)]
pub enum ObsoleteSyntax {
ObsoleteSwap,
ObsoleteUnsafeBlock,
ObsoleteBareFnType,
ObsoleteNamedExternModule,
ObsoleteMultipleLocalDecl,
ObsoleteUnsafeExternFn,
ObsoleteTraitFuncVisibility,
ObsoleteConstPointer,
2013-10-01 14:41:59 -07:00
ObsoleteLoopAsContinue,
ObsoleteEnumWildcard,
2013-11-07 19:25:39 -08:00
ObsoleteStructWildcard,
ObsoleteVecDotDotWildcard,
ObsoleteBoxedClosure,
ObsoleteClosureType,
ObsoleteMultipleImport,
ObsoleteExternModAttributesInParens,
ObsoleteManagedPattern,
ObsoleteManagedString,
ObsoleteManagedVec,
}
2013-05-02 18:33:33 -04:00
impl to_bytes::IterBytes for ObsoleteSyntax {
#[inline]
2013-05-02 18:33:33 -04:00
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
(*self as uint).iter_bytes(lsb0, f)
}
}
pub trait ParserObsoleteMethods {
/// Reports an obsolete syntax non-fatal error.
2013-12-30 14:04:00 -08:00
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
// Reports an obsolete syntax non-fatal error, and returns
// a placeholder expression
2013-12-30 14:04:00 -08:00
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr;
fn report(&mut self,
sp: Span,
kind: ObsoleteSyntax,
kind_str: &str,
desc: &str);
2013-12-30 14:04:00 -08:00
fn is_obsolete_ident(&mut self, ident: &str) -> bool;
fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
}
impl ParserObsoleteMethods for Parser {
/// Reports an obsolete syntax non-fatal error.
2013-12-30 14:04:00 -08:00
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
let (kind_str, desc) = match kind {
ObsoleteSwap => (
"swap",
2013-06-24 20:40:33 -04:00
"Use std::util::{swap, replace} instead"
),
ObsoleteUnsafeBlock => (
"non-standalone unsafe block",
"use an inner `unsafe { ... }` block instead"
),
ObsoleteBareFnType => (
"bare function type",
"use `|A| -> B` or `extern fn(A) -> B` instead"
),
ObsoleteNamedExternModule => (
"named external module",
"instead of `extern mod foo { ... }`, write `mod foo { \
extern { ... } }`"
),
ObsoleteMultipleLocalDecl => (
"declaration of multiple locals at once",
"instead of e.g. `let a = 1, b = 2`, write \
`let (a, b) = (1, 2)`."
),
ObsoleteUnsafeExternFn => (
"unsafe external function",
"external functions are always unsafe; remove the `unsafe` \
keyword"
),
ObsoleteTraitFuncVisibility => (
"visibility not necessary",
"trait functions inherit the visibility of the trait itself"
),
ObsoleteConstPointer => (
"const pointer",
"instead of `&const Foo` or `@const Foo`, write `&Foo` or \
`@Foo`"
),
2013-10-01 14:41:59 -07:00
ObsoleteLoopAsContinue => (
"`loop` instead of `continue`",
"`loop` is now only used for loops and `continue` is used for \
skipping iterations"
),
ObsoleteEnumWildcard => (
"enum wildcard",
"use `..` instead of `*` for matching all enum fields"
),
ObsoleteStructWildcard => (
"struct wildcard",
"use `..` instead of `_` for matching trailing struct fields"
),
2013-11-07 19:25:39 -08:00
ObsoleteVecDotDotWildcard => (
"vec slice wildcard",
"use `..` instead of `.._` for matching slices"
),
ObsoleteBoxedClosure => (
"managed or owned closure",
"managed closures have been removed and owned closures are \
now written `proc()`"
),
ObsoleteClosureType => (
"closure type",
"closures are now written `|A| -> B` rather than `&fn(A) -> \
B`."
),
ObsoleteMultipleImport => (
"multiple imports",
"only one import is allowed per `use` statement"
),
ObsoleteExternModAttributesInParens => (
"`extern mod` with linkage attribute list",
"use `extern mod foo = \"bar\";` instead of \
`extern mod foo (name = \"bar\")`"
),
ObsoleteManagedPattern => (
"managed pointer pattern",
"use a nested `match` expression instead of a managed box \
pattern"
),
ObsoleteManagedString => (
"managed string",
"use `Rc<~str>` instead of a managed string"
),
ObsoleteManagedVec => (
"managed vector",
"use `Rc<~[T]>` instead of a managed vector"
),
};
self.report(sp, kind, kind_str, desc);
}
// Reports an obsolete syntax non-fatal error, and returns
// a placeholder expression
2013-12-30 14:04:00 -08:00
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr {
self.obsolete(sp, kind);
self.mk_expr(sp.lo, sp.hi, ExprLit(@respan(sp, LitNil)))
}
2013-12-30 14:04:00 -08:00
fn report(&mut self,
sp: Span,
kind: ObsoleteSyntax,
kind_str: &str,
desc: &str) {
2013-09-27 21:01:58 -07:00
self.span_err(sp, format!("obsolete syntax: {}", kind_str));
2013-03-21 15:41:37 -04:00
if !self.obsolete_set.contains(&kind) {
2013-09-27 21:01:58 -07:00
self.sess.span_diagnostic.handler().note(format!("{}", desc));
2013-03-21 15:41:37 -04:00
self.obsolete_set.insert(kind);
}
}
fn is_obsolete_ident(&mut self, ident: &str) -> bool {
match self.token {
token::IDENT(sid, _) => {
let interned_string = token::get_ident(sid.name);
interned_string.equiv(&ident)
}
_ => false
}
}
2013-12-30 14:04:00 -08:00
fn eat_obsolete_ident(&mut self, ident: &str) -> bool {
if self.is_obsolete_ident(ident) {
self.bump();
true
} else {
false
}
}
}