Skip to content

Commit f45c338

Browse files
committed
[ASTPrinter] Fix duplicate «mutating» modifiers when printing file interface
1 parent 5a8e3ea commit f45c338

File tree

3 files changed

+40
-26
lines changed

3 files changed

+40
-26
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
812812
bool shouldPrintPattern(const Pattern *P);
813813
void printPatternType(const Pattern *P);
814814
void printAccessors(const AbstractStorageDecl *ASD);
815-
void printMutatingModifiersIfNeeded(const AccessorDecl *accessor);
815+
void printMutabilityModifiersIfNeeded(const FuncDecl *FD);
816816
void printMembersOfDecl(Decl * NTD, bool needComma = false,
817817
bool openBracket = true, bool closeBracket = true);
818818
void printMembers(ArrayRef<Decl *> members, bool needComma = false,
@@ -990,9 +990,6 @@ void PrintAST::printAttributes(const Decl *D) {
990990
#define CONTEXTUAL_SIMPLE_DECL_ATTR(X, Class, Y, Z) EXCLUDE_ATTR(Class)
991991
#define CONTEXTUAL_DECL_ATTR_ALIAS(X, Class) EXCLUDE_ATTR(Class)
992992
#include "swift/AST/Attr.def"
993-
} else if (isa<FuncDecl>(D)) {
994-
Options.ExcludeAttrList.push_back(DAK_Mutating);
995-
Options.ExcludeAttrList.push_back(DAK_NonMutating);
996993
}
997994

998995
// If the declaration is implicitly @objc, print the attribute now.
@@ -1008,19 +1005,23 @@ void PrintAST::printAttributes(const Decl *D) {
10081005
// clients, or if it inherits superclass convenience initializers,
10091006
// then print those attributes specially.
10101007
if (auto CD = dyn_cast<ClassDecl>(D)) {
1011-
if (Options.PrintImplicitAttrs) {
1012-
if (CD->inheritsSuperclassInitializers()) {
1013-
Printer.printAttrName("@_inheritsConvenienceInitializers");
1014-
Printer << " ";
1015-
}
1016-
if (CD->hasMissingDesignatedInitializers()) {
1017-
Printer.printAttrName("@_hasMissingDesignatedInitializers");
1018-
Printer << " ";
1019-
}
1008+
if (CD->inheritsSuperclassInitializers()) {
1009+
Printer.printAttrName("@_inheritsConvenienceInitializers");
1010+
Printer << " ";
1011+
}
1012+
if (CD->hasMissingDesignatedInitializers()) {
1013+
Printer.printAttrName("@_hasMissingDesignatedInitializers");
1014+
Printer << " ";
10201015
}
10211016
}
10221017
}
10231018

1019+
// We will handle 'mutating' and 'nonmutating' separately.
1020+
if (isa<FuncDecl>(D)) {
1021+
Options.ExcludeAttrList.push_back(DAK_Mutating);
1022+
Options.ExcludeAttrList.push_back(DAK_NonMutating);
1023+
}
1024+
10241025
D->getAttrs().print(Printer, Options, D);
10251026

10261027
// Print the implicit 'final' attribute.
@@ -1758,12 +1759,15 @@ void PrintAST::printBodyIfNecessary(const AbstractFunctionDecl *decl) {
17581759
printBraceStmt(decl->getBody(), /*newlineIfEmpty*/!isa<AccessorDecl>(decl));
17591760
}
17601761

1761-
void PrintAST::printMutatingModifiersIfNeeded(const AccessorDecl *accessor) {
1762-
if (accessor->isAssumedNonMutating() && accessor->isMutating() &&
1763-
!Options.excludeAttrKind(DAK_Mutating)) {
1764-
Printer.printKeyword("mutating", Options, " ");
1765-
} else if (accessor->isExplicitNonMutating() &&
1766-
!Options.excludeAttrKind(DAK_NonMutating)) {
1762+
void PrintAST::printMutabilityModifiersIfNeeded(const FuncDecl *FD) {
1763+
const auto *AD = dyn_cast<AccessorDecl>(FD);
1764+
1765+
if (FD->isMutating()) {
1766+
if (AD == nullptr || AD->isAssumedNonMutating())
1767+
if (!Options.excludeAttrKind(DAK_Mutating))
1768+
Printer.printKeyword("mutating", Options, " ");
1769+
} else if (AD && AD->isExplicitNonMutating() &&
1770+
!Options.excludeAttrKind(DAK_Mutating)) {
17671771
Printer.printKeyword("nonmutating", Options, " ");
17681772
}
17691773
}
@@ -1881,7 +1885,7 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
18811885
return true;
18821886
if (!PrintAccessorBody) {
18831887
Printer << " ";
1884-
printMutatingModifiersIfNeeded(Accessor);
1888+
printMutabilityModifiersIfNeeded(Accessor);
18851889
Printer.printKeyword(getAccessorLabel(Accessor->getAccessorKind()), Options);
18861890
} else {
18871891
{
@@ -2777,10 +2781,9 @@ bool PrintAST::printASTNodes(const ArrayRef<ASTNode> &Elements,
27772781
void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
27782782
printDocumentationComment(decl);
27792783
printAttributes(decl);
2784+
// Explicitly print 'mutating' and 'nonmutating' if needed.
2785+
printMutabilityModifiersIfNeeded(decl);
27802786

2781-
// Explicitly print 'mutating' and 'nonmutating' before getters and setters
2782-
// for which that is true.
2783-
printMutatingModifiersIfNeeded(decl);
27842787
switch (auto kind = decl->getAccessorKind()) {
27852788
case AccessorKind::Get:
27862789
case AccessorKind::Address:
@@ -2837,9 +2840,9 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
28372840
if (!Options.SkipIntroducerKeywords) {
28382841
if (decl->isStatic() && Options.PrintStaticKeyword)
28392842
printStaticKeyword(decl->getCorrectStaticSpelling());
2840-
if (decl->isMutating() && !Options.excludeAttrKind(DAK_Mutating)) {
2841-
Printer.printKeyword("mutating", Options, " ");
2842-
} else if (decl->isConsuming() && !decl->getAttrs().hasAttribute<ConsumingAttr>()) {
2843+
2844+
printMutabilityModifiersIfNeeded(decl);
2845+
if (decl->isConsuming() && !decl->getAttrs().hasAttribute<ConsumingAttr>()) {
28432846
Printer.printKeyword("__consuming", Options, " ");
28442847
}
28452848
Printer << tok::kw_func << " ";

test/IDE/print_source_file_interface_2.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,10 @@ extension MyClass {
1616
subscript(i: Int) -> Int { return 0 }
1717
}
1818

19+
/// Don't print `mutating` twice.
20+
struct MyStruct {
21+
mutating func foo() {}
22+
}
23+
1924
// RUN: %target-swift-ide-test -print-swift-file-interface -source-filename %s > %t.out
2025
// RUN: diff -u %s.result %t.out

test/IDE/print_source_file_interface_2.swift.result

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,9 @@ extension MyClass {
1717
/// and a nice subscript.
1818
internal subscript(i: Int) -> Int { get }
1919
}
20+
21+
/// Don't print `mutating` twice.
22+
internal struct MyStruct {
23+
24+
internal mutating func foo()
25+
}

0 commit comments

Comments
 (0)