Skip to content

Commit 2e7e6c0

Browse files
rename @_nodoc to @_documentation(...)
1 parent a42850a commit 2e7e6c0

File tree

17 files changed

+196
-58
lines changed

17 files changed

+196
-58
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@ extension Text {
117117
}
118118
```
119119

120+
## `@_documentation(...)`
121+
122+
Adds a "documentation category" to the given symbol.
123+
124+
There are two special-case categories: `underscored` will treat the given symbol
125+
as having an underscored name regardless of its actual name, effectively marking
126+
it as `internal`. Conversely, the `ignoreUnderscored` category will do the
127+
opposite: A symbol with this category will appear in symbol graphs with its
128+
original visibility, regardless of whether it has an underscored name.
129+
130+
`@_documentation(underscored)` can also be applied to `@_exported import`
131+
statements to treat the re-exported symbols as `internal`, dropping them from
132+
public symbol graphs.
133+
120134
## `@_dynamicReplacement(for: targetFunc(label:))`
121135

122136
Marks a function as the dynamic replacement for another `dynamic` function.
@@ -482,16 +496,6 @@ Fun fact: Rust has a very similar concept called
482496
including one called `Send`,
483497
which inspired the design of `Sendable`.
484498

485-
## `@_nodoc`
486-
487-
Indicates that a declaration should not be included in symbol graphs. Symbols
488-
marked with this attribute are treated as if they were given an underscored
489-
name, meaning they are still included in a symbol graph with a "minimum access
490-
level" of `internal` or lower.
491-
492-
This attribute can also be attached to `@_exported import` statements to prevent
493-
symbols imported with this statement from appearing in symbol graphs.
494-
495499
## `@_nonEphemeral`
496500

497501
Marks a function parameter that cannot accept a temporary pointer produced from

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ SIMPLE_DECL_ATTR(_alwaysEmitConformanceMetadata, AlwaysEmitConformanceMetadata,
745745
OnProtocol | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
746746
132)
747747

748-
SIMPLE_DECL_ATTR(_nodoc, NoDoc,
748+
DECL_ATTR(_documentation, Documentation,
749749
OnAnyDecl |
750750
APIBreakingToAdd | APIStableToRemove | ABIStableToAdd | ABIStableToRemove,
751751
132)

include/swift/AST/Attr.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2226,6 +2226,27 @@ class BackDeployAttr: public DeclAttribute {
22262226
}
22272227
};
22282228

2229+
/// The `@_documentation(...)` attribute, used to note a "category" for a
2230+
/// symbol to be associated with, with special cases for forcing a symbol to be
2231+
/// hidden or visible.
2232+
class DocumentationAttr: public DeclAttribute {
2233+
public:
2234+
DocumentationAttr(SourceLoc AtLoc, SourceRange Range,
2235+
StringRef Category,
2236+
bool Implicit)
2237+
: DeclAttribute(DAK_Documentation, AtLoc, Range, Implicit),
2238+
Category(Category) {}
2239+
2240+
DocumentationAttr(StringRef Category, bool Implicit)
2241+
: DocumentationAttr(SourceLoc(), SourceRange(), Category, Implicit) {}
2242+
2243+
const StringRef Category;
2244+
2245+
static bool classof(const DeclAttribute *DA) {
2246+
return DA->getKind() == DAK_Documentation;
2247+
}
2248+
};
2249+
22292250

22302251
/// Attributes that may be applied to declarations.
22312252
class DeclAttributes {

include/swift/AST/DiagnosticsParse.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,9 @@ ERROR(attr_expected_string_literal,none,
14641464
ERROR(attr_expected_integer_literal,none,
14651465
"expected integer literal in '%0' attribute", (StringRef))
14661466

1467+
ERROR(attr_expected_identifier,none,
1468+
"expected identifier in '%0' attribute", (StringRef))
1469+
14671470
ERROR(attr_expected_option_such_as,none,
14681471
"expected '%0' option such as '%1'", (StringRef, StringRef))
14691472

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//===--- DocumentationCategory.h - Accessors for @_documentation ----------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_SYMBOLGRAPHGEN_DOCUMENTATIONCATEGORY_H
14+
#define SWIFT_SYMBOLGRAPHGEN_DOCUMENTATIONCATEGORY_H
15+
16+
#include "swift/AST/Decl.h"
17+
18+
namespace swift {
19+
namespace symbolgraphgen {
20+
21+
static StringRef documentationCategoryForDecl(const Decl *D) {
22+
if (!D) return {};
23+
24+
if (const auto *DC = D->getAttrs().getAttribute<DocumentationAttr>()) {
25+
return DC->Category;
26+
}
27+
28+
return {};
29+
}
30+
31+
static bool isUnderscoredDocumentationCategory(const Decl *D) {
32+
return documentationCategoryForDecl(D) == "underscored";
33+
}
34+
35+
static bool isIgnoreUnderscoredDocumentationCategory(const Decl *D) {
36+
return documentationCategoryForDecl(D) == "ignoreUnderscored";
37+
}
38+
39+
} // namespace symbolgraphgen
40+
} // namespace swift
41+
42+
#endif // SWIFT_SYMBOLGRAPHGEN_DOCUMENTATIONCATEGORY_H

lib/AST/Attr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,8 @@ StringRef DeclAttribute::getAttrName() const {
14401440
return "_unavailableFromAsync";
14411441
case DAK_BackDeploy:
14421442
return "_backDeploy";
1443+
case DAK_Documentation:
1444+
return "_documentation";
14431445
}
14441446
llvm_unreachable("bad DeclAttrKind");
14451447
}

lib/Parse/ParseDecl.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2980,6 +2980,33 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
29802980
return false;
29812981
break;
29822982
}
2983+
case DAK_Documentation: {
2984+
if (!consumeIf(tok::l_paren)) {
2985+
diagnose(Loc, diag::attr_expected_lparen, AttrName,
2986+
DeclAttribute::isDeclModifier(DK));
2987+
return false;
2988+
}
2989+
2990+
if (Tok.isNot(tok::identifier)) {
2991+
diagnose(Loc, diag::attr_expected_identifier, AttrName);
2992+
return false;
2993+
}
2994+
2995+
auto category = Tok.getText();
2996+
2997+
consumeToken(tok::identifier);
2998+
2999+
auto range = SourceRange(Loc, Tok.getRange().getStart());
3000+
3001+
if (!consumeIf(tok::r_paren)) {
3002+
diagnose(Loc, diag::attr_expected_rparen, AttrName,
3003+
DeclAttribute::isDeclModifier(DK));
3004+
return false;
3005+
}
3006+
3007+
Attributes.add(new (Context) DocumentationAttr(AtLoc, range, category, false));
3008+
break;
3009+
}
29833010
}
29843011

29853012
if (DuplicateAttribute) {

lib/Sema/ImportResolution.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/ClangImporter/ClangModule.h"
2929
#include "swift/Parse/Parser.h"
3030
#include "swift/Subsystems.h"
31+
#include "swift/SymbolGraphGen/DocumentationCategory.h"
3132
#include "clang/Basic/Module.h"
3233
#include "llvm/ADT/DenseMap.h"
3334
#include "llvm/ADT/TinyPtrVector.h"
@@ -530,7 +531,7 @@ UnboundImport::UnboundImport(ImportDecl *ID)
530531
if (ID->isExported())
531532
import.options |= ImportFlags::Exported;
532533

533-
if (ID->getAttrs().hasAttribute<NoDocAttr>())
534+
if (swift::symbolgraphgen::isUnderscoredDocumentationCategory(ID))
534535
import.options |= ImportFlags::NoDoc;
535536

536537
if (ID->getAttrs().hasAttribute<TestableAttr>())

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
157157
IGNORED_ATTR(Isolated)
158158
IGNORED_ATTR(Preconcurrency)
159159
IGNORED_ATTR(BackDeploy)
160-
IGNORED_ATTR(NoDoc)
160+
IGNORED_ATTR(Documentation)
161161
#undef IGNORED_ATTR
162162

163163
void visitAlignmentAttr(AlignmentAttr *attr) {

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,7 @@ namespace {
14911491
UNINTERESTING_ATTR(Borrowed)
14921492
UNINTERESTING_ATTR(CDecl)
14931493
UNINTERESTING_ATTR(Consuming)
1494+
UNINTERESTING_ATTR(Documentation)
14941495
UNINTERESTING_ATTR(Dynamic)
14951496
UNINTERESTING_ATTR(DynamicCallable)
14961497
UNINTERESTING_ATTR(DynamicMemberLookup)
@@ -1519,7 +1520,6 @@ namespace {
15191520
UNINTERESTING_ATTR(Lazy)
15201521
UNINTERESTING_ATTR(LLDBDebuggerFunction)
15211522
UNINTERESTING_ATTR(Mutating)
1522-
UNINTERESTING_ATTR(NoDoc)
15231523
UNINTERESTING_ATTR(NonMutating)
15241524
UNINTERESTING_ATTR(NonEphemeral)
15251525
UNINTERESTING_ATTR(NonObjC)

lib/Serialization/Deserialization.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5003,6 +5003,16 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
50035003
break;
50045004
}
50055005

5006+
case decls_block::Documentation_DECL_ATTR: {
5007+
bool isImplicit;
5008+
uint64_t CategoryID;
5009+
serialization::decls_block::DocumentationDeclAttrLayout::readRecord(
5010+
scratch, isImplicit, CategoryID);
5011+
StringRef CategoryText = MF.getIdentifierText(CategoryID);
5012+
Attr = new (ctx) DocumentationAttr(CategoryText, isImplicit);
5013+
break;
5014+
}
5015+
50065016
#define SIMPLE_DECL_ATTR(NAME, CLASS, ...) \
50075017
case decls_block::CLASS##_DECL_ATTR: { \
50085018
bool isImplicit; \

lib/Serialization/ModuleFormat.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,12 @@ namespace decls_block {
20962096
BCVBR<5> // platform
20972097
>;
20982098

2099+
using DocumentationDeclAttrLayout = BCRecordLayout<
2100+
Documentation_DECL_ATTR,
2101+
BCFixed<1>, // implicit flag
2102+
IdentifierIDField // category name
2103+
>;
2104+
20992105
#undef SYNTAX_SUGAR_TYPE_LAYOUT
21002106
#undef TYPE_LAYOUT
21012107
#undef TYPE_LAYOUT_IMPL

lib/Serialization/Serialization.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,6 +2844,15 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
28442844
theAttr->Message);
28452845
return;
28462846
}
2847+
2848+
case DAK_Documentation: {
2849+
auto *theAttr = cast<DocumentationAttr>(DA);
2850+
auto abbrCode = S.DeclTypeAbbrCodes[DocumentationDeclAttrLayout::Code];
2851+
auto categoryIDPair = S.addUniquedString(theAttr->Category);
2852+
DocumentationDeclAttrLayout::emitRecord(
2853+
S.Out, S.ScratchRecord, abbrCode, theAttr->isImplicit(), categoryIDPair.second);
2854+
return;
2855+
}
28472856
}
28482857
}
28492858

lib/SymbolGraphGen/SymbolGraph.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/USRGeneration.h"
1919
#include "swift/Basic/Version.h"
2020
#include "swift/Sema/IDETypeChecking.h"
21+
#include "swift/SymbolGraphGen/DocumentationCategory.h"
2122

2223
#include "DeclarationFragmentPrinter.h"
2324
#include "FormatVersion.h"
@@ -582,7 +583,8 @@ bool SymbolGraph::isImplicitlyPrivate(const Decl *D,
582583
}
583584

584585
// Don't record effectively internal declarations if specified
585-
if (D->hasUnderscoredNaming() || D->getAttrs().hasAttribute<NoDocAttr>()) {
586+
if (isUnderscoredDocumentationCategory(D) ||
587+
(D->hasUnderscoredNaming() && !isIgnoreUnderscoredDocumentationCategory(D))) {
586588
// Some implicit decls from Clang with underscored names sneak in, so throw those out
587589
if (const auto *clangD = D->getClangDecl()) {
588590
if (clangD->isImplicit())

test/SymbolGraph/Module/NoDocExportedImport.swift renamed to test/SymbolGraph/Module/DocAttrExportedImport.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
// RUN: %target-swift-frontend %S/Inputs/ExportedImport/A.swift -module-name A -emit-module -emit-module-path %t/A.swiftmodule
33
// RUN: %target-swift-frontend %S/Inputs/ExportedImport/B.swift -module-name B -emit-module -emit-module-path %t/B.swiftmodule
44

5-
// RUN: %target-swift-frontend %s -module-name NoDocExportedImport -emit-module -emit-module-path /dev/null -I %t -emit-symbol-graph -emit-symbol-graph-dir %t/
6-
// RUN: %FileCheck %s --input-file %t/NoDocExportedImport.symbols.json --check-prefix PUBLIC
5+
// RUN: %target-swift-frontend %s -module-name DocAttrExportedImport -emit-module -emit-module-path /dev/null -I %t -emit-symbol-graph -emit-symbol-graph-dir %t/
6+
// RUN: %FileCheck %s --input-file %t/DocAttrExportedImport.symbols.json --check-prefix PUBLIC
77
// RUN: ls %t | %FileCheck %s --check-prefix FILES
88

9-
// RUN: %target-swift-frontend %s -module-name NoDocExportedImport -emit-module -emit-module-path /dev/null -I %t -emit-symbol-graph -emit-symbol-graph-dir %t/ -symbol-graph-minimum-access-level internal
10-
// RUN: %FileCheck %s --input-file %t/NoDocExportedImport.symbols.json --check-prefix INTERNAL
9+
// RUN: %target-swift-frontend %s -module-name DocAttrExportedImport -emit-module -emit-module-path /dev/null -I %t -emit-symbol-graph -emit-symbol-graph-dir %t/ -symbol-graph-minimum-access-level internal
10+
// RUN: %FileCheck %s --input-file %t/DocAttrExportedImport.symbols.json --check-prefix INTERNAL
1111
// RUN: ls %t | %FileCheck %s --check-prefix FILES
1212

13-
@_nodoc @_exported import A
14-
@_nodoc @_exported import struct B.StructOne
13+
@_documentation(underscored) @_exported import A
14+
@_documentation(underscored) @_exported import struct B.StructOne
1515

1616
// PUBLIC-NOT: InternalSymbolFromA
1717
// PUBLIC-NOT: StructTwo
@@ -26,5 +26,5 @@
2626
// FIXME: Symbols from `@_exported import` do not get emitted when using swift-symbolgraph-extract
2727
// This is tracked by https://bugs.swift.org/browse/SR-15921.
2828

29-
// FILES-NOT: NoDocExportedImport@A.symbols.json
29+
// FILES-NOT: DocAttrExportedImport@A.symbols.json
3030

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -module-name DocumentationAttr -emit-module -emit-module-path %t/
3+
// RUN: %target-swift-symbolgraph-extract -module-name DocumentationAttr -I %t -pretty-print -output-dir %t
4+
// RUN: %FileCheck %s --input-file %t/DocumentationAttr.symbols.json --check-prefix PUBLIC
5+
6+
// RUN: %target-swift-symbolgraph-extract -module-name DocumentationAttr -I %t -pretty-print -output-dir %t -minimum-access-level internal
7+
// RUN: %FileCheck %s --input-file %t/DocumentationAttr.symbols.json --check-prefix INTERNAL
8+
9+
// RUN: %target-swift-symbolgraph-extract -module-name DocumentationAttr -I %t -pretty-print -output-dir %t -minimum-access-level private
10+
// RUN: %FileCheck %s --input-file %t/DocumentationAttr.symbols.json --check-prefix PRIVATE
11+
12+
// This test is a mirror of SkipsPublicUnderscore.swift, but using `@_documentation`
13+
// instead of underscored names.
14+
15+
public protocol PublicProtocol {}
16+
17+
// PUBLIC-NOT: ShouldntAppear
18+
// INTERNAL-DAG: ShouldntAppear
19+
// PRIVATE-DAG: ShouldntAppear
20+
21+
@_documentation(underscored) public struct ShouldntAppear: PublicProtocol {
22+
public struct InnerShouldntAppear {}
23+
}
24+
25+
public class SomeClass {
26+
// PUBLIC-NOT: internalVar
27+
// INTERNAL-NOT: internalVar
28+
// PRIVATE-DAG: internalVar
29+
@_documentation(underscored) internal var internalVar: String = ""
30+
}
31+
32+
@_documentation(underscored) public protocol ProtocolShouldntAppear {}
33+
34+
public struct PublicStruct: ProtocolShouldntAppear {
35+
@_documentation(underscored) public struct InnerShouldntAppear {}
36+
}
37+
38+
// The presence of `@_documentation(ignoreUnderscored)` should cause SymbolGraphGen to include an
39+
// underscored enum case.
40+
41+
// PUBLIC-DAG: _ShouldAppear
42+
43+
public enum PublicEnum {
44+
case RegularCase
45+
case _ShouldntAppear
46+
@_documentation(ignoreUnderscored) case _ShouldAppear
47+
}

test/SymbolGraph/Symbols/NoDocAttribute.swift

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)