From f45c338e38c363ffa3fb1262f8c46ec52ccd13d9 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Sat, 22 Feb 2020 18:09:43 +0300 Subject: [PATCH] =?UTF-8?q?[ASTPrinter]=20Fix=20duplicate=20=C2=ABmutating?= =?UTF-8?q?=C2=BB=20modifiers=20when=20printing=20file=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/AST/ASTPrinter.cpp | 55 ++++++++++--------- test/IDE/print_source_file_interface_2.swift | 5 ++ ...print_source_file_interface_2.swift.result | 6 ++ 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 45cc7d59752a5..6fbad80717ada 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -812,7 +812,7 @@ class PrintAST : public ASTVisitor { bool shouldPrintPattern(const Pattern *P); void printPatternType(const Pattern *P); void printAccessors(const AbstractStorageDecl *ASD); - void printMutatingModifiersIfNeeded(const AccessorDecl *accessor); + void printMutabilityModifiersIfNeeded(const FuncDecl *FD); void printMembersOfDecl(Decl * NTD, bool needComma = false, bool openBracket = true, bool closeBracket = true); void printMembers(ArrayRef members, bool needComma = false, @@ -990,9 +990,6 @@ void PrintAST::printAttributes(const Decl *D) { #define CONTEXTUAL_SIMPLE_DECL_ATTR(X, Class, Y, Z) EXCLUDE_ATTR(Class) #define CONTEXTUAL_DECL_ATTR_ALIAS(X, Class) EXCLUDE_ATTR(Class) #include "swift/AST/Attr.def" - } else if (isa(D)) { - Options.ExcludeAttrList.push_back(DAK_Mutating); - Options.ExcludeAttrList.push_back(DAK_NonMutating); } // If the declaration is implicitly @objc, print the attribute now. @@ -1008,19 +1005,23 @@ void PrintAST::printAttributes(const Decl *D) { // clients, or if it inherits superclass convenience initializers, // then print those attributes specially. if (auto CD = dyn_cast(D)) { - if (Options.PrintImplicitAttrs) { - if (CD->inheritsSuperclassInitializers()) { - Printer.printAttrName("@_inheritsConvenienceInitializers"); - Printer << " "; - } - if (CD->hasMissingDesignatedInitializers()) { - Printer.printAttrName("@_hasMissingDesignatedInitializers"); - Printer << " "; - } + if (CD->inheritsSuperclassInitializers()) { + Printer.printAttrName("@_inheritsConvenienceInitializers"); + Printer << " "; + } + if (CD->hasMissingDesignatedInitializers()) { + Printer.printAttrName("@_hasMissingDesignatedInitializers"); + Printer << " "; } } } + // We will handle 'mutating' and 'nonmutating' separately. + if (isa(D)) { + Options.ExcludeAttrList.push_back(DAK_Mutating); + Options.ExcludeAttrList.push_back(DAK_NonMutating); + } + D->getAttrs().print(Printer, Options, D); // Print the implicit 'final' attribute. @@ -1758,12 +1759,15 @@ void PrintAST::printBodyIfNecessary(const AbstractFunctionDecl *decl) { printBraceStmt(decl->getBody(), /*newlineIfEmpty*/!isa(decl)); } -void PrintAST::printMutatingModifiersIfNeeded(const AccessorDecl *accessor) { - if (accessor->isAssumedNonMutating() && accessor->isMutating() && - !Options.excludeAttrKind(DAK_Mutating)) { - Printer.printKeyword("mutating", Options, " "); - } else if (accessor->isExplicitNonMutating() && - !Options.excludeAttrKind(DAK_NonMutating)) { +void PrintAST::printMutabilityModifiersIfNeeded(const FuncDecl *FD) { + const auto *AD = dyn_cast(FD); + + if (FD->isMutating()) { + if (AD == nullptr || AD->isAssumedNonMutating()) + if (!Options.excludeAttrKind(DAK_Mutating)) + Printer.printKeyword("mutating", Options, " "); + } else if (AD && AD->isExplicitNonMutating() && + !Options.excludeAttrKind(DAK_Mutating)) { Printer.printKeyword("nonmutating", Options, " "); } } @@ -1881,7 +1885,7 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) { return true; if (!PrintAccessorBody) { Printer << " "; - printMutatingModifiersIfNeeded(Accessor); + printMutabilityModifiersIfNeeded(Accessor); Printer.printKeyword(getAccessorLabel(Accessor->getAccessorKind()), Options); } else { { @@ -2777,10 +2781,9 @@ bool PrintAST::printASTNodes(const ArrayRef &Elements, void PrintAST::visitAccessorDecl(AccessorDecl *decl) { printDocumentationComment(decl); printAttributes(decl); + // Explicitly print 'mutating' and 'nonmutating' if needed. + printMutabilityModifiersIfNeeded(decl); - // Explicitly print 'mutating' and 'nonmutating' before getters and setters - // for which that is true. - printMutatingModifiersIfNeeded(decl); switch (auto kind = decl->getAccessorKind()) { case AccessorKind::Get: case AccessorKind::Address: @@ -2837,9 +2840,9 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) { if (!Options.SkipIntroducerKeywords) { if (decl->isStatic() && Options.PrintStaticKeyword) printStaticKeyword(decl->getCorrectStaticSpelling()); - if (decl->isMutating() && !Options.excludeAttrKind(DAK_Mutating)) { - Printer.printKeyword("mutating", Options, " "); - } else if (decl->isConsuming() && !decl->getAttrs().hasAttribute()) { + + printMutabilityModifiersIfNeeded(decl); + if (decl->isConsuming() && !decl->getAttrs().hasAttribute()) { Printer.printKeyword("__consuming", Options, " "); } Printer << tok::kw_func << " "; diff --git a/test/IDE/print_source_file_interface_2.swift b/test/IDE/print_source_file_interface_2.swift index 3dd318ababfab..8a0bb8e7efae4 100644 --- a/test/IDE/print_source_file_interface_2.swift +++ b/test/IDE/print_source_file_interface_2.swift @@ -16,5 +16,10 @@ extension MyClass { subscript(i: Int) -> Int { return 0 } } +/// Don't print `mutating` twice. +struct MyStruct { + mutating func foo() {} +} + // RUN: %target-swift-ide-test -print-swift-file-interface -source-filename %s > %t.out // RUN: diff -u %s.result %t.out diff --git a/test/IDE/print_source_file_interface_2.swift.result b/test/IDE/print_source_file_interface_2.swift.result index 87cdb000b3d66..0ee5cb7d0fa5f 100644 --- a/test/IDE/print_source_file_interface_2.swift.result +++ b/test/IDE/print_source_file_interface_2.swift.result @@ -17,3 +17,9 @@ extension MyClass { /// and a nice subscript. internal subscript(i: Int) -> Int { get } } + +/// Don't print `mutating` twice. +internal struct MyStruct { + + internal mutating func foo() +}