This commit is contained in:
Aleksey Kladov 2018-08-11 11:03:22 +03:00
parent 78f41ea707
commit d5119133fc
5 changed files with 124 additions and 13 deletions

View file

@ -4,6 +4,30 @@ use {
SyntaxKind::*, SyntaxKind::*,
}; };
#[derive(Debug, Clone, Copy)]
pub struct ConstItem<R: TreeRoot = Arc<SyntaxRoot>> {
syntax: SyntaxNode<R>,
}
impl<R: TreeRoot> AstNode<R> for ConstItem<R> {
fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
match syntax.kind() {
CONST_ITEM => Some(ConstItem { syntax }),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
}
impl<R: TreeRoot> ConstItem<R> {
pub fn name(&self) -> Option<Name<R>> {
self.syntax()
.children()
.filter_map(Name::cast)
.next()
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Enum<R: TreeRoot = Arc<SyntaxRoot>> { pub struct Enum<R: TreeRoot = Arc<SyntaxRoot>> {
syntax: SyntaxNode<R>, syntax: SyntaxNode<R>,
@ -75,6 +99,30 @@ impl<R: TreeRoot> Function<R> {
} }
} }
#[derive(Debug, Clone, Copy)]
pub struct Module<R: TreeRoot = Arc<SyntaxRoot>> {
syntax: SyntaxNode<R>,
}
impl<R: TreeRoot> AstNode<R> for Module<R> {
fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
match syntax.kind() {
MODULE => Some(Module { syntax }),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
}
impl<R: TreeRoot> Module<R> {
pub fn name(&self) -> Option<Name<R>> {
self.syntax()
.children()
.filter_map(Name::cast)
.next()
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Name<R: TreeRoot = Arc<SyntaxRoot>> { pub struct Name<R: TreeRoot = Arc<SyntaxRoot>> {
syntax: SyntaxNode<R>, syntax: SyntaxNode<R>,
@ -92,6 +140,30 @@ impl<R: TreeRoot> AstNode<R> for Name<R> {
impl<R: TreeRoot> Name<R> {} impl<R: TreeRoot> Name<R> {}
#[derive(Debug, Clone, Copy)]
pub struct StaticItem<R: TreeRoot = Arc<SyntaxRoot>> {
syntax: SyntaxNode<R>,
}
impl<R: TreeRoot> AstNode<R> for StaticItem<R> {
fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
match syntax.kind() {
STATIC_ITEM => Some(StaticItem { syntax }),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
}
impl<R: TreeRoot> StaticItem<R> {
pub fn name(&self) -> Option<Name<R>> {
self.syntax()
.children()
.filter_map(Name::cast)
.next()
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Struct<R: TreeRoot = Arc<SyntaxRoot>> { pub struct Struct<R: TreeRoot = Arc<SyntaxRoot>> {
syntax: SyntaxNode<R>, syntax: SyntaxNode<R>,
@ -116,3 +188,27 @@ impl<R: TreeRoot> Struct<R> {
} }
} }
#[derive(Debug, Clone, Copy)]
pub struct Trait<R: TreeRoot = Arc<SyntaxRoot>> {
syntax: SyntaxNode<R>,
}
impl<R: TreeRoot> AstNode<R> for Trait<R> {
fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
match syntax.kind() {
TRAIT => Some(Trait { syntax }),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
}
impl<R: TreeRoot> Trait<R> {
pub fn name(&self) -> Option<Name<R>> {
self.syntax()
.children()
.filter_map(Name::cast)
.next()
}
}

View file

@ -12,7 +12,7 @@ pub struct {{ node }}<R: TreeRoot = Arc<SyntaxRoot>> {
impl<R: TreeRoot> AstNode<R> for {{ node }}<R> { impl<R: TreeRoot> AstNode<R> for {{ node }}<R> {
fn cast(syntax: SyntaxNode<R>) -> Option<Self> { fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
match syntax.kind() { match syntax.kind() {
{{ node | upper }} => Some({{ node }} { syntax }), {{ node | SCREAM }} => Some({{ node }} { syntax }),
_ => None, _ => None,
} }
} }

View file

@ -234,6 +234,26 @@ Grammar(
["name", "Name"] ["name", "Name"]
] ]
), ),
"Trait": (
options: [
["name", "Name"]
]
),
"Module": (
options: [
["name", "Name"]
]
),
"ConstItem": (
options: [
["name", "Name"]
]
),
"StaticItem": (
options: [
["name", "Name"]
]
),
"Name": (), "Name": (),
}, },
) )

View file

@ -12,3 +12,4 @@ tera = "0.11"
clap = "2.32.0" clap = "2.32.0"
failure = "0.1.1" failure = "0.1.1"
commandspec = "0.10" commandspec = "0.10"
heck = "0.3.0"

View file

@ -7,8 +7,10 @@ extern crate tools;
extern crate walkdir; extern crate walkdir;
#[macro_use] #[macro_use]
extern crate commandspec; extern crate commandspec;
extern crate heck;
use clap::{App, Arg, SubCommand}; use clap::{App, Arg, SubCommand};
use heck::{CamelCase, ShoutySnakeCase};
use std::{ use std::{
collections::HashMap, collections::HashMap,
fs, fs,
@ -87,18 +89,10 @@ fn render_template(template: &str) -> Result<String> {
.map_err(|e| format_err!("template error: {:?}", e))?; .map_err(|e| format_err!("template error: {:?}", e))?;
tera.register_global_function("concat", Box::new(concat)); tera.register_global_function("concat", Box::new(concat));
tera.register_filter("camel", |arg, _| { tera.register_filter("camel", |arg, _| {
Ok(arg.as_str().unwrap() Ok(arg.as_str().unwrap().to_camel_case().into())
.split("_") });
.flat_map(|word| { tera.register_filter("SCREAM", |arg, _| {
word.chars() Ok(arg.as_str().unwrap().to_shouty_snake_case().into())
.next().unwrap()
.to_uppercase()
.chain(
word.chars().skip(1).flat_map(|c| c.to_lowercase())
)
})
.collect::<String>()
.into())
}); });
let ret = tera let ret = tera
.render("grammar", &grammar) .render("grammar", &grammar)