@@ -989,6 +989,20 @@ void StreamPrinter::printText(StringRef Text) {
989
989
OS << Text;
990
990
}
991
991
992
+ // / Whether we will be printing a TypeLoc by using the TypeRepr printer
993
+ static bool willUseTypeReprPrinting (TypeLoc tyLoc,
994
+ const PrintOptions &options) {
995
+ // Special case for when transforming archetypes
996
+ if (options.TransformContext && tyLoc.getType () &&
997
+ options.TransformContext ->transform (tyLoc.getType ()))
998
+ return false ;
999
+
1000
+ // Otherwise, whether we have a type repr and prefer that
1001
+ return ((options.PreferTypeRepr && tyLoc.hasLocation ()) ||
1002
+ tyLoc.getType ().isNull ()) &&
1003
+ tyLoc.getTypeRepr ();
1004
+ }
1005
+
992
1006
namespace {
993
1007
// / \brief AST pretty-printer.
994
1008
class PrintAST : public ASTVisitor <PrintAST> {
@@ -1184,8 +1198,11 @@ class PrintAST : public ASTVisitor<PrintAST> {
1184
1198
// is null.
1185
1199
if ((Options.PreferTypeRepr && TL.hasLocation ()) ||
1186
1200
TL.getType ().isNull ()) {
1187
- if (auto repr = TL.getTypeRepr ())
1201
+ if (auto repr = TL.getTypeRepr ()) {
1202
+ llvm::SaveAndRestore<bool > SPTA (Options.SkipParameterTypeAttributes ,
1203
+ true );
1188
1204
repr->print (Printer, Options);
1205
+ }
1189
1206
return ;
1190
1207
}
1191
1208
@@ -1230,10 +1247,10 @@ class PrintAST : public ASTVisitor<PrintAST> {
1230
1247
// / \returns true if anything was printed.
1231
1248
bool printASTNodes (const ArrayRef<ASTNode> &Elements, bool NeedIndent = true );
1232
1249
1233
- void printOneParameter (const ParamDecl *param, bool Curried ,
1234
- bool ArgNameIsAPIByDefault);
1250
+ void printOneParameter (const ParamDecl *param, ParameterTypeFlags paramFlags ,
1251
+ bool Curried, bool ArgNameIsAPIByDefault);
1235
1252
1236
- void printParameterList (ParameterList *PL, bool isCurried,
1253
+ void printParameterList (ParameterList *PL, Type paramListTy, bool isCurried,
1237
1254
std::function<bool ()> isAPINameByDefault);
1238
1255
1239
1256
// / \brief Print the function parameters in curried or selector style,
@@ -2520,6 +2537,14 @@ static bool isStructOrClassContext(DeclContext *dc) {
2520
2537
return false ;
2521
2538
}
2522
2539
2540
+ static void printParameterFlags (ASTPrinter &printer, PrintOptions options,
2541
+ ParameterTypeFlags flags) {
2542
+ if (!options.excludeAttrKind (TAK_autoclosure) && flags.isAutoClosure ())
2543
+ printer << " @autoclosure " ;
2544
+ if (!options.excludeAttrKind (TAK_escaping) && flags.isEscaping ())
2545
+ printer << " @escaping " ;
2546
+ }
2547
+
2523
2548
void PrintAST::visitVarDecl (VarDecl *decl) {
2524
2549
printDocumentationComment (decl);
2525
2550
// Print @sil_stored when the attribute is not already
@@ -2556,7 +2581,8 @@ void PrintAST::visitParamDecl(ParamDecl *decl) {
2556
2581
visitVarDecl (decl);
2557
2582
}
2558
2583
2559
- void PrintAST::printOneParameter (const ParamDecl *param, bool Curried,
2584
+ void PrintAST::printOneParameter (const ParamDecl *param,
2585
+ ParameterTypeFlags paramFlags, bool Curried,
2560
2586
bool ArgNameIsAPIByDefault) {
2561
2587
Printer.callPrintStructurePre (PrintStructureKind::FunctionParameter, param);
2562
2588
SWIFT_DEFER {
@@ -2610,7 +2636,25 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
2610
2636
// Set and restore in-parameter-position printing of types
2611
2637
{
2612
2638
llvm::SaveAndRestore<bool > savePrintParam (Options.PrintAsInParamType , true );
2639
+ // FIXME: don't do if will be using type repr printing
2640
+ printParameterFlags (Printer, Options, paramFlags);
2641
+
2642
+ // Special case, if we're not going to use the type repr printing, peek
2643
+ // through the paren types so that we don't print excessive @escapings
2644
+ unsigned numParens = 0 ;
2645
+ if (!willUseTypeReprPrinting (TheTypeLoc, Options)) {
2646
+ while (auto parenTy =
2647
+ dyn_cast<ParenType>(TheTypeLoc.getType ().getPointer ())) {
2648
+ ++numParens;
2649
+ TheTypeLoc = TypeLoc::withoutLoc (parenTy->getUnderlyingType ());
2650
+ }
2651
+ }
2652
+
2653
+ for (unsigned i = 0 ; i < numParens; ++i)
2654
+ Printer << " (" ;
2613
2655
printTypeLoc (TheTypeLoc);
2656
+ for (unsigned i = 0 ; i < numParens; ++i)
2657
+ Printer << " )" ;
2614
2658
}
2615
2659
2616
2660
if (param->isVariadic ())
@@ -2641,28 +2685,68 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
2641
2685
}
2642
2686
}
2643
2687
2644
- void PrintAST::printParameterList (ParameterList *PL, bool isCurried,
2645
- std::function<bool ()> isAPINameByDefault) {
2688
+ void PrintAST::printParameterList (ParameterList *PL, Type paramListTy,
2689
+ bool isCurried,
2690
+ std::function<bool ()> isAPINameByDefault) {
2691
+ SmallVector<ParameterTypeFlags, 4 > paramFlags;
2692
+ if (paramListTy) {
2693
+ if (auto parenTy = dyn_cast<ParenType>(paramListTy.getPointer ())) {
2694
+ paramFlags.push_back (parenTy->getParameterFlags ());
2695
+ } else if (auto tupleTy = paramListTy->getAs <TupleType>()) {
2696
+ for (auto elt : tupleTy->getElements ())
2697
+ paramFlags.push_back (elt.getParameterFlags ());
2698
+ } else {
2699
+ paramFlags.push_back ({});
2700
+ }
2701
+ } else {
2702
+ // Malformed AST, just use default flags
2703
+ paramFlags.resize (PL->size ());
2704
+ }
2705
+
2646
2706
Printer << " (" ;
2647
2707
for (unsigned i = 0 , e = PL->size (); i != e; ++i) {
2648
2708
if (i > 0 )
2649
2709
Printer << " , " ;
2650
2710
2651
- printOneParameter (PL->get (i), isCurried, isAPINameByDefault ());
2711
+ printOneParameter (PL->get (i), paramFlags[i], isCurried,
2712
+ isAPINameByDefault ());
2652
2713
}
2653
2714
Printer << " )" ;
2654
2715
}
2655
2716
2656
2717
void PrintAST::printFunctionParameters (AbstractFunctionDecl *AFD) {
2657
2718
auto BodyParams = AFD->getParameterLists ();
2719
+ auto curTy = AFD->hasType () ? AFD->getType () : nullptr ;
2658
2720
2659
2721
// Skip over the implicit 'self'.
2660
- if (AFD->getImplicitSelfDecl ())
2722
+ if (AFD->getImplicitSelfDecl ()) {
2661
2723
BodyParams = BodyParams.slice (1 );
2724
+ if (curTy)
2725
+ if (auto funTy = curTy->getAs <AnyFunctionType>())
2726
+ curTy = funTy->getResult ();
2727
+ }
2728
+
2729
+ SmallVector<Type, 4 > parameterListTypes;
2730
+ for (auto i = 0 ; i < BodyParams.size (); ++i) {
2731
+ if (curTy) {
2732
+ if (auto funTy = curTy->getAs <AnyFunctionType>()) {
2733
+ parameterListTypes.push_back (funTy->getInput ());
2734
+ if (i < BodyParams.size () - 1 )
2735
+ curTy = funTy->getResult ();
2736
+ } else {
2737
+ parameterListTypes.push_back (curTy);
2738
+ }
2739
+ }
2740
+ }
2662
2741
2663
2742
for (unsigned CurrPattern = 0 , NumPatterns = BodyParams.size ();
2664
2743
CurrPattern != NumPatterns; ++CurrPattern) {
2665
- printParameterList (BodyParams[CurrPattern], /* Curried=*/ CurrPattern > 0 ,
2744
+ // Be extra careful in the event of printing mal-formed ASTs
2745
+ auto paramListType = parameterListTypes.size () > CurrPattern
2746
+ ? parameterListTypes[CurrPattern]
2747
+ : nullptr ;
2748
+ printParameterList (BodyParams[CurrPattern], paramListType,
2749
+ /* Curried=*/ CurrPattern > 0 ,
2666
2750
[&]()->bool {
2667
2751
return CurrPattern > 0 || AFD->argumentNameIsAPIByDefault ();
2668
2752
});
@@ -2915,7 +2999,8 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
2915
2999
recordDeclLoc (decl, [&]{
2916
3000
Printer << " subscript" ;
2917
3001
}, [&] { // Parameters
2918
- printParameterList (decl->getIndices (), /* Curried=*/ false ,
3002
+ printParameterList (decl->getIndices (), decl->getIndicesType (),
3003
+ /* Curried=*/ false ,
2919
3004
/* isAPINameByDefault*/ []()->bool {return false ;});
2920
3005
});
2921
3006
Printer << " -> " ;
@@ -3642,6 +3727,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
3642
3727
3643
3728
void visitParenType (ParenType *T) {
3644
3729
Printer << " (" ;
3730
+ printParameterFlags (Printer, Options, T->getParameterFlags ());
3645
3731
visit (T->getUnderlyingType ());
3646
3732
Printer << " )" ;
3647
3733
}
@@ -3671,8 +3757,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
3671
3757
if (TD.isVararg ()) {
3672
3758
visit (TD.getVarargBaseTy ());
3673
3759
Printer << " ..." ;
3674
- } else
3760
+ } else {
3761
+ printParameterFlags (Printer, Options, TD.getParameterFlags ());
3675
3762
visit (EltType);
3763
+ }
3676
3764
}
3677
3765
Printer << " )" ;
3678
3766
}
@@ -3804,13 +3892,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
3804
3892
if (Options.SkipAttributes )
3805
3893
return ;
3806
3894
3807
- if (info.isAutoClosure () && !Options.excludeAttrKind (TAK_autoclosure)) {
3808
- Printer.printSimpleAttr (" @autoclosure" ) << " " ;
3809
- }
3810
- if (inParameterPrinting && !info.isNoEscape () &&
3811
- !Options.excludeAttrKind (TAK_escaping)) {
3812
- Printer.printSimpleAttr (" @escaping" ) << " " ;
3813
- }
3814
3895
3815
3896
if (Options.PrintFunctionRepresentationAttrs &&
3816
3897
!Options.excludeAttrKind (TAK_convention) &&
0 commit comments