Skip to content

Commit

Permalink
[ClangModulePrint] If skipping an unavailable decl, skipping its foll…
Browse files Browse the repository at this point in the history
…owing regular comments too. rdar://20092567

This only works for Clang-imported but unavailable decls, but not for Clang decls that
are not imported.

Swift SVN r32769
  • Loading branch information
nkcsgexi committed Oct 20, 2015
1 parent 10a6615 commit e133125
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 16 deletions.
2 changes: 2 additions & 0 deletions include/swift/AST/ASTPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class ASTPrinter {

virtual void printText(StringRef Text) = 0;

/// Called after the printer decides not to print D.
virtual void avoidPrintDeclPost(const Decl *D) {};
/// Called before printing of a declaration.
virtual void printDeclPre(const Decl *D) {}
/// Called before printing at the point which would be considered the location
Expand Down
30 changes: 18 additions & 12 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
void printWhereClause(ArrayRef<RequirementRepr> requirements);

private:
bool shouldPrint(const Decl *D);
bool shouldPrint(const Decl *D, bool Notify = false);
bool shouldPrintPattern(const Pattern *P);
void printPatternType(const Pattern *P);
void printAccessors(AbstractStorageDecl *ASD);
Expand Down Expand Up @@ -420,7 +420,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
using ASTVisitor::visit;

bool visit(Decl *D) {
if (!shouldPrint(D))
if (!shouldPrint(D, true))
return false;

Printer.callPrintDeclPre(D);
Expand Down Expand Up @@ -664,33 +664,39 @@ void PrintAST::printPatternType(const Pattern *P) {
}
}

bool PrintAST::shouldPrint(const Decl *D) {
bool PrintAST::shouldPrint(const Decl *D, bool Notify) {
auto SkipDecl = [&] () {
if (Notify)
Printer.avoidPrintDeclPost(D);
return false;
};

if (auto *ED= dyn_cast<ExtensionDecl>(D)) {
if (Options.printExtensionContentAsMembers(ED))
return false;
return SkipDecl();
}

if (Options.SkipDeinit && isa<DestructorDecl>(D)) {
return false;
return SkipDecl();
}

if (Options.SkipImplicit && D->isImplicit())
return false;
return SkipDecl();

if (Options.SkipUnavailable &&
D->getAttrs().isUnavailable(D->getASTContext()))
return false;
return SkipDecl();

// Skip declarations that are not accessible.
if (auto *VD = dyn_cast<ValueDecl>(D)) {
if (Options.AccessibilityFilter > Accessibility::Private &&
VD->hasAccessibility() &&
VD->getFormalAccess() < Options.AccessibilityFilter)
return false;
return SkipDecl();
}

if (Options.SkipPrivateStdlibDecls && D->isPrivateStdlibDecl())
return false;
return SkipDecl();

if (Options.SkipEmptyExtensionDecls && isa<ExtensionDecl>(D)) {
auto Ext = cast<ExtensionDecl>(D);
Expand All @@ -705,7 +711,7 @@ bool PrintAST::shouldPrint(const Decl *D) {
}
}
if (!HasMemberToPrint)
return false;
return SkipDecl();
}
}

Expand All @@ -718,7 +724,7 @@ bool PrintAST::shouldPrint(const Decl *D) {
if (ShouldPrint)
return true;
}
return false;
return SkipDecl();
}

