2012-12-03 16:48:01 -08:00
|
|
|
// 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.
|
|
|
|
|
2012-09-08 15:50:29 -07:00
|
|
|
/*!
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2013-07-19 21:51:37 +10:00
|
|
|
use ast::{expr, expr_lit, lit_nil, Attribute};
|
2012-12-23 17:41:37 -05:00
|
|
|
use ast;
|
2013-01-30 09:56:33 -08:00
|
|
|
use codemap::{span, respan};
|
2013-01-08 19:37:25 -08:00
|
|
|
use parse::parser::Parser;
|
2013-05-25 17:45:45 +02:00
|
|
|
use parse::token::{keywords, Token};
|
2012-12-23 17:41:37 -05:00
|
|
|
use parse::token;
|
|
|
|
|
2013-06-24 20:40:33 -04:00
|
|
|
use std::str;
|
|
|
|
use std::to_bytes;
|
2012-09-08 15:50:29 -07:00
|
|
|
|
|
|
|
/// The specific types of unsupported syntax
|
2013-03-20 11:52:45 -04:00
|
|
|
#[deriving(Eq)]
|
2012-09-08 15:50:29 -07:00
|
|
|
pub enum ObsoleteSyntax {
|
|
|
|
ObsoleteLet,
|
|
|
|
ObsoleteFieldTerminator,
|
2012-09-10 17:26:20 -07:00
|
|
|
ObsoleteWith,
|
2012-09-10 18:56:07 -07:00
|
|
|
ObsoleteClassTraits,
|
2012-09-23 04:39:27 -07:00
|
|
|
ObsoletePrivSection,
|
2012-10-05 22:07:53 -07:00
|
|
|
ObsoleteModeInFnType,
|
2012-10-23 11:28:20 -07:00
|
|
|
ObsoleteMoveInit,
|
2013-01-23 11:43:58 -08:00
|
|
|
ObsoleteBinaryMove,
|
2013-05-06 00:43:19 -04:00
|
|
|
ObsoleteSwap,
|
2013-01-28 10:46:43 -08:00
|
|
|
ObsoleteUnsafeBlock,
|
2013-02-14 21:17:26 -08:00
|
|
|
ObsoleteUnenforcedBound,
|
2013-02-20 18:04:57 -08:00
|
|
|
ObsoleteImplSyntax,
|
2013-02-25 15:54:13 -08:00
|
|
|
ObsoleteMutOwnedPointer,
|
2013-02-26 14:50:09 -08:00
|
|
|
ObsoleteMutVector,
|
2013-06-03 16:56:35 -07:00
|
|
|
ObsoleteImplVisibility,
|
2013-03-05 17:36:59 -08:00
|
|
|
ObsoleteRecordType,
|
2013-03-05 18:38:52 -08:00
|
|
|
ObsoleteRecordPattern,
|
2013-02-27 19:41:02 -05:00
|
|
|
ObsoletePostFnTySigil,
|
2013-03-07 15:44:21 -08:00
|
|
|
ObsoleteBareFnType,
|
2013-03-07 18:59:00 -08:00
|
|
|
ObsoleteNewtypeEnum,
|
2013-03-10 11:02:16 -04:00
|
|
|
ObsoleteMode,
|
2013-03-12 19:32:14 -07:00
|
|
|
ObsoleteImplicitSelf,
|
2013-03-14 12:25:48 -07:00
|
|
|
ObsoleteLifetimeNotation,
|
2013-03-22 12:56:10 -07:00
|
|
|
ObsoletePurity,
|
|
|
|
ObsoleteStaticMethod,
|
2013-03-22 14:51:35 -07:00
|
|
|
ObsoleteConstItem,
|
2013-03-22 19:22:12 -07:00
|
|
|
ObsoleteFixedLengthVectorType,
|
2013-05-09 14:14:42 -07:00
|
|
|
ObsoleteNamedExternModule,
|
2013-06-04 21:43:41 -07:00
|
|
|
ObsoleteMultipleLocalDecl,
|
2013-06-06 18:54:14 -07:00
|
|
|
ObsoleteMutWithMultipleBindings,
|
2013-07-18 19:08:57 -07:00
|
|
|
ObsoleteExternVisibility,
|
2013-08-02 14:30:00 -07:00
|
|
|
ObsoleteUnsafeExternFn,
|
2013-08-06 23:03:31 -07:00
|
|
|
ObsoletePrivVisibility,
|
2013-08-09 01:25:24 -07:00
|
|
|
ObsoleteTraitFuncVisibility,
|
2013-08-02 21:41:06 -07:00
|
|
|
ObsoleteConstPointer,
|
2012-09-19 18:00:26 -07:00
|
|
|
}
|
2012-09-08 15:50:29 -07:00
|
|
|
|
2013-05-02 18:33:33 -04:00
|
|
|
impl to_bytes::IterBytes for ObsoleteSyntax {
|
2013-06-18 14:45:18 -07:00
|
|
|
#[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)
|
|
|
|
}
|
|
|
|
}
|
2012-09-08 15:50:29 -07:00
|
|
|
|
2013-06-14 18:21:47 -07:00
|
|
|
pub trait ParserObsoleteMethods {
|
|
|
|
/// Reports an obsolete syntax non-fatal error.
|
|
|
|
fn obsolete(&self, sp: span, kind: ObsoleteSyntax);
|
|
|
|
// Reports an obsolete syntax non-fatal error, and returns
|
|
|
|
// a placeholder expression
|
|
|
|
fn obsolete_expr(&self, sp: span, kind: ObsoleteSyntax) -> @expr;
|
|
|
|
fn report(&self,
|
|
|
|
sp: span,
|
|
|
|
kind: ObsoleteSyntax,
|
|
|
|
kind_str: &str,
|
|
|
|
desc: &str);
|
|
|
|
fn token_is_obsolete_ident(&self, ident: &str, token: &Token) -> bool;
|
|
|
|
fn is_obsolete_ident(&self, ident: &str) -> bool;
|
|
|
|
fn eat_obsolete_ident(&self, ident: &str) -> bool;
|
|
|
|
fn try_parse_obsolete_with(&self) -> bool;
|
2013-07-19 21:51:37 +10:00
|
|
|
fn try_parse_obsolete_priv_section(&self, attrs: &[Attribute]) -> bool;
|
2013-06-14 18:21:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ParserObsoleteMethods for Parser {
|
2012-09-08 15:50:29 -07:00
|
|
|
/// Reports an obsolete syntax non-fatal error.
|
2013-08-09 01:25:24 -07:00
|
|
|
fn obsolete(&self, sp: span, kind: ObsoleteSyntax) {
|
2012-09-08 15:50:29 -07:00
|
|
|
let (kind_str, desc) = match kind {
|
|
|
|
ObsoleteLet => (
|
|
|
|
"`let` in field declaration",
|
|
|
|
"declare fields as `field: Type`"
|
|
|
|
),
|
|
|
|
ObsoleteFieldTerminator => (
|
|
|
|
"field declaration terminated with semicolon",
|
|
|
|
"fields are now separated by commas"
|
|
|
|
),
|
|
|
|
ObsoleteWith => (
|
|
|
|
"with",
|
|
|
|
"record update is done with `..`, e.g. \
|
|
|
|
`MyStruct { foo: bar, .. baz }`"
|
|
|
|
),
|
2012-09-10 18:00:03 -07:00
|
|
|
ObsoleteClassTraits => (
|
|
|
|
"class traits",
|
|
|
|
"implemented traits are specified on the impl, as in \
|
|
|
|
`impl foo : bar {`"
|
|
|
|
),
|
2012-09-10 18:56:07 -07:00
|
|
|
ObsoletePrivSection => (
|
|
|
|
"private section",
|
|
|
|
"the `priv` keyword is applied to individual items, methods, \
|
|
|
|
and fields"
|
|
|
|
),
|
2012-09-23 04:39:27 -07:00
|
|
|
ObsoleteModeInFnType => (
|
|
|
|
"mode without identifier in fn type",
|
|
|
|
"to use a (deprecated) mode in a fn type, you should \
|
|
|
|
give the argument an explicit name (like `&&v: int`)"
|
|
|
|
),
|
2012-10-23 11:28:20 -07:00
|
|
|
ObsoleteMoveInit => (
|
|
|
|
"initializer-by-move",
|
|
|
|
"Write `let foo = move bar` instead"
|
|
|
|
),
|
|
|
|
ObsoleteBinaryMove => (
|
|
|
|
"binary move",
|
|
|
|
"Write `foo = move bar` instead"
|
2013-01-23 11:43:58 -08:00
|
|
|
),
|
2013-05-06 00:43:19 -04:00
|
|
|
ObsoleteSwap => (
|
|
|
|
"swap",
|
2013-06-24 20:40:33 -04:00
|
|
|
"Use std::util::{swap, replace} instead"
|
2013-05-06 00:43:19 -04:00
|
|
|
),
|
2013-01-23 11:43:58 -08:00
|
|
|
ObsoleteUnsafeBlock => (
|
|
|
|
"non-standalone unsafe block",
|
|
|
|
"use an inner `unsafe { ... }` block instead"
|
2013-01-28 10:46:43 -08:00
|
|
|
),
|
|
|
|
ObsoleteUnenforcedBound => (
|
|
|
|
"unenforced type parameter bound",
|
|
|
|
"use trait bounds on the functions that take the type as \
|
|
|
|
arguments, not on the types themselves"
|
2013-02-14 21:17:26 -08:00
|
|
|
),
|
|
|
|
ObsoleteImplSyntax => (
|
|
|
|
"colon-separated impl syntax",
|
|
|
|
"write `impl Trait for Type`"
|
2013-02-20 18:04:57 -08:00
|
|
|
),
|
2013-02-25 15:54:13 -08:00
|
|
|
ObsoleteMutOwnedPointer => (
|
2013-02-26 11:32:00 -08:00
|
|
|
"const or mutable owned pointer",
|
2013-02-25 15:54:13 -08:00
|
|
|
"mutability inherits through `~` pointers; place the `~` box
|
|
|
|
in a mutable location, like a mutable local variable or an \
|
|
|
|
`@mut` box"
|
|
|
|
),
|
2013-02-26 14:50:09 -08:00
|
|
|
ObsoleteMutVector => (
|
|
|
|
"const or mutable vector",
|
|
|
|
"mutability inherits through `~` pointers; place the vector \
|
|
|
|
in a mutable location, like a mutable local variable or an \
|
|
|
|
`@mut` box"
|
|
|
|
),
|
2013-06-03 16:56:35 -07:00
|
|
|
ObsoleteImplVisibility => (
|
|
|
|
"visibility-qualified implementation",
|
|
|
|
"`pub` or `priv` goes on individual functions; remove the \
|
|
|
|
`pub` or `priv`"
|
2013-02-26 17:12:00 -08:00
|
|
|
),
|
2013-03-05 17:36:59 -08:00
|
|
|
ObsoleteRecordType => (
|
|
|
|
"structural record type",
|
|
|
|
"use a structure instead"
|
|
|
|
),
|
2013-03-05 18:38:52 -08:00
|
|
|
ObsoleteRecordPattern => (
|
|
|
|
"structural record pattern",
|
|
|
|
"use a structure instead"
|
|
|
|
),
|
2013-02-27 19:41:02 -05:00
|
|
|
ObsoletePostFnTySigil => (
|
|
|
|
"fn sigil in postfix position",
|
|
|
|
"Rather than `fn@`, `fn~`, or `fn&`, \
|
|
|
|
write `@fn`, `~fn`, and `&fn` respectively"
|
|
|
|
),
|
2013-03-07 15:44:21 -08:00
|
|
|
ObsoleteBareFnType => (
|
|
|
|
"bare function type",
|
|
|
|
"use `&fn` or `extern fn` instead"
|
|
|
|
),
|
2013-03-07 18:59:00 -08:00
|
|
|
ObsoleteNewtypeEnum => (
|
|
|
|
"newtype enum",
|
|
|
|
"instead of `enum Foo = int`, write `struct Foo(int)`"
|
|
|
|
),
|
2013-03-10 11:02:16 -04:00
|
|
|
ObsoleteMode => (
|
|
|
|
"obsolete argument mode",
|
|
|
|
"replace `-` or `++` mode with `+`"
|
|
|
|
),
|
2013-03-12 19:32:14 -07:00
|
|
|
ObsoleteImplicitSelf => (
|
|
|
|
"implicit self",
|
|
|
|
"use an explicit `self` declaration or declare the method as \
|
|
|
|
static"
|
|
|
|
),
|
2013-03-14 12:25:48 -07:00
|
|
|
ObsoleteLifetimeNotation => (
|
|
|
|
"`/` lifetime notation",
|
|
|
|
"instead of `&foo/bar`, write `&'foo bar`; instead of \
|
|
|
|
`bar/&foo`, write `&bar<'foo>"
|
|
|
|
),
|
2013-03-22 12:56:10 -07:00
|
|
|
ObsoletePurity => (
|
|
|
|
"pure function",
|
|
|
|
"remove `pure`"
|
|
|
|
),
|
|
|
|
ObsoleteStaticMethod => (
|
|
|
|
"`static` notation",
|
|
|
|
"`static` is superfluous; remove it"
|
|
|
|
),
|
2013-03-22 14:51:35 -07:00
|
|
|
ObsoleteConstItem => (
|
|
|
|
"`const` item",
|
|
|
|
"`const` items are now `static` items; replace `const` with \
|
|
|
|
`static`"
|
|
|
|
),
|
2013-03-22 19:22:12 -07:00
|
|
|
ObsoleteFixedLengthVectorType => (
|
|
|
|
"fixed-length vector notation",
|
|
|
|
"instead of `[T * N]`, write `[T, ..N]`"
|
|
|
|
),
|
2013-05-09 14:14:42 -07:00
|
|
|
ObsoleteNamedExternModule => (
|
|
|
|
"named external module",
|
|
|
|
"instead of `extern mod foo { ... }`, write `mod foo { \
|
|
|
|
extern { ... } }`"
|
|
|
|
),
|
2013-06-04 21:43:41 -07:00
|
|
|
ObsoleteMultipleLocalDecl => (
|
|
|
|
"declaration of multiple locals at once",
|
|
|
|
"instead of e.g. `let a = 1, b = 2`, write \
|
|
|
|
`let (a, b) = (1, 2)`."
|
|
|
|
),
|
2013-06-06 18:54:14 -07:00
|
|
|
ObsoleteMutWithMultipleBindings => (
|
|
|
|
"`mut` with multiple bindings",
|
|
|
|
"use multiple local declarations instead of e.g. `let mut \
|
|
|
|
(x, y) = ...`."
|
|
|
|
),
|
2013-07-18 19:08:57 -07:00
|
|
|
ObsoleteExternVisibility => (
|
|
|
|
"`pub extern` or `priv extern`",
|
|
|
|
"place the `pub` or `priv` on the individual external items \
|
|
|
|
instead"
|
2013-08-02 14:30:00 -07:00
|
|
|
),
|
|
|
|
ObsoleteUnsafeExternFn => (
|
|
|
|
"unsafe external function",
|
|
|
|
"external functions are always unsafe; remove the `unsafe` \
|
|
|
|
keyword"
|
|
|
|
),
|
2013-08-06 23:03:31 -07:00
|
|
|
ObsoletePrivVisibility => (
|
|
|
|
"`priv` not necessary",
|
|
|
|
"an item without a visibility qualifier is private by default"
|
|
|
|
),
|
2013-08-09 01:25:24 -07:00
|
|
|
ObsoleteTraitFuncVisibility => (
|
|
|
|
"visibility not necessary",
|
|
|
|
"trait functions inherit the visibility of the trait itself"
|
|
|
|
),
|
2013-08-02 21:41:06 -07:00
|
|
|
ObsoleteConstPointer => (
|
|
|
|
"const pointer",
|
|
|
|
"instead of `&const Foo` or `@const Foo`, write `&Foo` or \
|
|
|
|
`@Foo`"
|
|
|
|
),
|
2012-09-08 15:50:29 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
self.report(sp, kind, kind_str, desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reports an obsolete syntax non-fatal error, and returns
|
|
|
|
// a placeholder expression
|
2013-08-09 01:25:24 -07:00
|
|
|
fn obsolete_expr(&self, sp: span, kind: ObsoleteSyntax) -> @expr {
|
2012-09-08 15:50:29 -07:00
|
|
|
self.obsolete(sp, kind);
|
|
|
|
self.mk_expr(sp.lo, sp.hi, expr_lit(@respan(sp, lit_nil)))
|
|
|
|
}
|
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
fn report(&self,
|
|
|
|
sp: span,
|
|
|
|
kind: ObsoleteSyntax,
|
|
|
|
kind_str: &str,
|
|
|
|
desc: &str) {
|
2012-09-08 15:50:29 -07:00
|
|
|
self.span_err(sp, fmt!("obsolete syntax: %s", kind_str));
|
|
|
|
|
2013-03-21 15:41:37 -04:00
|
|
|
if !self.obsolete_set.contains(&kind) {
|
2012-09-08 15:50:29 -07:00
|
|
|
self.sess.span_diagnostic.handler().note(fmt!("%s", desc));
|
2013-03-21 15:41:37 -04:00
|
|
|
self.obsolete_set.insert(kind);
|
2012-09-08 15:50:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-09 01:25:24 -07:00
|
|
|
fn token_is_obsolete_ident(&self, ident: &str, token: &Token)
|
2013-05-31 15:17:22 -07:00
|
|
|
-> bool {
|
2013-05-12 00:25:31 -04:00
|
|
|
match *token {
|
|
|
|
token::IDENT(sid, _) => {
|
2013-06-13 03:02:55 +10:00
|
|
|
str::eq_slice(self.id_to_str(sid), ident)
|
2012-09-08 15:50:29 -07:00
|
|
|
}
|
|
|
|
_ => false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-09 01:25:24 -07:00
|
|
|
fn is_obsolete_ident(&self, ident: &str) -> bool {
|
2013-05-12 00:25:31 -04:00
|
|
|
self.token_is_obsolete_ident(ident, self.token)
|
2012-09-08 15:50:29 -07:00
|
|
|
}
|
|
|
|
|
2013-08-09 01:25:24 -07:00
|
|
|
fn eat_obsolete_ident(&self, ident: &str) -> bool {
|
2012-09-08 15:50:29 -07:00
|
|
|
if self.is_obsolete_ident(ident) {
|
|
|
|
self.bump();
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-09 01:25:24 -07:00
|
|
|
fn try_parse_obsolete_with(&self) -> bool {
|
2013-02-21 18:12:13 -08:00
|
|
|
if *self.token == token::COMMA
|
2013-07-02 12:47:32 -07:00
|
|
|
&& self.look_ahead(1,
|
|
|
|
|t| self.token_is_obsolete_ident("with", t)) {
|
2012-09-08 15:50:29 -07:00
|
|
|
self.bump();
|
|
|
|
}
|
|
|
|
if self.eat_obsolete_ident("with") {
|
2013-02-21 18:12:13 -08:00
|
|
|
self.obsolete(*self.last_span, ObsoleteWith);
|
2012-09-08 15:50:29 -07:00
|
|
|
self.parse_expr();
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-09 01:25:24 -07:00
|
|
|
fn try_parse_obsolete_priv_section(&self, attrs: &[Attribute])
|
2013-05-31 15:17:22 -07:00
|
|
|
-> bool {
|
2013-07-02 12:47:32 -07:00
|
|
|
if self.is_keyword(keywords::Priv) &&
|
|
|
|
self.look_ahead(1, |t| *t == token::LBRACE) {
|
2013-06-27 17:41:35 -07:00
|
|
|
self.obsolete(*self.span, ObsoletePrivSection);
|
2013-05-25 17:45:45 +02:00
|
|
|
self.eat_keyword(keywords::Priv);
|
2012-09-10 18:56:07 -07:00
|
|
|
self.bump();
|
2013-02-21 18:12:13 -08:00
|
|
|
while *self.token != token::RBRACE {
|
2013-05-12 00:25:31 -04:00
|
|
|
self.parse_single_struct_field(ast::private, attrs.to_owned());
|
2012-09-10 18:56:07 -07:00
|
|
|
}
|
|
|
|
self.bump();
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
2012-10-20 16:33:59 -07:00
|
|
|
|
2012-09-08 15:50:29 -07:00
|
|
|
}
|