1010//! `parse(format!())` we use internally is an implementation detail -- long
1111//! term, it will be replaced with direct tree manipulation.
1212use itertools:: Itertools ;
13- use stdx:: format_to;
13+ use stdx:: { format_to, never } ;
1414
1515use crate :: { ast, AstNode , SourceFile , SyntaxKind , SyntaxNode , SyntaxToken } ;
1616
@@ -22,6 +22,16 @@ pub fn name_ref(text: &str) -> ast::NameRef {
2222 ast_from_text ( & format ! ( "fn f() {{ {}{}; }}" , raw_ident_esc( text) , text) )
2323}
2424
25+ pub fn lifetime ( text : & str ) -> ast:: Lifetime {
26+ let mut text = text;
27+ let tmp;
28+ if never ! ( !text. starts_with( '\'' ) ) {
29+ tmp = format ! ( "'{}" , text) ;
30+ text = & tmp;
31+ }
32+ ast_from_text ( & format ! ( "fn f<{}>() {{ }}" , text) )
33+ }
34+
2535fn raw_ident_esc ( ident : & str ) -> & ' static str {
2636 let is_keyword = parser:: SyntaxKind :: from_keyword ( ident) . is_some ( ) ;
2737 if is_keyword && !matches ! ( ident, "self" | "crate" | "super" | "Self" ) {
@@ -34,10 +44,13 @@ fn raw_ident_esc(ident: &str) -> &'static str {
3444// FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
3545// `expr_xxx`.
3646pub fn ty ( text : & str ) -> ast:: Type {
37- ast_from_text ( & format ! ( "fn f() -> {} {{}}" , text) )
47+ ty_from_text ( text)
3848}
3949pub fn ty_unit ( ) -> ast:: Type {
40- ty ( "()" )
50+ ty_from_text ( "()" )
51+ }
52+ pub fn ty_bool ( ) -> ast:: Type {
53+ ty_path ( path_unqualified ( path_segment ( name_ref ( "bool" ) ) ) )
4154}
4255pub fn ty_tuple ( types : impl IntoIterator < Item = ast:: Type > ) -> ast:: Type {
4356 let mut count: usize = 0 ;
@@ -46,15 +59,21 @@ pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
4659 contents. push ( ',' ) ;
4760 }
4861
49- ty ( & format ! ( "({})" , contents) )
62+ ty_from_text ( & format ! ( "({})" , contents) )
5063}
5164// FIXME: handle path to type
5265pub fn ty_generic ( name : ast:: NameRef , types : impl IntoIterator < Item = ast:: Type > ) -> ast:: Type {
5366 let contents = types. into_iter ( ) . join ( ", " ) ;
54- ty ( & format ! ( "{}<{}>" , name, contents) )
67+ ty_from_text ( & format ! ( "{}<{}>" , name, contents) )
5568}
5669pub fn ty_ref ( target : ast:: Type , exclusive : bool ) -> ast:: Type {
57- ty ( & if exclusive { format ! ( "&mut {}" , target) } else { format ! ( "&{}" , target) } )
70+ ty_from_text ( & if exclusive { format ! ( "&mut {}" , target) } else { format ! ( "&{}" , target) } )
71+ }
72+ pub fn ty_path ( path : ast:: Path ) -> ast:: Type {
73+ ty_from_text ( & path. to_string ( ) )
74+ }
75+ fn ty_from_text ( text : & str ) -> ast:: Type {
76+ ast_from_text ( & format ! ( "type _T = {};" , text) )
5877}
5978
6079pub fn assoc_item_list ( ) -> ast:: AssocItemList {
@@ -475,15 +494,19 @@ pub fn param_list(
475494 } ;
476495 ast_from_text ( & list)
477496}
478- // FIXME: s/&str/ast:Name
479- pub fn generic_param ( name : & str , ty : Option < ast:: TypeBoundList > ) -> ast:: GenericParam {
497+
498+ pub fn type_param ( name : ast :: Name , ty : Option < ast:: TypeBoundList > ) -> ast:: TypeParam {
480499 let bound = match ty {
481500 Some ( it) => format ! ( ": {}" , it) ,
482501 None => String :: new ( ) ,
483502 } ;
484503 ast_from_text ( & format ! ( "fn f<{}{}>() {{ }}" , name, bound) )
485504}
486505
506+ pub fn lifetime_param ( lifetime : ast:: Lifetime ) -> ast:: LifetimeParam {
507+ ast_from_text ( & format ! ( "fn f<{}>() {{ }}" , lifetime) )
508+ }
509+
487510pub fn generic_param_list (
488511 pats : impl IntoIterator < Item = ast:: GenericParam > ,
489512) -> ast:: GenericParamList {
0 commit comments