From db75264579215aeb0a550bc7411d16646d33c15e Mon Sep 17 00:00:00 2001 From: Jan Haller Date: Tue, 2 Aug 2022 19:53:02 +0200 Subject: [PATCH] InlineGenericArgs::to_owned_args() --- ...l__tests__parse_inline_generic_args-2.snap | 32 +++++++++++ ...ial__tests__parse_inline_generic_args.snap | 37 +++++++++++++ src/tests.rs | 17 ++++++ src/types_edition.rs | 54 ++++++++++++++++++- 4 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 src/snapshots/venial__tests__parse_inline_generic_args-2.snap create mode 100644 src/snapshots/venial__tests__parse_inline_generic_args.snap diff --git a/src/snapshots/venial__tests__parse_inline_generic_args-2.snap b/src/snapshots/venial__tests__parse_inline_generic_args-2.snap new file mode 100644 index 0000000..b589711 --- /dev/null +++ b/src/snapshots/venial__tests__parse_inline_generic_args-2.snap @@ -0,0 +1,32 @@ +--- +source: src/tests.rs +expression: owned_args +--- +GenericArgList { + args: [ + Lifetime { + tk_lifetime: Punct { + char: '\'', + spacing: Joint, + }, + ident: Ident( + a, + ), + }, + TyOrConst { + expr: [ + T, + ], + }, + TyOrConst { + expr: [ + U, + ], + }, + TyOrConst { + expr: [ + N, + ], + }, + ], +} diff --git a/src/snapshots/venial__tests__parse_inline_generic_args.snap b/src/snapshots/venial__tests__parse_inline_generic_args.snap new file mode 100644 index 0000000..e54bb86 --- /dev/null +++ b/src/snapshots/venial__tests__parse_inline_generic_args.snap @@ -0,0 +1,37 @@ +--- +source: src/tests.rs +expression: params +--- +[ + GenericParam { + tk_prefix: "'", + name: "a", + bound: Some( + [ + "'", + static, + ], + ), + }, + GenericParam { + name: "T", + bound: None, + }, + GenericParam { + name: "U", + bound: Some( + [ + Clone, + ], + ), + }, + GenericParam { + tk_prefix: "const", + name: "N", + bound: Some( + [ + usize, + ], + ), + }, +] diff --git a/src/tests.rs b/src/tests.rs index 9cf897c..f84a917 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -534,6 +534,23 @@ fn parse_generic_args_turbofish() { assert_debug_snapshot!(parsed); } +#[test] +fn parse_inline_generic_args() { + let generic_params_tokens = quote! { + <'a: 'static, T, U: Clone, const N: usize> + }; + + let mut token_iter = generic_params_tokens.clone().into_iter().peekable(); + let params = crate::parse_type::consume_generic_params(&mut token_iter).unwrap(); + + similar_asserts::assert_str_eq!(quote!(#params), generic_params_tokens); + assert_debug_snapshot!(params); + + let inline_args = params.as_inline_args(); + let owned_args = inline_args.to_owned_args(); + assert_debug_snapshot!(owned_args); +} + // ================== // ENUM VARIANT VALUE // ================== diff --git a/src/types_edition.rs b/src/types_edition.rs index d395495..85cd107 100644 --- a/src/types_edition.rs +++ b/src/types_edition.rs @@ -4,8 +4,8 @@ pub use crate::types::{ GenericBound, GenericParam, GenericParamList, GroupSpan, InlineGenericArgs, NamedField, Struct, StructFields, TupleField, TyExpr, Union, VisMarker, WhereClause, WhereClauseItem, }; -use crate::types::{FnQualifiers, Impl, Path}; -use crate::{Constant, TyDefinition}; +use crate::types::{FnQualifiers, GenericArg, GenericArgList, Impl, Path}; +use crate::{Constant, Punctuated, TyDefinition}; use proc_macro2::{Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; impl Declaration { @@ -578,6 +578,56 @@ impl GenericParam { } } +impl<'a> InlineGenericArgs<'a> { + /// Returns an owned argument list from this. + pub fn to_owned_args(&self) -> GenericArgList { + let GenericParamList { + tk_l_bracket, + params, + tk_r_bracket, + } = self.0; + + GenericArgList { + tk_turbofish_colons: None, // TODO add if GenericParamList supports this, too + tk_l_bracket: tk_l_bracket.clone(), + args: Punctuated { + inner: params + .inner + .iter() + .map(|(param, punctuated_punct)| { + let name = param.name.clone(); + let arg = match ¶m.tk_prefix { + Some(TokenTree::Punct(punct)) if punct.as_char() == '\'' => { + GenericArg::Lifetime { + tk_lifetime: punct.clone(), + ident: name, + } + } + Some(TokenTree::Ident(ident)) if ident == "const" => { + GenericArg::TyOrConst { + expr: TyExpr { + tokens: vec![TokenTree::Ident(name)], + }, + } + } + Some(_) => panic!("unexpected tk_prefix, must be ' or const"), + None => GenericArg::TyOrConst { + expr: TyExpr { + tokens: vec![TokenTree::Ident(name)], + }, + }, + }; + + (arg, punctuated_punct.clone()) + }) + .collect(), + skip_last: params.skip_last, + }, + tk_r_bracket: tk_r_bracket.clone(), + } + } +} + impl WhereClause { /// Create where-clause with a single item. pub fn from_item(item: WhereClauseItem) -> Self {