@@ -992,6 +992,20 @@ void StreamPrinter::printText(StringRef Text) {
992992 OS << Text;
993993}
994994
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+
9951009namespace {
9961010// / \brief AST pretty-printer.
9971011class PrintAST : public ASTVisitor <PrintAST> {
@@ -1187,8 +1201,11 @@ class PrintAST : public ASTVisitor<PrintAST> {
11871201 // is null.
11881202 if ((Options.PreferTypeRepr && TL.hasLocation ()) ||
11891203 TL.getType ().isNull ()) {
1190- if (auto repr = TL.getTypeRepr ())
1204+ if (auto repr = TL.getTypeRepr ()) {
1205+ llvm::SaveAndRestore<bool > SPTA (Options.SkipParameterTypeAttributes ,
1206+ true );
11911207 repr->print (Printer, Options);
1208+ }
11921209 return ;
11931210 }
11941211
@@ -1232,10 +1249,10 @@ class PrintAST : public ASTVisitor<PrintAST> {
12321249 // / \returns true if anything was printed.
12331250 bool printASTNodes (const ArrayRef<ASTNode> &Elements, bool NeedIndent = true );
12341251
1235- void printOneParameter (const ParamDecl *param, bool Curried ,
1236- bool ArgNameIsAPIByDefault);
1252+ void printOneParameter (const ParamDecl *param, ParameterTypeFlags paramFlags ,
1253+ bool Curried, bool ArgNameIsAPIByDefault);
12371254
1238- void printParameterList (ParameterList *PL, bool isCurried,
1255+ void printParameterList (ParameterList *PL, Type paramListTy, bool isCurried,
12391256 std::function<bool ()> isAPINameByDefault);
12401257
12411258 // / \brief Print the function parameters in curried or selector style,
@@ -2500,6 +2517,14 @@ static bool isStructOrClassContext(DeclContext *dc) {
25002517 return false ;
25012518}
25022519
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+
25032528void PrintAST::visitVarDecl (VarDecl *decl) {
25042529 printDocumentationComment (decl);
25052530 // Print @sil_stored when the attribute is not already
@@ -2536,7 +2561,8 @@ void PrintAST::visitParamDecl(ParamDecl *decl) {
25362561 visitVarDecl (decl);
25372562}
25382563
2539- void PrintAST::printOneParameter (const ParamDecl *param, bool Curried,
2564+ void PrintAST::printOneParameter (const ParamDecl *param,
2565+ ParameterTypeFlags paramFlags, bool Curried,
25402566 bool ArgNameIsAPIByDefault) {
25412567 Printer.callPrintStructurePre (PrintStructureKind::FunctionParameter, param);
25422568 SWIFT_DEFER {
@@ -2590,7 +2616,25 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
25902616 // Set and restore in-parameter-position printing of types
25912617 {
25922618 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 << " (" ;
25932635 printTypeLoc (TheTypeLoc);
2636+ for (unsigned i = 0 ; i < numParens; ++i)
2637+ Printer << " )" ;
25942638 }
25952639
25962640 if (param->isVariadic ())
@@ -2621,28 +2665,68 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
26212665 }
26222666}
26232667
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+
26262686 Printer << " (" ;
26272687 for (unsigned i = 0 , e = PL->size (); i != e; ++i) {
26282688 if (i > 0 )
26292689 Printer << " , " ;
26302690
2631- printOneParameter (PL->get (i), isCurried, isAPINameByDefault ());
2691+ printOneParameter (PL->get (i), paramFlags[i], isCurried,
2692+ isAPINameByDefault ());
26322693 }
26332694 Printer << " )" ;
26342695}
26352696
26362697void PrintAST::printFunctionParameters (AbstractFunctionDecl *AFD) {
26372698 auto BodyParams = AFD->getParameterLists ();
2699+ auto curTy = AFD->hasType () ? AFD->getType () : nullptr ;
26382700
26392701 // Skip over the implicit 'self'.
2640- if (AFD->getImplicitSelfDecl ())
2702+ if (AFD->getImplicitSelfDecl ()) {
26412703 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+ }
26422721
26432722 for (unsigned CurrPattern = 0 , NumPatterns = BodyParams.size ();
26442723 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 ,
26462730 [&]()->bool {
26472731 return CurrPattern > 0 || AFD->argumentNameIsAPIByDefault ();
26482732 });
@@ -2889,7 +2973,8 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
28892973 recordDeclLoc (decl, [&]{
28902974 Printer << " subscript" ;
28912975 }, [&] { // Parameters
2892- printParameterList (decl->getIndices (), /* Curried=*/ false ,
2976+ printParameterList (decl->getIndices (), decl->getIndicesType (),
2977+ /* Curried=*/ false ,
28932978 /* isAPINameByDefault*/ []()->bool {return false ;});
28942979 });
28952980 Printer << " -> " ;
@@ -3609,6 +3694,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
36093694
36103695 void visitParenType (ParenType *T) {
36113696 Printer << " (" ;
3697+ printParameterFlags (Printer, Options, T->getParameterFlags ());
36123698 visit (T->getUnderlyingType ());
36133699 Printer << " )" ;
36143700 }
@@ -3638,8 +3724,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
36383724 if (TD.isVararg ()) {
36393725 visit (TD.getVarargBaseTy ());
36403726 Printer << " ..." ;
3641- } else
3727+ } else {
3728+ printParameterFlags (Printer, Options, TD.getParameterFlags ());
36423729 visit (EltType);
3730+ }
36433731 }
36443732 Printer << " )" ;
36453733 }
@@ -3765,15 +3853,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37653853 if (Options.SkipAttributes )
37663854 return ;
37673855
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- }
37773856
37783857 if (Options.PrintFunctionRepresentationAttrs &&
37793858 !Options.excludeAttrKind (TAK_convention)) {
0 commit comments