Skip to content
Merged

Ctx #43

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions grammar.ron
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ Grammar(
"mut",
"unsafe",
],
contextual_keywords: [
"auto",
"default",
"union",
],
tokens: [
"ERROR",
"IDENT",
Expand Down
29 changes: 18 additions & 11 deletions src/parser/event.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use {File, FileBuilder, Sink, SyntaxKind, Token};
use {File, FileBuilder, Sink, SyntaxKind, TextUnit, Token};
use syntax_kinds::TOMBSTONE;
use super::is_insignificant;

Expand Down Expand Up @@ -120,19 +120,26 @@ pub(super) fn to_file(text: String, tokens: &[Token], events: Vec<Event>) -> Fil
builder.finish_internal()
}
&Event::Token {
kind: _,
kind,
mut n_raw_tokens,
} => loop {
let token = tokens[idx];
if !is_insignificant(token.kind) {
n_raw_tokens -= 1;
} => {
// FIXME: currently, we attach whitespace to some random node
// this should be done in a sensible manner instead
loop {
let token = tokens[idx];
if !is_insignificant(token.kind) {
break;
}
builder.leaf(token.kind, token.len);
idx += 1
}
idx += 1;
builder.leaf(token.kind, token.len);
if n_raw_tokens == 0 {
break;
let mut len = TextUnit::new(0);
for _ in 0..n_raw_tokens {
len += tokens[idx].len;
idx += 1;
}
},
builder.leaf(kind, len);
}
&Event::Error { ref message } => builder.error().message(message.clone()).emit(),
}
}
Expand Down
82 changes: 68 additions & 14 deletions src/parser/grammar/items/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,76 @@ fn item(p: &mut Parser) {
CONST_ITEM
}
},
// TODO: auto trait
// test unsafe_trait
// unsafe trait T {}
UNSAFE_KW if la == TRAIT_KW => {
UNSAFE_KW => {
p.bump();
traits::trait_item(p);
TRAIT_ITEM
}
// TODO: default impl
// test unsafe_impl
// unsafe impl Foo {}
UNSAFE_KW if la == IMPL_KW => {
p.bump();
traits::impl_item(p);
IMPL_ITEM
let la = p.nth(1);
match p.current() {
// test unsafe_trait
// unsafe trait T {}
TRAIT_KW => {
traits::trait_item(p);
TRAIT_ITEM
}

// test unsafe_auto_trait
// unsafe auto trait T {}
IDENT if p.at_kw("auto") && la == TRAIT_KW => {
p.bump_remap(AUTO_KW);
traits::trait_item(p);
TRAIT_ITEM
}

// test unsafe_impl
// unsafe impl Foo {}
IMPL_KW => {
traits::impl_item(p);
IMPL_ITEM
}

// test unsafe_default_impl
// unsafe default impl Foo {}
IDENT if p.at_kw("default") && la == IMPL_KW => {
p.bump_remap(DEFAULT_KW);
traits::impl_item(p);
IMPL_ITEM
}

// test unsafe_extern_fn
// unsafe extern "C" fn foo() {}
EXTERN_KW => {
abi(p);
if !p.at(FN_KW) {
item.abandon(p);
p.error().message("expected function").emit();
return;
}
fn_item(p);
FN_ITEM
}

// test unsafe_fn
// unsafe fn foo() {}
FN_KW => {
fn_item(p);
FN_ITEM
}

t => {
item.abandon(p);
let message = "expected `trait`, `impl` or `fn`";

// test unsafe_block_in_mod
// fn foo(){} unsafe { } fn bar(){}
if t == L_CURLY {
error_block(p, message);
} else {
p.error().message(message).emit();
}
return;
}
}
}

MOD_KW => {
mod_item(p);
MOD_ITEM
Expand Down
4 changes: 1 addition & 3 deletions src/parser/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ impl<'t> ParserInput<'t> {
if !(idx < self.tokens.len()) {
return "";
}
let start_offset = self.start_offsets[idx];
let end_offset = self.tokens[idx].len;
let range = TextRange::from_to(start_offset, end_offset);
let range = TextRange::from_len(self.start_offsets[idx], self.tokens[idx].len);
&self.text[range]
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,26 @@ impl<'t> Parser<'t> {
});
}

pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
if self.current() == EOF {
// TODO: panic!?
return;
}
self.pos += 1;
self.event(Event::Token {
kind,
n_raw_tokens: 1,
});
}

pub(crate) fn nth(&self, n: u32) -> SyntaxKind {
self.inp.kind(self.pos + n)
}

pub(crate) fn at_kw(&self, t: &str) -> bool {
self.inp.text(self.pos) == t
}

