mut bindings

This commit is contained in:
Aleksey Kladov 2018-07-31 15:30:11 +03:00
parent 346f6e4f7d
commit 580340d1b8
5 changed files with 119 additions and 68 deletions

View File

@ -4,7 +4,7 @@ pub(super) fn pattern(p: &mut Parser) {
match p.current() {
UNDERSCORE => placeholder_pat(p),
AMPERSAND => ref_pat(p),
IDENT | REF_KW => bind_pat(p),
IDENT | REF_KW | MUT_KW => bind_pat(p),
_ => p.err_and_bump("expected pattern"),
}
}
@ -35,14 +35,18 @@ fn ref_pat(p: &mut Parser) {
// test bind_pat
// fn main() {
// let a = ();
// let ref b = ();
// let ref mut c = ();
// let d @ _ = ();
// let mut b = ();
// let ref c = ();
// let ref mut d = ();
// let e @ _ = ();
// let ref mut f @ g @ _ = ();
// }
fn bind_pat(p: &mut Parser) {
let m = p.start();
if p.eat(REF_KW) {
p.eat(MUT_KW);
} else {
p.eat(MUT_KW);
}
name(p);
if p.eat(AT) {

View File

@ -1,6 +1,8 @@
fn main() {
let a = ();
let ref b = ();
let ref mut c = ();
let d @ _ = ();
let mut b = ();
let ref c = ();
let ref mut d = ();
let e @ _ = ();
let ref mut f @ g @ _ = ();
}

View File

@ -1,5 +1,5 @@
FILE@[0; 94)
FN_ITEM@[0; 94)
FILE@[0; 146)
FN_ITEM@[0; 146)
FN_KW@[0; 2)
NAME@[2; 7)
WHITESPACE@[2; 3)
@ -8,7 +8,7 @@ FILE@[0; 94)
L_PAREN@[7; 8)
R_PAREN@[8; 9)
WHITESPACE@[9; 10)
BLOCK@[10; 94)
BLOCK@[10; 146)
L_CURLY@[10; 11)
LET_STMT@[11; 32)
WHITESPACE@[11; 16)
@ -29,7 +29,7 @@ FILE@[0; 94)
LET_KW@[32; 35)
BIND_PAT@[35; 42)
WHITESPACE@[35; 36)
REF_KW@[36; 39)
MUT_KW@[36; 39)
NAME@[39; 42)
WHITESPACE@[39; 40)
IDENT@[40; 41) "b"
@ -41,35 +41,32 @@ FILE@[0; 94)
R_PAREN@[45; 46)
SEMI@[46; 47)
WHITESPACE@[47; 52)
LET_STMT@[52; 76)
LET_STMT@[52; 72)
LET_KW@[52; 55)
BIND_PAT@[55; 66)
BIND_PAT@[55; 62)
WHITESPACE@[55; 56)
REF_KW@[56; 59)
WHITESPACE@[59; 60)
MUT_KW@[60; 63)
NAME@[63; 66)
WHITESPACE@[63; 64)
IDENT@[64; 65) "c"
WHITESPACE@[65; 66)
EQ@[66; 67)
TUPLE_EXPR@[67; 70)
WHITESPACE@[67; 68)
L_PAREN@[68; 69)
R_PAREN@[69; 70)
SEMI@[70; 71)
WHITESPACE@[71; 76)
LET_STMT@[76; 92)
LET_KW@[76; 79)
BIND_PAT@[79; 86)
NAME@[79; 82)
WHITESPACE@[79; 80)
IDENT@[80; 81) "d"
WHITESPACE@[81; 82)
AT@[82; 83)
PLACEHOLDER_PAT@[83; 86)
NAME@[59; 62)
WHITESPACE@[59; 60)
IDENT@[60; 61) "c"
WHITESPACE@[61; 62)
EQ@[62; 63)
TUPLE_EXPR@[63; 66)
WHITESPACE@[63; 64)
L_PAREN@[64; 65)
R_PAREN@[65; 66)
SEMI@[66; 67)
WHITESPACE@[67; 72)
LET_STMT@[72; 96)
LET_KW@[72; 75)
BIND_PAT@[75; 86)
WHITESPACE@[75; 76)
REF_KW@[76; 79)
WHITESPACE@[79; 80)
MUT_KW@[80; 83)
NAME@[83; 86)
WHITESPACE@[83; 84)
UNDERSCORE@[84; 85)
IDENT@[84; 85) "d"
WHITESPACE@[85; 86)
EQ@[86; 87)
TUPLE_EXPR@[87; 90)
@ -77,6 +74,54 @@ FILE@[0; 94)
L_PAREN@[88; 89)
R_PAREN@[89; 90)
SEMI@[90; 91)
WHITESPACE@[91; 92)
R_CURLY@[92; 93)
WHITESPACE@[93; 94)
WHITESPACE@[91; 96)
LET_STMT@[96; 116)
LET_KW@[96; 99)
BIND_PAT@[99; 106)
NAME@[99; 102)
WHITESPACE@[99; 100)
IDENT@[100; 101) "e"
WHITESPACE@[101; 102)
AT@[102; 103)
PLACEHOLDER_PAT@[103; 106)
WHITESPACE@[103; 104)
UNDERSCORE@[104; 105)
WHITESPACE@[105; 106)
EQ@[106; 107)
TUPLE_EXPR@[107; 110)
WHITESPACE@[107; 108)
L_PAREN@[108; 109)
R_PAREN@[109; 110)
SEMI@[110; 111)
WHITESPACE@[111; 116)
LET_STMT@[116; 144)
LET_KW@[116; 119)
BIND_PAT@[119; 138)
WHITESPACE@[119; 120)
REF_KW@[120; 123)
WHITESPACE@[123; 124)
MUT_KW@[124; 127)
NAME@[127; 130)
WHITESPACE@[127; 128)
IDENT@[128; 129) "f"
WHITESPACE@[129; 130)
AT@[130; 131)
BIND_PAT@[131; 138)
NAME@[131; 134)
WHITESPACE@[131; 132)
IDENT@[132; 133) "g"
WHITESPACE@[133; 134)
AT@[134; 135)
PLACEHOLDER_PAT@[135; 138)
WHITESPACE@[135; 136)
UNDERSCORE@[136; 137)
WHITESPACE@[137; 138)
EQ@[138; 139)
TUPLE_EXPR@[139; 142)
WHITESPACE@[139; 140)
L_PAREN@[140; 141)
R_PAREN@[141; 142)
SEMI@[142; 143)
WHITESPACE@[143; 144)
R_CURLY@[144; 145)
WHITESPACE@[145; 146)

View File

@ -3,24 +3,12 @@ extern crate itertools;
use std::hash;
use itertools::Itertools;
#[derive(Debug, Eq)]
#[derive(Debug)]
pub struct Test {
pub name: String,
pub text: String,
}
impl PartialEq for Test {
fn eq(&self, other: &Test) -> bool {
self.name.eq(&other.name)
}
}
impl hash::Hash for Test {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.name.hash(state)
}
}
pub fn collect_tests(s: &str) -> Vec<(usize, Test)> {
let mut res = vec![];
let prefix = "// ";

View File

@ -8,7 +8,7 @@ extern crate tools;
#[macro_use]
extern crate commandspec;
use std::{collections::{HashSet, HashMap}, fs, path::Path};
use std::{collections::{HashMap}, fs, path::{Path, PathBuf}};
use clap::{App, Arg, SubCommand};
use tools::{collect_tests, Test};
@ -104,21 +104,27 @@ fn gen_tests(verify: bool) -> Result<()> {
}
let existing = existing_tests(inline_tests_dir)?;
for t in existing.difference(&tests) {
panic!("Test is deleted: {}\n{}", t.name, t.text);
for t in existing.keys().filter(|&t| !tests.contains_key(t)) {
panic!("Test is deleted: {}", t);
}
let new_tests = tests.difference(&existing);
for (i, t) in new_tests.enumerate() {
let name = format!("{:04}_{}.rs", existing.len() + i + 1, t.name);
let path = inline_tests_dir.join(name);
update(&path, &t.text, verify)?;
let mut new_idx = existing.len() + 2;
for (name, test) in tests {
let path = match existing.get(&name) {
Some((path, _test)) => path.clone(),
None => {
let file_name = format!("{:04}_{}.rs", new_idx, name);
new_idx += 1;
inline_tests_dir.join(file_name)
}
};
update(&path, &test.text, verify)?;
}
Ok(())
}
fn tests_from_dir(dir: &Path) -> Result<HashSet<Test>> {
let mut res = HashSet::new();
fn tests_from_dir(dir: &Path) -> Result<HashMap<String, Test>> {
let mut res = HashMap::new();
for entry in ::walkdir::WalkDir::new(dir) {
let entry = entry.unwrap();
if !entry.file_type().is_file() {
@ -130,7 +136,7 @@ fn tests_from_dir(dir: &Path) -> Result<HashSet<Test>> {
let text = fs::read_to_string(entry.path())?;
for (_, test) in collect_tests(&text) {
if let Some(old_test) = res.replace(test) {
if let Some(old_test) = res.insert(test.name.clone(), test) {
bail!("Duplicate test: {}", old_test.name)
}
}
@ -138,18 +144,24 @@ fn tests_from_dir(dir: &Path) -> Result<HashSet<Test>> {
Ok(res)
}
fn existing_tests(dir: &Path) -> Result<HashSet<Test>> {
let mut res = HashSet::new();
fn existing_tests(dir: &Path) -> Result<HashMap<String, (PathBuf, Test)>> {
let mut res = HashMap::new();
for file in fs::read_dir(dir)? {
let file = file?;
let path = file.path();
if path.extension().unwrap_or_default() != "rs" {
continue;
}
let name = path.file_name().unwrap().to_str().unwrap();
let name = name["0000_".len()..name.len() - 3].to_string();
let name = {
let file_name = path.file_name().unwrap().to_str().unwrap();
file_name[5..file_name.len() - 3].to_string()
};
let text = fs::read_to_string(&path)?;
res.insert(Test { name, text });
let test = Test { name: name.clone(), text };
match res.insert(name, (path, test)) {
Some(old) => println!("Duplicate test: {:?}", old),
None => (),
}
}
Ok(res)
}