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", "static",
"mut", "mut",
"unsafe", "unsafe",
"type",
], ],
contextual_keywords: [ contextual_keywords: [
"auto", "auto",
@ -98,6 +99,7 @@ Grammar(
"CONST_ITEM", "CONST_ITEM",
"TRAIT_ITEM", "TRAIT_ITEM",
"IMPL_ITEM", "IMPL_ITEM",
"TYPE_ITEM",
"EXTERN_BLOCK", "EXTERN_BLOCK",
"ENUM_VARIANT", "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_KW => {
mod_item(p); mod_item(p);
MOD_ITEM MOD_ITEM
@ -163,10 +170,6 @@ fn item(p: &mut Parser) {
structs::enum_item(p); structs::enum_item(p);
ENUM_ITEM ENUM_ITEM
} }
FN_KW => {
fn_item(p);
FN_ITEM
}
L_CURLY => { L_CURLY => {
item.abandon(p); item.abandon(p);
error_block(p, "expected item"); error_block(p, "expected item");
@ -203,29 +206,6 @@ fn extern_block(p: &mut Parser) {
p.expect(R_CURLY); 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) { fn fn_item(p: &mut Parser) {
assert!(p.at(FN_KW)); assert!(p.at(FN_KW));
p.bump(); p.bump();
@ -248,3 +228,47 @@ fn fn_item(p: &mut Parser) {
p.expect(R_PAREN); 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) { pub(super) fn where_clause(p: &mut Parser) {
if p.at(WHERE_KW) { if p.at(WHERE_KW) {
p.bump(); p.bump();
p.expect(IDENT);
p.expect(COLON);
p.expect(IDENT);
} }
} }

View File

@ -1,5 +1,14 @@
use super::*; use super::*;
pub(super) fn type_ref(p: &mut Parser) { 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, STATIC_KW,
MUT_KW, MUT_KW,
UNSAFE_KW, UNSAFE_KW,
TYPE_KW,
AUTO_KW, AUTO_KW,
DEFAULT_KW, DEFAULT_KW,
UNION_KW, UNION_KW,
@ -97,6 +98,7 @@ pub enum SyntaxKind {
CONST_ITEM, CONST_ITEM,
TRAIT_ITEM, TRAIT_ITEM,
IMPL_ITEM, IMPL_ITEM,
TYPE_ITEM,
EXTERN_BLOCK, EXTERN_BLOCK,
ENUM_VARIANT, ENUM_VARIANT,
NAMED_FIELD, NAMED_FIELD,
@ -203,6 +205,7 @@ impl SyntaxKind {
STATIC_KW => &SyntaxInfo { name: "STATIC_KW" }, STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
MUT_KW => &SyntaxInfo { name: "MUT_KW" }, MUT_KW => &SyntaxInfo { name: "MUT_KW" },
UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" }, UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" },
TYPE_KW => &SyntaxInfo { name: "TYPE_KW" },
AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
UNION_KW => &SyntaxInfo { name: "UNION_KW" }, UNION_KW => &SyntaxInfo { name: "UNION_KW" },
@ -217,6 +220,7 @@ impl SyntaxKind {
CONST_ITEM => &SyntaxInfo { name: "CONST_ITEM" }, CONST_ITEM => &SyntaxInfo { name: "CONST_ITEM" },
TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" }, TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" },
IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" },
TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" },
EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
@ -268,6 +272,7 @@ pub(crate) fn ident_to_keyword(ident: &str) -> Option<SyntaxKind> {
"static" => Some(STATIC_KW), "static" => Some(STATIC_KW),
"mut" => Some(MUT_KW), "mut" => Some(MUT_KW),
"unsafe" => Some(UNSAFE_KW), "unsafe" => Some(UNSAFE_KW),
"type" => Some(TYPE_KW),
_ => None, _ => None,
} }
} }

View File

@ -1,3 +1,3 @@
fn use struct trait enum impl true false as extern crate fn use struct trait enum impl true false as extern crate
mod pub self super in where for loop while if match const 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" STATIC_KW 6 "static"
WHITESPACE 1 " " WHITESPACE 1 " "
MUT_KW 3 "mut" MUT_KW 3 "mut"
WHITESPACE 1 " "
TYPE_KW 4 "type"
WHITESPACE 1 "\n" 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) { fn print_difference(expected: &str, actual: &str, path: &Path) {
let dir = project_dir(); let dir = project_dir();
let path = path.strip_prefix(&dir).unwrap_or_else(|_| path); let path = path.strip_prefix(&dir).unwrap_or_else(|_| path);
println!("\nfile: {}", path.display());
if expected.trim() == actual.trim() { if expected.trim() == actual.trim() {
println!("whitespace difference"); println!("whitespace difference, rewriting");
println!("rewriting the file");
file::put_text(path, actual).unwrap(); file::put_text(path, actual).unwrap();
} else { } else {
let changeset = Changeset::new(actual, expected, "\n"); let changeset = Changeset::new(actual, expected, "\n");
println!("{}", changeset); print!("{}", changeset);
} }
println!("file: {}\n", path.display());
panic!("Comparison failed") panic!("Comparison failed")
} }