mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
G: struct fields
This commit is contained in:
parent
55602727c8
commit
d0900b3ca7
9 changed files with 86 additions and 11 deletions
|
@ -62,6 +62,7 @@ Grammar(
|
||||||
],
|
],
|
||||||
nodes: [
|
nodes: [
|
||||||
"FILE",
|
"FILE",
|
||||||
"STRUCT_ITEM"
|
"STRUCT_ITEM",
|
||||||
|
"STRUCT_FIELD",
|
||||||
]
|
]
|
||||||
)
|
)
|
|
@ -6,7 +6,6 @@ extern crate ron;
|
||||||
extern crate file;
|
extern crate file;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::ascii::AsciiExt;
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use super::Event;
|
|
||||||
use super::parser::Parser;
|
use super::parser::Parser;
|
||||||
|
|
||||||
use syntax_kinds::*;
|
use syntax_kinds::*;
|
||||||
|
@ -50,10 +49,26 @@ fn item(p: &mut Parser) -> Result {
|
||||||
ERR
|
ERR
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_item(p: &mut Parser) -> Result{
|
fn struct_item(p: &mut Parser) -> Result {
|
||||||
p.expect(IDENT)?;
|
p.expect(IDENT)?;
|
||||||
p.expect(L_CURLY)?;
|
p.curly_block(|p| {
|
||||||
p.expect(R_CURLY)
|
comma_list(p, struct_field)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn struct_field(p: &mut Parser) -> Result {
|
||||||
|
if !p.current_is(IDENT) {
|
||||||
|
return ERR;
|
||||||
|
}
|
||||||
|
p.start(STRUCT_FIELD);
|
||||||
|
p.bump();
|
||||||
|
ignore_errors(|| {
|
||||||
|
p.expect(COLON)?;
|
||||||
|
p.expect(IDENT)?;
|
||||||
|
OK
|
||||||
|
});
|
||||||
|
p.finish();
|
||||||
|
OK
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paths, types, attributes, and stuff //
|
// Paths, types, attributes, and stuff //
|
||||||
|
@ -78,4 +93,19 @@ fn skip_one_token(p: &mut Parser) {
|
||||||
p.start(ERROR);
|
p.start(ERROR);
|
||||||
p.bump().unwrap();
|
p.bump().unwrap();
|
||||||
p.finish();
|
p.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ignore_errors<F: FnOnce() -> Result>(f: F) {
|
||||||
|
drop(f());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn comma_list<F: Fn(&mut Parser) -> Result>(p: &mut Parser, element: F) {
|
||||||
|
loop {
|
||||||
|
if element(p).is_err() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if p.expect(COMMA).is_err() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
use {Token, TextUnit, SyntaxKind};
|
use {Token, SyntaxKind};
|
||||||
|
|
||||||
use syntax_kinds::*;
|
|
||||||
mod grammar;
|
mod grammar;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use {Token, SyntaxKind, TextUnit};
|
use {Token, SyntaxKind, TextUnit};
|
||||||
use super::{Event};
|
use super::{Event};
|
||||||
use super::super::is_insignificant;
|
use super::super::is_insignificant;
|
||||||
use syntax_kinds::{WHITESPACE, COMMENT};
|
use syntax_kinds::{L_CURLY, R_CURLY, ERROR};
|
||||||
|
|
||||||
pub struct Parser<'t> {
|
pub struct Parser<'t> {
|
||||||
text: &'t str,
|
text: &'t str,
|
||||||
|
@ -10,6 +10,7 @@ pub struct Parser<'t> {
|
||||||
|
|
||||||
pos: usize,
|
pos: usize,
|
||||||
events: Vec<Event>,
|
events: Vec<Event>,
|
||||||
|
curly_level: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> Parser<'t> {
|
impl<'t> Parser<'t> {
|
||||||
|
@ -30,6 +31,7 @@ impl<'t> Parser<'t> {
|
||||||
|
|
||||||
pos: 0,
|
pos: 0,
|
||||||
events: Vec::new(),
|
events: Vec::new(),
|
||||||
|
curly_level: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +66,11 @@ impl<'t> Parser<'t> {
|
||||||
|
|
||||||
pub(crate) fn bump(&mut self) -> Option<SyntaxKind> {
|
pub(crate) fn bump(&mut self) -> Option<SyntaxKind> {
|
||||||
let kind = self.current()?;
|
let kind = self.current()?;
|
||||||
|
match kind {
|
||||||
|
L_CURLY => self.curly_level += 1,
|
||||||
|
R_CURLY => self.curly_level -= 1,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
self.pos += 1;
|
self.pos += 1;
|
||||||
self.event(Event::Token { kind, n_raw_tokens: 1 });
|
self.event(Event::Token { kind, n_raw_tokens: 1 });
|
||||||
Some(kind)
|
Some(kind)
|
||||||
|
@ -78,6 +85,24 @@ impl<'t> Parser<'t> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> Result<(), ()> {
|
||||||
|
let level = self.curly_level;
|
||||||
|
self.expect(L_CURLY)?;
|
||||||
|
f(self);
|
||||||
|
assert!(self.curly_level > level);
|
||||||
|
if self.expect(R_CURLY).is_ok() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
self.start(ERROR);
|
||||||
|
while self.curly_level > level {
|
||||||
|
if self.bump().is_none() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.finish();
|
||||||
|
Ok(()) //???
|
||||||
|
}
|
||||||
|
|
||||||
fn event(&mut self, event: Event) {
|
fn event(&mut self, event: Event) {
|
||||||
self.events.push(event)
|
self.events.push(event)
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,9 @@ pub const DOC_COMMENT: SyntaxKind = SyntaxKind(55);
|
||||||
pub const SHEBANG: SyntaxKind = SyntaxKind(56);
|
pub const SHEBANG: SyntaxKind = SyntaxKind(56);
|
||||||
pub const FILE: SyntaxKind = SyntaxKind(57);
|
pub const FILE: SyntaxKind = SyntaxKind(57);
|
||||||
pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58);
|
pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58);
|
||||||
|
pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59);
|
||||||
|
|
||||||
static INFOS: [SyntaxInfo; 59] = [
|
static INFOS: [SyntaxInfo; 60] = [
|
||||||
SyntaxInfo { name: "USE_KW" },
|
SyntaxInfo { name: "USE_KW" },
|
||||||
SyntaxInfo { name: "FN_KW" },
|
SyntaxInfo { name: "FN_KW" },
|
||||||
SyntaxInfo { name: "STRUCT_KW" },
|
SyntaxInfo { name: "STRUCT_KW" },
|
||||||
|
@ -121,6 +122,7 @@ static INFOS: [SyntaxInfo; 59] = [
|
||||||
SyntaxInfo { name: "SHEBANG" },
|
SyntaxInfo { name: "SHEBANG" },
|
||||||
SyntaxInfo { name: "FILE" },
|
SyntaxInfo { name: "FILE" },
|
||||||
SyntaxInfo { name: "STRUCT_ITEM" },
|
SyntaxInfo { name: "STRUCT_ITEM" },
|
||||||
|
SyntaxInfo { name: "STRUCT_FIELD" },
|
||||||
];
|
];
|
||||||
|
|
||||||
pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {
|
pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {
|
||||||
|
|
3
tests/data/parser/0002_struct_item_field.rs
Normal file
3
tests/data/parser/0002_struct_item_field.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
struct S {
|
||||||
|
foo: u32
|
||||||
|
}
|
15
tests/data/parser/0002_struct_item_field.txt
Normal file
15
tests/data/parser/0002_struct_item_field.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FILE@[0; 25)
|
||||||
|
STRUCT_ITEM@[0; 25)
|
||||||
|
STRUCT_KW@[0; 6)
|
||||||
|
WHITESPACE@[6; 7)
|
||||||
|
IDENT@[7; 8)
|
||||||
|
WHITESPACE@[8; 9)
|
||||||
|
L_CURLY@[9; 10)
|
||||||
|
STRUCT_FIELD@[10; 24)
|
||||||
|
WHITESPACE@[10; 15)
|
||||||
|
IDENT@[15; 18)
|
||||||
|
COLON@[18; 19)
|
||||||
|
WHITESPACE@[19; 20)
|
||||||
|
IDENT@[20; 23)
|
||||||
|
WHITESPACE@[23; 24)
|
||||||
|
R_CURLY@[24; 25)
|
|
@ -61,7 +61,8 @@ fn dump_tree(file: &File) -> String {
|
||||||
|
|
||||||
fn go(node: Node, buff: &mut String, level: usize) {
|
fn go(node: Node, buff: &mut String, level: usize) {
|
||||||
buff.push_str(&String::from(" ").repeat(level));
|
buff.push_str(&String::from(" ").repeat(level));
|
||||||
write!(buff, "{:?}\n", node);
|
write!(buff, "{:?}\n", node)
|
||||||
|
.unwrap();
|
||||||
for child in node.children() {
|
for child in node.children() {
|
||||||
go(child, buff, level + 1)
|
go(child, buff, level + 1)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue