@@ -992,6 +992,20 @@ void StreamPrinter::printText(StringRef Text) {
992
992
OS << Text;
993
993
}
994
994
995
+ // / Whether we will be printing a TypeLoc by using the TypeRepr printer
996
+ static bool willUseTypeReprPrinting (TypeLoc tyLoc,
997
+ const PrintOptions &options) {
998
+ // Special case for when transforming archetypes
999
+ if (options.TransformContext && tyLoc.getType () &&
1000
+ options.TransformContext ->transform (tyLoc.getType ()))
1001
+ return false ;
1002
+
1003
+ // Otherwise, whether we have a type repr and prefer that
1004
+ return ((options.PreferTypeRepr && tyLoc.hasLocation ()) ||
1005
+ tyLoc.getType ().isNull ()) &&
1006
+ tyLoc.getTypeRepr ();
1007
+ }
1008
+
995
1009
namespace {
996
1010
// / \brief AST pretty-printer.
997
1011
class PrintAST : public ASTVisitor <PrintAST> {
@@ -1187,8 +1201,11 @@ class PrintAST : public ASTVisitor<PrintAST> {
1187
1201
// is null.
1188
1202
if ((Options.PreferTypeRepr && TL.hasLocation ()) ||
1189
1203
TL.getType ().isNull ()) {
1190
- if (auto repr = TL.getTypeRepr ())
1204
+ if (auto repr = TL.getTypeRepr ()) {
1205
+ llvm::SaveAndRestore<bool > SPTA (Options.SkipParameterTypeAttributes ,
1206
+ true );
1191
1207
repr->print (Printer, Options);
1208
+ }
1192
1209
return ;
1193
1210
}
1194
1211
@@ -1232,10 +1249,10 @@ class PrintAST : public ASTVisitor<PrintAST> {
1232
1249
// / \returns true if anything was printed.
1233
1250
bool printASTNodes (const ArrayRef<ASTNode> &Elements, bool NeedIndent = true );
1234
1251
1235
- void printOneParameter (const ParamDecl *param, bool Curried ,
1236
- bool ArgNameIsAPIByDefault);
1252
+ void printOneParameter (const ParamDecl *param, ParameterTypeFlags paramFlags ,
1253
+ bool Curried, bool ArgNameIsAPIByDefault);
1237
1254
1238
- void printParameterList (ParameterList *PL, bool isCurried,
1255
+ void printParameterList (ParameterList *PL, Type paramListTy, bool isCurried,
1239
1256
std::function<bool ()> isAPINameByDefault);
1240
1257
1241
1258
// / \brief Print the function parameters in curried or selector style,
@@ -2500,6 +2517,14 @@ static bool isStructOrClassContext(DeclContext *dc) {
2500
2517
return false ;
2501
2518
}
2502
2519
2520
+ static void printParameterFlags (ASTPrinter &printer, PrintOptions options,
2521
+ ParameterTypeFlags flags) {
2522
+ if (!options.excludeAttrKind (TAK_autoclosure) && flags.isAutoClosure ())
2523
+ printer << " @autoclosure " ;
2524
+ if (!options.excludeAttrKind (TAK_escaping) && flags.isEscaping ())
2525
+ printer << " @escaping " ;
2526
+ }
2527
+
2503
2528
void PrintAST::visitVarDecl (VarDecl *decl) {
2504
2529
printDocumentationComment (decl);
2505
2530
// Print @sil_stored when the attribute is not already
@@ -2536,7 +2561,8 @@ void PrintAST::visitParamDecl(ParamDecl *decl) {
2536
2561
visitVarDecl (decl);
2537
2562
}
2538
2563
2539
- void PrintAST::printOneParameter (const ParamDecl *param, bool Curried,
2564
+ void PrintAST::printOneParameter (const ParamDecl *param,
2565
+ ParameterTypeFlags paramFlags, bool Curried,
2540
2566
bool ArgNameIsAPIByDefault) {
2541
2567
Printer.callPrintStructurePre (PrintStructureKind::FunctionParameter, param);
2542
2568
SWIFT_DEFER {
@@ -2590,7 +2616,25 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
2590
2616
// Set and restore in-parameter-position printing of types
2591
2617
{
2592
2618
llvm::SaveAndRestore<bool > savePrintParam (Options.PrintAsInParamType , true );
2619
+ // FIXME: don't do if will be using type repr printing
2620
+ printParameterFlags (Printer, Options, paramFlags);
2621
+
2622
+ // Special case, if we're not going to use the type repr printing, peek
2623
+ // through the paren types so that we don't print excessive @escapings
2624
+ unsigned numParens = 0 ;
2625
+ if (!willUseTypeReprPrinting (TheTypeLoc, Options)) {
2626
+ while (auto parenTy =
2627
+ dyn_cast<ParenType>(TheTypeLoc.getType ().getPointer ())) {
2628
+ ++numParens;
2629
+ TheTypeLoc = TypeLoc::withoutLoc (parenTy->getUnderlyingType ());
2630
+ }
2631
+ }
2632
+
2633
+ for (unsigned i = 0 ; i < numParens; ++i)
2634
+ Printer << " (" ;
2593
2635
printTypeLoc (TheTypeLoc);
2636
+ for (unsigned i = 0 ; i < numParens; ++i)
2637
+ Printer << " )" ;
2594
2638
}
2595
2639
2596
2640
if (param->isVariadic ())
@@ -2621,28 +2665,68 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
2621
2665
}
2622
2666
}
2623
2667
2624
- void PrintAST::printParameterList (ParameterList *PL, bool isCurried,
2625
- std::function<bool ()> isAPINameByDefault) {
2668
+ void PrintAST::printParameterList (ParameterList *PL, Type paramListTy,
2669
+ bool isCurried,
2670
+ std::function<bool ()> isAPINameByDefault) {
2671
+ SmallVector<ParameterTypeFlags, 4 > paramFlags;
2672
+ if (paramListTy) {
2673
+ if (auto parenTy = dyn_cast<ParenType>(paramListTy.getPointer ())) {
2674
+ paramFlags.push_back (parenTy->getParameterFlags ());
2675
+ } else if (auto tupleTy = paramListTy->getAs <TupleType>()) {
2676
+ for (auto elt : tupleTy->getElements ())
2677
+ paramFlags.push_back (elt.getParameterFlags ());
2678
+ } else {
2679
+ paramFlags.push_back ({});
2680
+ }
2681
+ } else {
2682
+ // Malformed AST, just use default flags
2683
+ paramFlags.resize (PL->size ());
2684
+ }
2685
+
2626
2686
Printer << " (" ;
2627
2687
for (unsigned i = 0 , e = PL->size (); i != e; ++i) {
2628
2688
if (i > 0 )
2629
2689
Printer << " , " ;
2630
2690
2631
- printOneParameter (PL->get (i), isCurried, isAPINameByDefault ());
2691
+ printOneParameter (PL->get (i), paramFlags[i], isCurried,
2692
+ isAPINameByDefault ());
2632
2693
}
2633
2694
Printer << " )" ;
2634
2695
}
2635
2696
2636
2697
void PrintAST::printFunctionParameters (AbstractFunctionDecl *AFD) {
2637
2698
auto BodyParams = AFD->getParameterLists ();
2699
+ auto curTy = AFD->hasType () ? AFD->getType () : nullptr ;
2638
2700
2639
2701
// Skip over the implicit 'self'.
2640
- if (AFD->getImplicitSelfDecl ())
2702
+ if (AFD->getImplicitSelfDecl ()) {
2641
2703
BodyParams = BodyParams.slice (1 );
2704
+ if (curTy)
2705
+ if (auto funTy = curTy->getAs <AnyFunctionType>())
2706
+ curTy = funTy->getResult ();
2707
+ }
2708
+
2709
+ SmallVector<Type, 4 > parameterListTypes;
2710
+ for (auto i = 0 ; i < BodyParams.size (); ++i) {
2711
+ if (curTy) {
2712
+ if (auto funTy = curTy->getAs <AnyFunctionType>()) {
2713
+ parameterListTypes.push_back (funTy->getInput ());
2714
+ if (i < BodyParams.size () - 1 )
2715
+ curTy = funTy->getResult ();
2716
+ } else {
2717
+ parameterListTypes.push_back (curTy);
2718
+ }
2719
+ }
2720
+ }
2642
2721
2643
2722
for (unsigned CurrPattern = 0 , NumPatterns = BodyParams.size ();
2644
2723
CurrPattern != NumPatterns; ++CurrPattern) {
2645
- printParameterList (BodyParams[CurrPattern], /* Curried=*/ CurrPattern > 0 ,
2724
+ // Be extra careful in the event of printing mal-formed ASTs
2725
+ auto paramListType = parameterListTypes.size () > CurrPattern
2726
+ ? parameterListTypes[CurrPattern]
2727
+ : nullptr ;
2728
+ printParameterList (BodyParams[CurrPattern], paramListType,
2729
+ /* Curried=*/ CurrPattern > 0 ,
2646
2730
[&]()->bool {
2647
2731
return CurrPattern > 0 || AFD->argumentNameIsAPIByDefault ();
2648
2732
});
@@ -2889,7 +2973,8 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
2889
2973
recordDeclLoc (decl, [&]{
2890
2974
Printer << " subscript" ;
2891
2975
}, [&] { // Parameters
2892
- printParameterList (decl->getIndices (), /* Curried=*/ false ,
2976
+ printParameterList (decl->getIndices (), decl->getIndicesType (),
2977
+ /* Curried=*/ false ,
2893
2978
/* isAPINameByDefault*/ []()->bool {return false ;});
2894
2979
});
2895
2980
Printer << " -> " ;
@@ -3609,6 +3694,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
3609
3694
3610
3695
void visitParenType (ParenType *T) {
3611
3696
Printer << " (" ;
3697
+ printParameterFlags (Printer, Options, T->getParameterFlags ());
3612
3698
visit (T->getUnderlyingType ());
3613
3699
Printer << " )" ;
3614
3700
}
@@ -3638,8 +3724,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
3638
3724
if (TD.isVararg ()) {
3639
3725
visit (TD.getVarargBaseTy ());
3640
3726
Printer << " ..." ;
3641
- } else
3727
+ } else {
3728
+ printParameterFlags (Printer, Options, TD.getParameterFlags ());
3642
3729
visit (EltType);
3730
+ }
3643
3731
}
3644
3732
Printer << " )" ;
3645
3733
}
@@ -3765,15 +3853,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
3765
3853
if (Options.SkipAttributes )
3766
3854
return ;
3767
3855
3768
- if (info.isAutoClosure () && !Options.excludeAttrKind (TAK_autoclosure)) {
3769
- Printer.printSimpleAttr (" @autoclosure" );
3770
- Printer << " " ;
3771
- }
3772
- if (inParameterPrinting && !info.isNoEscape () &&
3773
- !Options.excludeAttrKind (TAK_escaping)) {
3774
- Printer.printSimpleAttr (" @escaping" );
3775
- Printer << " " ;
3776
- }
3777
3856
3778
3857
if (Options.PrintFunctionRepresentationAttrs &&
3779
3858
!Options.excludeAttrKind (TAK_convention)) {
0 commit comments