This commit is contained in:
Aleksey Kladov 2018-08-22 17:01:51 +03:00
parent 8e3bec11eb
commit 69a524fbef
3 changed files with 28 additions and 45 deletions

View file

@ -40,10 +40,7 @@ impl<'a> AstNode<'a> for Attr<'a> {
impl<'a> Attr<'a> {
pub fn value(self) -> Option<TokenTree<'a>> {
self.syntax()
.children()
.filter_map(TokenTree::cast)
.next()
super::child_opt(self)
}
}
@ -125,15 +122,11 @@ impl<'a> AstNode<'a> for File<'a> {
impl<'a> File<'a> {
pub fn functions(self) -> impl Iterator<Item = FnDef<'a>> + 'a {
self.syntax()
.children()
.filter_map(FnDef::cast)
super::children(self)
}
pub fn modules(self) -> impl Iterator<Item = Module<'a>> + 'a {
self.syntax()
.children()
.filter_map(Module::cast)
super::children(self)
}
}
@ -250,9 +243,7 @@ impl<'a> ast::NameOwner<'a> for Module<'a> {}
impl<'a> ast::AttrsOwner<'a> for Module<'a> {}
impl<'a> Module<'a> {
pub fn modules(self) -> impl Iterator<Item = Module<'a>> + 'a {
self.syntax()
.children()
.filter_map(Module::cast)
super::children(self)
}
}
@ -507,9 +498,7 @@ impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {}
impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {}
impl<'a> StructDef<'a> {
pub fn fields(self) -> impl Iterator<Item = NamedField<'a>> + 'a {
self.syntax()
.children()
.filter_map(NamedField::cast)
super::children(self)
}
}

View file

@ -58,9 +58,7 @@ impl<'a> {{ node }}<'a> {
{%- set method_name = m.0 -%}
{%- set ChildName = m.1 %}
pub fn {{ method_name }}(self) -> impl Iterator<Item = {{ ChildName }}<'a>> + 'a {
self.syntax()
.children()
.filter_map({{ ChildName }}::cast)
super::children(self)
}
{% endfor -%}
{%- endif -%}
@ -70,10 +68,7 @@ impl<'a> {{ node }}<'a> {
{%- set method_name = m.0 -%}
{%- set ChildName = m.1 %}
pub fn {{ method_name }}(self) -> Option<{{ ChildName }}<'a>> {
self.syntax()
.children()
.filter_map({{ ChildName }}::cast)
.next()
super::child_opt(self)
}
{% endfor -%}
{%- endif -%}

View file

@ -9,7 +9,7 @@ use {
};
pub use self::generated::*;
pub trait AstNode<'a>: Clone + Copy {
pub trait AstNode<'a>: Clone + Copy + 'a {
fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self>
where Self: Sized;
fn syntax(self) -> SyntaxNodeRef<'a>;
@ -17,34 +17,23 @@ pub trait AstNode<'a>: Clone + Copy {
pub trait NameOwner<'a>: AstNode<'a> {
fn name(self) -> Option<Name<'a>> {
self.syntax()
.children()
.filter_map(Name::cast)
.next()
child_opt(self)
}
}
pub trait TypeParamsOwner<'a>: AstNode<'a> {
fn type_param_list(self) -> Option<TypeParamList<'a>> {
self.syntax()
.children()
.filter_map(TypeParamList::cast)
.next()
child_opt(self)
}
fn where_clause(self) -> Option<WhereClause<'a>> {
self.syntax()
.children()
.filter_map(WhereClause::cast)
.next()
child_opt(self)
}
}
pub trait AttrsOwner<'a>: AstNode<'a> {
fn attrs(&self) -> Box<Iterator<Item=Attr<'a>> + 'a> {
let it = self.syntax().children()
.filter_map(Attr::cast);
Box::new(it)
fn attrs(self) -> Box<Iterator<Item=Attr<'a>> + 'a> {
Box::new(children(self))
}
}
@ -118,22 +107,22 @@ impl<'a> NameRef<'a> {
}
impl<'a> ImplItem<'a> {
pub fn target_type(&self) -> Option<TypeRef<'a>> {
pub fn target_type(self) -> Option<TypeRef<'a>> {
match self.target() {
(Some(t), None) | (_, Some(t)) => Some(t),
_ => None,
}
}
pub fn target_trait(&self) -> Option<TypeRef<'a>> {
pub fn target_trait(self) -> Option<TypeRef<'a>> {
match self.target() {
(Some(t), Some(_)) => Some(t),
_ => None,
}
}
fn target(&self) -> (Option<TypeRef<'a>>, Option<TypeRef<'a>>) {
let mut types = self.syntax().children().filter_map(TypeRef::cast);
fn target(self) -> (Option<TypeRef<'a>>, Option<TypeRef<'a>>) {
let mut types = children(self);
let first = types.next();
let second = types.next();
(first, second)
@ -141,10 +130,20 @@ impl<'a> ImplItem<'a> {
}
impl<'a> Module<'a> {
pub fn has_semi(&self) -> bool {
pub fn has_semi(self) -> bool {
match self.syntax().last_child() {
None => false,
Some(node) => node.kind() == SEMI,
}
}
}
fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> {
children(parent).next()
}
fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> impl Iterator<Item=C> + 'a {
parent.syntax()
.children()
.filter_map(C::cast)
}