return true;
Expand Down Expand Up @@ -941,7 +947,7 @@ void PrintAST::printMembers(ArrayRef<Decl *> members, bool needComma) {
for (auto i = members.begin(), iEnd = members.end(); i != iEnd; ++i) {
auto member = *i;

if (!shouldPrint(member))
if (!shouldPrint(member, true))
continue;

if (!member->shouldPrintInContext(Options))
Expand Down
25 changes: 24 additions & 1 deletion lib/IDE/ModuleInterfacePrinting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ClangCommentPrinter : public ASTPrinter {
private:
void printDeclPre(const Decl *D) override;
void printDeclPost(const Decl *D) override;

void avoidPrintDeclPost(const Decl *D) override;
// Forwarding implementations.

void printText(StringRef Text) override {
Expand Down Expand Up @@ -519,6 +519,29 @@ void swift::ide::printHeaderInterface(
}
}

void ClangCommentPrinter::avoidPrintDeclPost(const Decl *D) {
auto CD = D->getClangDecl();
if (!CD)
return;
const auto &Ctx = ClangLoader.getClangASTContext();
const auto &SM = Ctx.getSourceManager();
auto EndLoc = CD->getSourceRange().getEnd();
if (EndLoc.isInvalid())
return;
clang::FileID FID = SM.getFileID(EndLoc);
if (FID.isInvalid())
return;
auto Loc = EndLoc;

for (unsigned Line = SM.getSpellingLineNumber(EndLoc);
Loc.isValid() && SM.getSpellingLineNumber(Loc) == Line;
Loc = Loc.getLocWithOffset(1));
if (Loc.isInvalid())
return;
if (SM.getFileOffset(Loc) > getResumeOffset(FID))
setResumeOffset(FID, SM.getFileOffset(Loc));
}

void ClangCommentPrinter::printDeclPre(const Decl *D) {
if (auto ClangN = D->getClangNode()) {
printCommentsUntil(ClangN);
Expand Down
9 changes: 9 additions & 0 deletions test/IDE/Inputs/mock-sdk/Foo.annotated.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,12 @@ func <loc>FooCFTypeRelease(_: <ref:Class>FooCFType</ref>!)</loc></decl>
}</decl>
<decl:Extension>extension <ref:Class><loc>FooRepeatedMembers</ref></loc> {
}</decl>
<decl:Enum>enum <loc>SCNFilterMode</loc> : <ref:Struct>Int</ref> {
<decl:Constructor><loc>init?(rawValue: <ref:Struct>Int</ref>)</loc></decl>
<decl:Var>var <loc>rawValue</loc>: <ref:Struct>Int</ref> { get }</decl>
<decl:EnumElement>case <loc>None</loc></decl>
<decl:EnumElement>case <loc>Nearest</loc></decl>
<decl:EnumElement>case <loc>Linear</loc></decl>
<decl:EnumElement>@available(*, unavailable)
case <loc>SCNNoFiltering</loc></decl>
}</decl>
9 changes: 8 additions & 1 deletion test/IDE/Inputs/mock-sdk/Foo.framework/Headers/Foo.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ struct _InternalStruct {
@interface FooUnavailableMembers : FooClassBase
+ (instancetype)unavailableMembersWithInt:(int)i;

- (void)unavailable __attribute__((unavailable("x")));
- (void)unavailable __attribute__((unavailable("x"))); // This comment should not show without decl. rdar://20092567
- (void)swiftUnavailable __attribute__((annotate("swift1_unavailable")));
- (void)deprecated __attribute__((deprecated("x")));

Expand Down Expand Up @@ -282,4 +282,11 @@ void FooCFTypeRelease(FooCFTypeRef);
- (void)repeatedMethodFromCategory;
@end

typedef NS_ENUM(long, SCNFilterMode) {
SCNFilterModeNone = 0,
SCNFilterModeNearest = 1,
SCNFilterModeLinear = 2,
SCNNoFiltering __attribute__((unavailable(""))) = 3, // This comment should not show without decl.
};

#endif /* ! __FOO_H__ */
9 changes: 9 additions & 0 deletions test/IDE/Inputs/mock-sdk/Foo.printed.recursive.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ extension FooRepeatedMembers {
}
extension FooRepeatedMembers {
}
enum SCNFilterMode : Int {
init?(rawValue: Int)
var rawValue: Int { get }
case None
case Nearest
case Linear
@available(*, unavailable)
case SCNNoFiltering
}
func fooSubFunc1(a: Int32) -> Int32
struct FooSubEnum1 : RawRepresentable, Equatable {
init(_ rawValue: UInt32)
Expand Down
13 changes: 12 additions & 1 deletion test/IDE/Inputs/mock-sdk/Foo.printed.txt
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ class FooUnavailableMembers : FooClassBase {
class func unavailableMembersWithInt(i: Int32) -> Self!

@available(*, unavailable, message="x")
func unavailable()
func unavailable() // This comment should not show without decl. rdar://20092567
@available(*, unavailable, message="Not available in Swift")
func swiftUnavailable()
@available(*, deprecated, message="x")
Expand Down Expand Up @@ -325,3 +325,14 @@ extension FooRepeatedMembers {

extension FooRepeatedMembers {
}

enum SCNFilterMode : Int {
init?(rawValue: Int)
var rawValue: Int { get }

case None
case Nearest
case Linear
@available(*, unavailable)
case SCNNoFiltering // This comment should not show without decl.
}
8 changes: 7 additions & 1 deletion test/IDE/print_clang_framework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
// RUN: %target-swift-ide-test(mock-sdk: -F %S/Inputs/mock-sdk) -print-module -source-filename %s -module-to-print=Foo -function-definitions=false -print-regular-comments > %t/Foo.printed.txt
// RUN: diff -u %S/Inputs/mock-sdk/Foo.printed.txt %t/Foo.printed.txt

// RUN: %target-swift-ide-test(mock-sdk: -F %S/Inputs/mock-sdk) -print-interface -print-module -source-filename %s -module-to-print=Foo -function-definitions=false -print-regular-comments > %t/Foo.interface.printed.txt
// RUN: FileCheck %s -check-prefix=INTERFACE1 < %t/Foo.interface.printed.txt

// RUN: %target-swift-ide-test(mock-sdk: -F %S/Inputs/mock-sdk) -print-module -source-filename %s -module-to-print=Foo -function-definitions=false -prefer-type-repr=true -module-print-submodules > %t/Foo.printed.recursive.txt
// RUN: diff -u %S/Inputs/mock-sdk/Foo.printed.recursive.txt %t/Foo.printed.recursive.txt

Expand Down Expand Up @@ -140,4 +143,7 @@
// FOUNDATION-NEXT: {{^}} func someMethodWithAvailability()
// FOUNDATION-NEXT: {{^}} @available(OSX 10.11, *)
// FOUNDATION-NEXT: {{^}} var someProperty: AnnotatedFrameworkClass
}
}

// INTERFACE1-NOT: unavailable
// INTERFACE1-NOT: This comment should not show without decl.

0 comments on commit e133125

Please sign in to comment.