G: type item

This commit is contained in:
Aleksey Kladov 2018-02-10 12:35:40 +03:00
parent 419b9b7e5e
commit 2ef16a4121
14 changed files with 128 additions and 34 deletions

View File

@ -26,6 +26,7 @@ Grammar(
"static",
"mut",
"unsafe",
"type",
],
contextual_keywords: [
"auto",
@ -98,6 +99,7 @@ Grammar(
"CONST_ITEM",
"TRAIT_ITEM",
"IMPL_ITEM",
"TYPE_ITEM",
"EXTERN_BLOCK",
"ENUM_VARIANT",

View File

@ -150,7 +150,14 @@ fn item(p: &mut Parser) {
}
}
}
FN_KW => {
fn_item(p);
FN_ITEM
}
TYPE_KW => {
type_item(p);
TYPE_ITEM
}
MOD_KW => {
mod_item(p);
MOD_ITEM
@ -163,10 +170,6 @@ fn item(p: &mut Parser) {
structs::enum_item(p);
ENUM_ITEM
}
FN_KW => {
fn_item(p);
FN_ITEM
}
L_CURLY => {
item.abandon(p);
error_block(p, "expected item");
@ -203,29 +206,6 @@ fn extern_block(p: &mut Parser) {
p.expect(R_CURLY);
}
fn mod_item(p: &mut Parser) {
assert!(p.at(MOD_KW));
p.bump();
if p.expect(IDENT) && !p.eat(SEMI) {
if p.expect(L_CURLY) {
mod_contents(p, true);
p.expect(R_CURLY);
}
}
}
fn abi(p: &mut Parser) {
assert!(p.at(EXTERN_KW));
let abi = p.start();
p.bump();
match p.current() {
STRING | RAW_STRING => p.bump(),
_ => (),
}
abi.complete(p, ABI);
}
fn fn_item(p: &mut Parser) {
assert!(p.at(FN_KW));
p.bump();
@ -248,3 +228,47 @@ fn fn_item(p: &mut Parser) {
p.expect(R_PAREN);
}
}
// test type_item
// type Foo = Bar;
fn type_item(p: &mut Parser) {
assert!(p.at(TYPE_KW));
p.bump();
p.expect(IDENT);
// test type_item_type_params
// type Result<T> = ();
type_params::list(p);
// test type_item_where_clause
// type Foo where Foo: Copy = ();
type_params::where_clause(p);
p.expect(EQ);
types::type_ref(p);
p.expect(SEMI);
}
fn mod_item(p: &mut Parser) {
assert!(p.at(MOD_KW));
p.bump();
if p.expect(IDENT) && !p.eat(SEMI) {
if p.expect(L_CURLY) {
mod_contents(p, true);
p.expect(R_CURLY);
}
}
}
fn abi(p: &mut Parser) {
assert!(p.at(EXTERN_KW));
let abi = p.start();
p.bump();
match p.current() {
STRING | RAW_STRING => p.bump(),
_ => (),
}
abi.complete(p, ABI);
}

View File

@ -71,5 +71,8 @@ pub(super) fn list(p: &mut Parser) {
pub(super) fn where_clause(p: &mut Parser) {
if p.at(WHERE_KW) {
p.bump();
p.expect(IDENT);
p.expect(COLON);
p.expect(IDENT);
}
}

View File

@ -1,5 +1,14 @@
use super::*;
pub(super) fn type_ref(p: &mut Parser) {
p.expect(IDENT);
match p.current() {
IDENT => p.bump(),
L_PAREN => {
p.bump();
p.expect(R_PAREN);
}
_ => {
p.error("expected type");
}
}
}

View File

@ -83,6 +83,7 @@ pub enum SyntaxKind {
STATIC_KW,
MUT_KW,
UNSAFE_KW,
TYPE_KW,
AUTO_KW,
DEFAULT_KW,
UNION_KW,
@ -97,6 +98,7 @@ pub enum SyntaxKind {
CONST_ITEM,
TRAIT_ITEM,
IMPL_ITEM,
TYPE_ITEM,
EXTERN_BLOCK,
ENUM_VARIANT,
NAMED_FIELD,
@ -203,6 +205,7 @@ impl SyntaxKind {
STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
MUT_KW => &SyntaxInfo { name: "MUT_KW" },
UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" },
TYPE_KW => &SyntaxInfo { name: "TYPE_KW" },
AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
UNION_KW => &SyntaxInfo { name: "UNION_KW" },
@ -217,6 +220,7 @@ impl SyntaxKind {
CONST_ITEM => &SyntaxInfo { name: "CONST_ITEM" },
TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" },
IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" },
TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" },
EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
@ -268,6 +272,7 @@ pub(crate) fn ident_to_keyword(ident: &str) -> Option<SyntaxKind> {
"static" => Some(STATIC_KW),
"mut" => Some(MUT_KW),
"unsafe" => Some(UNSAFE_KW),
"type" => Some(TYPE_KW),
_ => None,
}
}

View File

@ -1,3 +1,3 @@
fn use struct trait enum impl true false as extern crate
mod pub self super in where for loop while if match const
static mut
static mut type

View File

@ -47,4 +47,6 @@ WHITESPACE 1 "\n"
STATIC_KW 6 "static"
WHITESPACE 1 " "
MUT_KW 3 "mut"
WHITESPACE 1 " "
TYPE_KW 4 "type"
WHITESPACE 1 "\n"

View File

@ -0,0 +1 @@
type Result<T> = ();

View File

@ -0,0 +1,17 @@
FILE@[0; 21)
TYPE_ITEM@[0; 21)
TYPE_KW@[0; 4)
WHITESPACE@[4; 5)
IDENT@[5; 11) "Result"
TYPE_PARAM_LIST@[11; 15)
L_ANGLE@[11; 12)
TYPE_PARAM@[12; 13)
IDENT@[12; 13) "T"
R_ANGLE@[13; 14)
WHITESPACE@[14; 15)
EQ@[15; 16)
WHITESPACE@[16; 17)
L_PAREN@[17; 18)
R_PAREN@[18; 19)
SEMI@[19; 20)
WHITESPACE@[20; 21)

View File

@ -0,0 +1 @@
type Foo = Bar;

View File

@ -0,0 +1,11 @@
FILE@[0; 16)
TYPE_ITEM@[0; 16)
TYPE_KW@[0; 4)
WHITESPACE@[4; 5)
IDENT@[5; 8) "Foo"
WHITESPACE@[8; 9)
EQ@[9; 10)
WHITESPACE@[10; 11)
IDENT@[11; 14) "Bar"
SEMI@[14; 15)
WHITESPACE@[15; 16)

View File

@ -0,0 +1 @@
type Foo where Foo: Copy = ();

View File

@ -0,0 +1,19 @@
FILE@[0; 31)
TYPE_ITEM@[0; 31)
TYPE_KW@[0; 4)
WHITESPACE@[4; 5)
IDENT@[5; 8) "Foo"
WHITESPACE@[8; 9)
WHERE_KW@[9; 14)
WHITESPACE@[14; 15)
IDENT@[15; 18) "Foo"
COLON@[18; 19)
WHITESPACE@[19; 20)
IDENT@[20; 24) "Copy"
WHITESPACE@[24; 25)
EQ@[25; 26)
WHITESPACE@[26; 27)
L_PAREN@[27; 28)
R_PAREN@[28; 29)
SEMI@[29; 30)
WHITESPACE@[30; 31)

View File

@ -76,15 +76,14 @@ fn test_from_dir(dir: &Path) -> Vec<PathBuf> {
fn print_difference(expected: &str, actual: &str, path: &Path) {
let dir = project_dir();
let path = path.strip_prefix(&dir).unwrap_or_else(|_| path);
println!("\nfile: {}", path.display());
if expected.trim() == actual.trim() {
println!("whitespace difference");
println!("rewriting the file");
println!("whitespace difference, rewriting");
file::put_text(path, actual).unwrap();
} else {
let changeset = Changeset::new(actual, expected, "\n");
println!("{}", changeset);
print!("{}", changeset);
}
println!("file: {}\n", path.display());
panic!("Comparison failed")
}