Skip to content

Commit

Permalink
Add Lifetime type and support it in function parameters and generics
Browse files Browse the repository at this point in the history
  • Loading branch information
Bromeon committed Feb 19, 2024
1 parent 77ebda9 commit 1ae5627
Show file tree
Hide file tree
Showing 20 changed files with 257 additions and 55 deletions.
3 changes: 1 addition & 2 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ use crate::parse_type::{
parse_named_fields, parse_tuple_fields,
};
use crate::parse_utils::{consume_outer_attributes, consume_punct, consume_vis_marker};
use crate::types::{Enum, Fields, Item, Struct, Union};
use crate::types_edition::GroupSpan;
use crate::types::{Enum, Fields, GroupSpan, Item, Struct, Union};
use proc_macro2::token_stream::IntoIter;
use proc_macro2::{Delimiter, TokenStream, TokenTree};
use std::iter::Peekable;
Expand Down
5 changes: 4 additions & 1 deletion src/parse_fn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::parse_type::{
consume_field_type, consume_generic_params, consume_item_name, consume_where_clause,
consume_field_type, consume_generic_params, consume_item_name, consume_lifetime,
consume_where_clause,
};
use crate::parse_utils::{
consume_any_ident, consume_comma, consume_ident, consume_outer_attributes, consume_punct,
Expand Down Expand Up @@ -79,13 +80,15 @@ fn parse_fn_params(tokens: TokenStream) -> Punctuated<FnParam> {
let attributes = consume_outer_attributes(&mut tokens);

let tk_ref = consume_punct(&mut tokens, '&');
let lifetime = consume_lifetime(&mut tokens, false);
let tk_mut = consume_ident(&mut tokens, "mut");
let tk_self = consume_ident(&mut tokens, "self");

let param = if let Some(tk_self) = tk_self {
FnParam::Receiver(FnReceiverParam {
attributes,
tk_ref,
lifetime,
tk_mut,
tk_self,
})
Expand Down
7 changes: 4 additions & 3 deletions src/parse_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ use crate::parse_utils::{
consume_ident, consume_inner_attributes, consume_outer_attributes, consume_punct,
consume_stuff_until, consume_vis_marker, parse_any_ident, parse_ident, parse_punct,
};
use crate::types::{Constant, ImplMember, TypeAlias, ValueExpr};
use crate::types_edition::GroupSpan;
use crate::{Attribute, Impl, Item, Trait, TraitMember, TypeExpr, VisMarker};
use crate::types::{
Attribute, Constant, GroupSpan, Impl, ImplMember, Item, Trait, TraitMember, TypeAlias,
TypeExpr, ValueExpr, VisMarker,
};
use proc_macro2::{Delimiter, Group, TokenTree};
use quote::ToTokens;
use std::iter::Peekable;
Expand Down
35 changes: 20 additions & 15 deletions src/parse_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ use crate::parse_utils::{
consume_colon2, consume_comma, consume_ident, consume_outer_attributes, consume_punct,
consume_stuff_until, consume_vis_marker, parse_any_ident, parse_punct,
};
use crate::punctuated::Punctuated;
use crate::types::{
EnumVariant, EnumVariantValue, Fields, GenericArg, GenericArgList, GenericBound, GenericParam,
GenericParamList, NamedField, NamedFields, TupleField, TupleFields, TypeExpr, WhereClause,
WhereClausePredicate,
GenericParamList, GroupSpan, Lifetime, NamedField, NamedFields, Punctuated, TupleField,
TupleFields, TypeExpr, WhereClause, WhereClausePredicate,
};
use crate::types_edition::GroupSpan;
use proc_macro2::{Delimiter, Group, Ident, Punct, TokenStream, TokenTree};
use std::iter::Peekable;
use std::vec::IntoIter;

type TokenIter = Peekable<proc_macro2::token_stream::IntoIter>;

Expand Down Expand Up @@ -99,8 +96,8 @@ fn parse_generic_arg(tokens: Vec<TokenTree>) -> GenericArg {
// Note: method not called if tokens is empty
let mut tokens = tokens.into_iter().peekable();

if let Some((tk_lifetime, ident)) = consume_lifetime(&mut tokens) {
return GenericArg::Lifetime { tk_lifetime, ident };
if let Some(lifetime) = consume_lifetime(&mut tokens, true) {
return GenericArg::Lifetime { lifetime };
}

// Then, try parsing Item = ...
Expand Down Expand Up @@ -129,9 +126,12 @@ fn parse_generic_arg(tokens: Vec<TokenTree>) -> GenericArg {
}
}

fn consume_lifetime(tokens: &mut Peekable<IntoIter<TokenTree>>) -> Option<(Punct, Ident)> {
pub(crate) fn consume_lifetime(
tokens: &mut Peekable<impl Iterator<Item = TokenTree>>,
expect_end: bool,
) -> Option<Lifetime> {
// Try parsing 'lifetime
let tk_lifetime = match tokens.peek() {
let tk_apostrophe = match tokens.peek() {
Some(TokenTree::Punct(punct)) if punct.as_char() == '\'' => {
let apostrophe = punct.clone();
tokens.next(); // consume '
Expand All @@ -142,13 +142,18 @@ fn consume_lifetime(tokens: &mut Peekable<IntoIter<TokenTree>>) -> Option<(Punct

// after the ', there must be a single identifier
match tokens.next() {
Some(TokenTree::Ident(ident)) => {
assert!(
tokens.next().is_none(),
"cannot parse lifetime generic argument"
);
Some(TokenTree::Ident(name)) => {
if expect_end {
assert!(
tokens.next().is_none(),
"cannot parse lifetime generic argument"
);
}

return Some((tk_lifetime, ident));
Some(Lifetime {
tk_apostrophe,
name,
})
}
Some(other) => {
panic!(
Expand Down
3 changes: 1 addition & 2 deletions src/parse_utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::parse_type::consume_generic_args;
use crate::types::{Attribute, AttributeValue, Path, PathSegment, VisMarker};
use crate::types_edition::GroupSpan;
use crate::types::{Attribute, AttributeValue, GroupSpan, Path, PathSegment, VisMarker};
use proc_macro2::{Delimiter, Ident, Punct, Spacing, TokenStream, TokenTree};
use std::iter::Peekable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ Path {
generic_args: GenericArgList {
args: [
Lifetime {
tk_lifetime: Punct {
char: '\'',
spacing: Joint,
lifetime: Lifetime {
tk_apostrophe: Punct {
char: '\'',
spacing: Joint,
},
name: Ident(
a,
),
},
ident: Ident(
a,
),
},
TypeOrConst {
expr: [
Expand Down
76 changes: 76 additions & 0 deletions src/snapshots/venial__tests__parse_fn_mut_receiver_lifetime.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
source: src/tests.rs
expression: func
---
Function(
Function {
attributes: [],
vis_marker: None,
qualifiers: FnQualifiers {
tk_default: None,
tk_const: None,
tk_async: None,
tk_unsafe: None,
tk_extern: None,
extern_abi: None,
},
tk_fn_keyword: Ident(
fn,
),
name: Ident(
prototype,
),
generic_params: Some(
[
GenericParam {
tk_prefix: "'",
name: "a",
bound: None,
},
],
),
tk_params_parens: (),
params: [
Receiver(
FnReceiverParam {
attributes: [],
tk_ref: Some(
Punct {
char: '&',
spacing: Alone,
},
),
lifetime: Some(
Lifetime {
tk_apostrophe: Punct {
char: '\'',
spacing: Joint,
},
name: Ident(
a,
),
},
),
tk_mut: Some(
Ident(
mut,
),
),
tk_self: Ident(
self,
),
},
),
],
where_clause: None,
tk_return_arrow: None,
return_ty: None,
tk_semicolon: Some(
Punct {
char: ';',
spacing: Alone,
},
),
body: None,
},
)
64 changes: 64 additions & 0 deletions src/snapshots/venial__tests__parse_fn_receiver_lifetime.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
source: src/tests.rs
expression: func
---
Function(
Function {
attributes: [],
vis_marker: None,
qualifiers: FnQualifiers {
tk_default: None,
tk_const: None,
tk_async: None,
tk_unsafe: None,
tk_extern: None,
extern_abi: None,
},
tk_fn_keyword: Ident(
fn,
),
name: Ident(
prototype,
),
generic_params: None,
tk_params_parens: (),
params: [
Receiver(
FnReceiverParam {
attributes: [],
tk_ref: Some(
Punct {
char: '&',
spacing: Alone,
},
),
lifetime: Some(
Lifetime {
tk_apostrophe: Punct {
char: '\'',
spacing: Joint,
},
name: Ident(
lifetime,
),
},
),
tk_mut: None,
tk_self: Ident(
self,
),
},
),
],
where_clause: None,
tk_return_arrow: None,
return_ty: None,
tk_semicolon: Some(
Punct {
char: ';',
spacing: Alone,
},
),
body: None,
},
)
1 change: 1 addition & 0 deletions src/snapshots/venial__tests__parse_fn_self_param-2.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Ok(
spacing: Alone,
},
),
lifetime: None,
tk_mut: None,
tk_self: Ident(
self,
Expand Down
1 change: 1 addition & 0 deletions src/snapshots/venial__tests__parse_fn_self_param-3.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Ok(
FnReceiverParam {
attributes: [],
tk_ref: None,
lifetime: None,
tk_mut: Some(
Ident(
mut,
Expand Down
1 change: 1 addition & 0 deletions src/snapshots/venial__tests__parse_fn_self_param-4.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Ok(
spacing: Alone,
},
),
lifetime: None,
tk_mut: Some(
Ident(
mut,
Expand Down
1 change: 1 addition & 0 deletions src/snapshots/venial__tests__parse_fn_self_param.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Ok(
FnReceiverParam {
attributes: [],
tk_ref: None,
lifetime: None,
tk_mut: None,
tk_self: Ident(
self,
Expand Down
14 changes: 8 additions & 6 deletions src/snapshots/venial__tests__parse_generic_args.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ expression: generic_args
GenericArgList {
args: [
Lifetime {
tk_lifetime: Punct {
char: '\'',
spacing: Joint,
lifetime: Lifetime {
tk_apostrophe: Punct {
char: '\'',
spacing: Joint,
},
name: Ident(
a,
),
},
ident: Ident(
a,
),
},
TypeOrConst {
expr: [
Expand Down
1 change: 1 addition & 0 deletions src/snapshots/venial__tests__parse_impl_inherent.snap
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ Impl(
spacing: Alone,
},
),
lifetime: None,
tk_mut: Some(
Ident(
mut,
Expand Down
1 change: 1 addition & 0 deletions src/snapshots/venial__tests__parse_impl_trait.snap
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ Impl(
spacing: Alone,
},
),
lifetime: None,
tk_mut: Some(
Ident(
mut,
Expand Down
14 changes: 8 additions & 6 deletions src/snapshots/venial__tests__parse_inline_generic_args-2.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ expression: owned_args
GenericArgList {
args: [
Lifetime {
tk_lifetime: Punct {
char: '\'',
spacing: Joint,
lifetime: Lifetime {
tk_apostrophe: Punct {
char: '\'',
spacing: Joint,
},
name: Ident(
a,
),
},
ident: Ident(
a,
),
},
TypeOrConst {
expr: [
Expand Down
1 change: 1 addition & 0 deletions src/snapshots/venial__tests__parse_trait_simple.snap
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Trait(
spacing: Alone,
},
),
lifetime: None,
tk_mut: None,
tk_self: Ident(
self,
Expand Down
Loading

0 comments on commit 1ae5627

Please sign in to comment.