syntax: Tidy up parsing the new attribute syntax
This commit is contained in:
parent
4e00cf6134
commit
84a91b8603
@ -12,6 +12,7 @@
|
||||
#[feature(phase)];
|
||||
|
||||
#[allow(non_camel_case_types)];
|
||||
#[allow(deprecated_owned_vector)]; // NOTE: remove after stage0
|
||||
#[deny(warnings)];
|
||||
|
||||
extern crate test;
|
||||
|
@ -24,6 +24,7 @@
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
#[allow(missing_doc)];
|
||||
#[feature(managed_boxes)];
|
||||
#[allow(deprecated_owned_vector)]; // NOTE: remove after stage0
|
||||
|
||||
extern crate collections;
|
||||
|
||||
|
@ -174,6 +174,7 @@
|
||||
// NB this does *not* include globs, please keep it that way.
|
||||
#[feature(macro_rules, phase)];
|
||||
#[allow(visible_private_types)];
|
||||
#[allow(deprecated_owned_vector)]; // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
extern crate rand;
|
||||
|
@ -42,6 +42,7 @@ via `close` and `delete` methods.
|
||||
#[feature(macro_rules)];
|
||||
#[deny(unused_result, unused_must_use)];
|
||||
#[allow(visible_private_types)];
|
||||
#[allow(deprecated_owned_vector)]; // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] extern crate green;
|
||||
|
||||
|
@ -58,41 +58,40 @@ impl<'a> ParserAttr for Parser<'a> {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
// matches attribute = # [ meta_item ]
|
||||
// matches attribute = # ! [ meta_item ]
|
||||
//
|
||||
// if permit_inner is true, then a trailing `;` indicates an inner
|
||||
// if permit_inner is true, then a leading `!` indicates an inner
|
||||
// attribute
|
||||
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
|
||||
debug!("parse_attributes: permit_inner={:?} self.token={:?}",
|
||||
permit_inner, self.token);
|
||||
let mut warned = false;
|
||||
let (span, value) = match self.token {
|
||||
let (span, value, mut style) = match self.token {
|
||||
INTERPOLATED(token::NtAttr(attr)) => {
|
||||
assert!(attr.node.style == ast::AttrOuter);
|
||||
self.bump();
|
||||
(attr.span, attr.node.value)
|
||||
(attr.span, attr.node.value, ast::AttrOuter)
|
||||
}
|
||||
token::POUND => {
|
||||
let lo = self.span.lo;
|
||||
self.bump();
|
||||
|
||||
if self.eat(&token::NOT) {
|
||||
let style = if self.eat(&token::NOT) {
|
||||
if !permit_inner {
|
||||
self.fatal("an inner attribute was not permitted in this context.");
|
||||
self.span_err(self.span,
|
||||
"an inner attribute is not permitted in \
|
||||
this context");
|
||||
}
|
||||
ast::AttrInner
|
||||
} else {
|
||||
warned = true;
|
||||
// NOTE: uncomment this after a stage0 snap
|
||||
//self.warn("The syntax for inner attributes have changed.
|
||||
// Use `#![lang(foo)]` instead.");
|
||||
}
|
||||
ast::AttrOuter
|
||||
};
|
||||
|
||||
self.expect(&token::LBRACKET);
|
||||
let meta_item = self.parse_meta_item();
|
||||
self.expect(&token::RBRACKET);
|
||||
|
||||
let hi = self.span.hi;
|
||||
(mk_sp(lo, hi), meta_item)
|
||||
(mk_sp(lo, hi), meta_item, style)
|
||||
}
|
||||
_ => {
|
||||
let token_str = self.this_token_to_str();
|
||||
@ -101,21 +100,12 @@ impl<'a> ParserAttr for Parser<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
let style = if permit_inner {
|
||||
|
||||
if self.eat(&token::SEMI) {
|
||||
// Only warn the user once if the syntax is the old one.
|
||||
if !warned {
|
||||
// NOTE: uncomment this after a stage0 snap
|
||||
//self.warn("This uses the old attribute syntax. Semicolons
|
||||
// are not longer required.");
|
||||
}
|
||||
}
|
||||
|
||||
ast::AttrInner
|
||||
} else {
|
||||
ast::AttrOuter
|
||||
};
|
||||
if permit_inner && self.eat(&token::SEMI) {
|
||||
// NOTE: uncomment this after a stage0 snap
|
||||
//self.warn("This uses the old attribute syntax. Semicolons
|
||||
// are not longer required.");
|
||||
style = ast::AttrInner;
|
||||
}
|
||||
|
||||
return Spanned {
|
||||
span: span,
|
||||
|
@ -12,7 +12,7 @@ use ast;
|
||||
use codemap::{BytePos, CharPos, CodeMap, Pos};
|
||||
use diagnostic;
|
||||
use parse::lexer::{is_whitespace, with_str_from, Reader};
|
||||
use parse::lexer::{StringReader, bump, peek, is_eof, nextch_is, TokenAndSpan};
|
||||
use parse::lexer::{StringReader, bump, is_eof, nextch_is, TokenAndSpan};
|
||||
use parse::lexer::{is_line_non_doc_comment, is_block_non_doc_comment};
|
||||
use parse::lexer;
|
||||
use parse::token;
|
||||
@ -319,7 +319,9 @@ fn read_block_comment(rdr: &StringReader,
|
||||
fn peeking_at_comment(rdr: &StringReader) -> bool {
|
||||
return (rdr.curr_is('/') && nextch_is(rdr, '/')) ||
|
||||
(rdr.curr_is('/') && nextch_is(rdr, '*')) ||
|
||||
(rdr.curr_is('#') && nextch_is(rdr, '!'));
|
||||
// consider shebangs comments, but not inner attributes
|
||||
(rdr.curr_is('#') && nextch_is(rdr, '!') &&
|
||||
!lexer::nextnextch_is(rdr, '['));
|
||||
}
|
||||
|
||||
fn consume_comment(rdr: &StringReader,
|
||||
@ -331,11 +333,7 @@ fn consume_comment(rdr: &StringReader,
|
||||
} else if rdr.curr_is('/') && nextch_is(rdr, '*') {
|
||||
read_block_comment(rdr, code_to_the_left, comments);
|
||||
} else if rdr.curr_is('#') && nextch_is(rdr, '!') {
|
||||
// Make sure the following token is **not** the beginning
|
||||
// of an inner attribute, which starts with the same syntax.
|
||||
if peek(rdr, 2).unwrap() != '[' {
|
||||
read_shebang_comment(rdr, code_to_the_left, comments);
|
||||
}
|
||||
read_shebang_comment(rdr, code_to_the_left, comments);
|
||||
} else { fail!(); }
|
||||
debug!("<<< consume comment");
|
||||
}
|
||||
|
@ -18,9 +18,10 @@ use parse::token::{str_to_ident};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::char;
|
||||
use std::rc::Rc;
|
||||
use std::mem::replace;
|
||||
use std::num::from_str_radix;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
|
||||
pub use ext::tt::transcribe::{TtReader, new_tt_reader};
|
||||
|
||||
@ -272,16 +273,6 @@ pub fn bump(rdr: &StringReader) {
|
||||
}
|
||||
}
|
||||
|
||||
// EFFECT: Peek 'n' characters ahead.
|
||||
pub fn peek(rdr: &StringReader, n: uint) -> Option<char> {
|
||||
let offset = byte_offset(rdr, rdr.pos.get()).to_uint() + (n - 1);
|
||||
if offset < (rdr.filemap.src).len() {
|
||||
Some(rdr.filemap.src.char_at(offset))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_eof(rdr: &StringReader) -> bool {
|
||||
rdr.curr.get().is_none()
|
||||
}
|
||||
@ -298,6 +289,21 @@ pub fn nextch_is(rdr: &StringReader, c: char) -> bool {
|
||||
nextch(rdr) == Some(c)
|
||||
}
|
||||
|
||||
pub fn nextnextch(rdr: &StringReader) -> Option<char> {
|
||||
let offset = byte_offset(rdr, rdr.pos.get()).to_uint();
|
||||
let s = rdr.filemap.deref().src.as_slice();
|
||||
if offset >= s.len() { return None }
|
||||
let str::CharRange { next, .. } = s.char_range_at(offset);
|
||||
if next < s.len() {
|
||||
Some(s.char_at(next))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn nextnextch_is(rdr: &StringReader, c: char) -> bool {
|
||||
nextnextch(rdr) == Some(c)
|
||||
}
|
||||
|
||||
fn hex_digit_val(c: Option<char>) -> int {
|
||||
let d = c.unwrap_or('\x00');
|
||||
|
||||
@ -384,7 +390,7 @@ fn consume_any_line_comment(rdr: &StringReader)
|
||||
if nextch_is(rdr, '!') {
|
||||
|
||||
// Parse an inner attribute.
|
||||
if peek(rdr, 2).unwrap() == '[' {
|
||||
if nextnextch_is(rdr, '[') {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
|
||||
#[feature(asm, macro_rules)];
|
||||
#[allow(deprecated_owned_vector)]; // NOTE: remove after stage0
|
||||
|
||||
extern crate collections;
|
||||
extern crate getopts;
|
||||
|
@ -10,5 +10,5 @@
|
||||
|
||||
fn main() {}
|
||||
|
||||
#![lang(foo)] //~ ERROR An inner attribute was not permitted in this context.
|
||||
fn foo() {}
|
||||
#![lang(foo)] //~ ERROR an inner attribute is not permitted in this context
|
||||
fn foo() {}
|
||||
|
@ -8,4 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
# //~ ERROR 11:1: 11:2 error: expected item
|
||||
# //~ ERROR 11:1: 11:2 error: expected `[` but found `<eof>`
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:expected item
|
||||
// error-pattern:expected `[` but found `~`
|
||||
mod blade_runner {
|
||||
#~[doc(
|
||||
brief = "Blade Runner is probably the best movie ever",
|
||||
|
@ -13,4 +13,4 @@ mod foo {
|
||||
#![feature(globs)]
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
pub fn main() {}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![allow(unknown_features)]
|
||||
#![feature(bogus)]
|
||||
fn main() { }
|
||||
// ignore-license
|
||||
pub fn main() { }
|
||||
// ignore-license
|
||||
// ignore-fast
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-fast
|
||||
|
||||
#[main]
|
||||
fn foo() {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user