pub(crate) fn current(&self) -> SyntaxKind {
self.nth(0)
}
Expand Down
110 changes: 58 additions & 52 deletions src/syntax_kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,6 @@ use tree::SyntaxInfo;
/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SyntaxKind {
USE_KW,
FN_KW,
STRUCT_KW,
ENUM_KW,
TRAIT_KW,
IMPL_KW,
TRUE_KW,
FALSE_KW,
AS_KW,
EXTERN_KW,
CRATE_KW,
MOD_KW,
PUB_KW,
SELF_KW,
SUPER_KW,
IN_KW,
WHERE_KW,
FOR_KW,
LOOP_KW,
WHILE_KW,
IF_KW,
MATCH_KW,
CONST_KW,
STATIC_KW,
MUT_KW,
UNSAFE_KW,
ERROR,
IDENT,
UNDERSCORE,
Expand Down Expand Up @@ -83,6 +57,35 @@ pub enum SyntaxKind {
COMMENT,
DOC_COMMENT,
SHEBANG,
USE_KW,
FN_KW,
STRUCT_KW,
ENUM_KW,
TRAIT_KW,
IMPL_KW,
TRUE_KW,
FALSE_KW,
AS_KW,
EXTERN_KW,
CRATE_KW,
MOD_KW,
PUB_KW,
SELF_KW,
SUPER_KW,
IN_KW,
WHERE_KW,
FOR_KW,
LOOP_KW,
WHILE_KW,
IF_KW,
MATCH_KW,
CONST_KW,
STATIC_KW,
MUT_KW,
UNSAFE_KW,
AUTO_KW,
DEFAULT_KW,
UNION_KW,
FILE,
STRUCT_ITEM,
ENUM_ITEM,
Expand Down Expand Up @@ -123,32 +126,6 @@ pub(crate) use self::SyntaxKind::*;
impl SyntaxKind {
pub(crate) fn info(self) -> &'static SyntaxInfo {
match self {
USE_KW => &SyntaxInfo { name: "USE_KW" },
FN_KW => &SyntaxInfo { name: "FN_KW" },
STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" },
ENUM_KW => &SyntaxInfo { name: "ENUM_KW" },
TRAIT_KW => &SyntaxInfo { name: "TRAIT_KW" },
IMPL_KW => &SyntaxInfo { name: "IMPL_KW" },
TRUE_KW => &SyntaxInfo { name: "TRUE_KW" },
FALSE_KW => &SyntaxInfo { name: "FALSE_KW" },
AS_KW => &SyntaxInfo { name: "AS_KW" },
EXTERN_KW => &SyntaxInfo { name: "EXTERN_KW" },
CRATE_KW => &SyntaxInfo { name: "CRATE_KW" },
MOD_KW => &SyntaxInfo { name: "MOD_KW" },
PUB_KW => &SyntaxInfo { name: "PUB_KW" },
SELF_KW => &SyntaxInfo { name: "SELF_KW" },
SUPER_KW => &SyntaxInfo { name: "SUPER_KW" },
IN_KW => &SyntaxInfo { name: "IN_KW" },
WHERE_KW => &SyntaxInfo { name: "WHERE_KW" },
FOR_KW => &SyntaxInfo { name: "FOR_KW" },
LOOP_KW => &SyntaxInfo { name: "LOOP_KW" },
WHILE_KW => &SyntaxInfo { name: "WHILE_KW" },
IF_KW => &SyntaxInfo { name: "IF_KW" },
MATCH_KW => &SyntaxInfo { name: "MATCH_KW" },
CONST_KW => &SyntaxInfo { name: "CONST_KW" },
STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
MUT_KW => &SyntaxInfo { name: "MUT_KW" },
UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" },
ERROR => &SyntaxInfo { name: "ERROR" },
IDENT => &SyntaxInfo { name: "IDENT" },
UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" },
Expand Down Expand Up @@ -200,6 +177,35 @@ impl SyntaxKind {
COMMENT => &SyntaxInfo { name: "COMMENT" },
DOC_COMMENT => &SyntaxInfo { name: "DOC_COMMENT" },
SHEBANG => &SyntaxInfo { name: "SHEBANG" },
USE_KW => &SyntaxInfo { name: "USE_KW" },
FN_KW => &SyntaxInfo { name: "FN_KW" },
STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" },
ENUM_KW => &SyntaxInfo { name: "ENUM_KW" },
TRAIT_KW => &SyntaxInfo { name: "TRAIT_KW" },
IMPL_KW => &SyntaxInfo { name: "IMPL_KW" },
TRUE_KW => &SyntaxInfo { name: "TRUE_KW" },
FALSE_KW => &SyntaxInfo { name: "FALSE_KW" },
AS_KW => &SyntaxInfo { name: "AS_KW" },
EXTERN_KW => &SyntaxInfo { name: "EXTERN_KW" },
CRATE_KW => &SyntaxInfo { name: "CRATE_KW" },
MOD_KW => &SyntaxInfo { name: "MOD_KW" },
PUB_KW => &SyntaxInfo { name: "PUB_KW" },
SELF_KW => &SyntaxInfo { name: "SELF_KW" },
SUPER_KW => &SyntaxInfo { name: "SUPER_KW" },
IN_KW => &SyntaxInfo { name: "IN_KW" },
WHERE_KW => &SyntaxInfo { name: "WHERE_KW" },
FOR_KW => &SyntaxInfo { name: "FOR_KW" },
LOOP_KW => &SyntaxInfo { name: "LOOP_KW" },
WHILE_KW => &SyntaxInfo { name: "WHILE_KW" },
IF_KW => &SyntaxInfo { name: "IF_KW" },
MATCH_KW => &SyntaxInfo { name: "MATCH_KW" },
CONST_KW => &SyntaxInfo { name: "CONST_KW" },
STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
MUT_KW => &SyntaxInfo { name: "MUT_KW" },
UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" },
AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
UNION_KW => &SyntaxInfo { name: "UNION_KW" },
FILE => &SyntaxInfo { name: "FILE" },
STRUCT_ITEM => &SyntaxInfo { name: "STRUCT_ITEM" },
ENUM_ITEM => &SyntaxInfo { name: "ENUM_ITEM" },
Expand Down
1 change: 1 addition & 0 deletions tests/data/parser/inline/0009_unsafe_auto_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
unsafe auto trait T {}
13 changes: 13 additions & 0 deletions tests/data/parser/inline/0009_unsafe_auto_trait.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FILE@[0; 23)
TRAIT_ITEM@[0; 23)
UNSAFE_KW@[0; 6)
WHITESPACE@[6; 7)
AUTO_KW@[7; 11)
WHITESPACE@[11; 12)
TRAIT_KW@[12; 17)
WHITESPACE@[17; 18)
IDENT@[18; 19) "T"
WHITESPACE@[19; 20)
L_CURLY@[20; 21)
R_CURLY@[21; 22)
WHITESPACE@[22; 23)
1 change: 1 addition & 0 deletions tests/data/parser/inline/0010_unsafe_default_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
unsafe default impl Foo {}
13 changes: 13 additions & 0 deletions tests/data/parser/inline/0010_unsafe_default_impl.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FILE@[0; 27)
IMPL_ITEM@[0; 27)
UNSAFE_KW@[0; 6)
WHITESPACE@[6; 7)
DEFAULT_KW@[7; 14)
WHITESPACE@[14; 15)
IMPL_KW@[15; 19)
WHITESPACE@[19; 20)
IDENT@[20; 23) "Foo"
WHITESPACE@[23; 24)
L_CURLY@[24; 25)
R_CURLY@[25; 26)
WHITESPACE@[26; 27)
1 change: 1 addition & 0 deletions tests/data/parser/inline/0011_unsafe_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
unsafe fn foo() {}
13 changes: 13 additions & 0 deletions tests/data/parser/inline/0011_unsafe_fn.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FILE@[0; 19)
FN_ITEM@[0; 19)
UNSAFE_KW@[0; 6)
WHITESPACE@[6; 7)
FN_KW@[7; 9)
WHITESPACE@[9; 10)
IDENT@[10; 13) "foo"
L_PAREN@[13; 14)
R_PAREN@[14; 15)
WHITESPACE@[15; 16)
L_CURLY@[16; 17)
R_CURLY@[17; 18)
WHITESPACE@[18; 19)
1 change: 1 addition & 0 deletions tests/data/parser/inline/0012_unsafe_extern_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
unsafe extern "C" fn foo() {}
18 changes: 18 additions & 0 deletions tests/data/parser/inline/0012_unsafe_extern_fn.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FILE@[0; 30)
FN_ITEM@[0; 30)
UNSAFE_KW@[0; 6)
ABI@[6; 18)
WHITESPACE@[6; 7)
EXTERN_KW@[7; 13)
WHITESPACE@[13; 14)
STRING@[14; 17)
WHITESPACE@[17; 18)
FN_KW@[18; 20)
WHITESPACE@[20; 21)
IDENT@[21; 24) "foo"
L_PAREN@[24; 25)
R_PAREN@[25; 26)
WHITESPACE@[26; 27)
L_CURLY@[27; 28)
R_CURLY@[28; 29)
WHITESPACE@[29; 30)
1 change: 1 addition & 0 deletions tests/data/parser/inline/0013_unsafe_block_in_mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn foo(){} unsafe { } fn bar(){}
Loading