Skip to content

Commit c3b662d

Browse files
committed
Serialize package and SPI doc comments in swiftsourceinfo
Previously we were using the same set of conditions for serializing as for swiftdoc, so excluded them. However it's reasonable to have them in the swiftsourceinfo.
1 parent 3dbfdc0 commit c3b662d

File tree

5 files changed

+146
-20
lines changed

5 files changed

+146
-20
lines changed

lib/Serialization/SerializeDoc.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -331,29 +331,42 @@ static bool hasDoubleUnderscore(Decl *D) {
331331
return false;
332332
}
333333

334-
static bool shouldIncludeDecl(Decl *D, bool ExcludeDoubleUnderscore) {
334+
static bool shouldIncludeDecl(Decl *D, bool ForSourceInfo) {
335335
if (auto *VD = dyn_cast<ValueDecl>(D)) {
336+
// When emitting for .swiftsourceinfo, we can include package decls.
337+
// Otherwise, the decl must be public.
338+
auto MinAccess = ForSourceInfo ? swift::AccessLevel::Package
339+
: swift::AccessLevel::Public;
340+
336341
// Skip the decl if it's not visible to clients. The use of
337342
// getEffectiveAccess is unusual here; we want to take the testability
338343
// state into account and emit documentation if and only if they are
339344
// visible to clients (which means public ordinarily, but
340345
// public+internal when testing enabled).
341-
if (VD->getEffectiveAccess() < swift::AccessLevel::Public)
346+
if (VD->getEffectiveAccess() < MinAccess)
342347
return false;
343348
}
344349

345-
// Skip SPI decls, unless we're generating a symbol graph with SPI information.
346-
if (D->isSPI() && !D->getASTContext().SymbolGraphOpts.IncludeSPISymbols)
347-
return false;
350+
// Apply some extra filters, unless we're emitting .swiftsourceinfo, where
351+
// we can be more relaxed with what we emit.
352+
if (!ForSourceInfo) {
353+
// Skip SPI decls, unless we're generating a symbol graph with SPI
354+
// information.
355+
if (D->isSPI() && !D->getASTContext().SymbolGraphOpts.IncludeSPISymbols)
356+
return false;
357+
358+
// .swiftdoc doesn't include comments for double underscored symbols, but
359+
// for .swiftsourceinfo, having the source location for these symbols isn't
360+
// a concern because these symbols are in .swiftinterface anyway.
361+
if (hasDoubleUnderscore(D))
362+
return false;
363+
}
348364

349365
if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
350366
auto *extended = ED->getExtendedNominal();
351367
if (!extended)
352368
return false;
353-
return shouldIncludeDecl(extended, ExcludeDoubleUnderscore);
354-
}
355-
if (ExcludeDoubleUnderscore && hasDoubleUnderscore(D)) {
356-
return false;
369+
return shouldIncludeDecl(extended, ForSourceInfo);
357370
}
358371
return true;
359372
}
@@ -419,7 +432,7 @@ static void writeDeclCommentTable(
419432
}
420433

421434
PreWalkAction walkToDeclPre(Decl *D) override {
422-
if (!shouldIncludeDecl(D, /*ExcludeDoubleUnderscore*/true))
435+
if (!shouldIncludeDecl(D, /*ForSourceInfo*/false))
423436
return Action::SkipChildren();
424437
if (!shouldSerializeDoc(D))
425438
return Action::Continue();
@@ -731,10 +744,7 @@ struct BasicDeclLocsTableWriter : public ASTWalker {
731744
}
732745

733746
PreWalkAction walkToDeclPre(Decl *D) override {
734-
// .swiftdoc doesn't include comments for double underscored symbols, but
735-
// for .swiftsourceinfo, having the source location for these symbols isn't
736-
// a concern because these symbols are in .swiftinterface anyway.
737-
if (!shouldIncludeDecl(D, /*ExcludeDoubleUnderscore*/false))
747+
if (!shouldIncludeDecl(D, /*ForSourceInfo*/true))
738748
return Action::SkipChildren();
739749
if (!shouldSerializeSourceLoc(D))
740750
return Action::Continue();

test/Serialization/Inputs/def_comments.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,11 @@ public protocol second_decl_protocol_1 {
2727

2828
public var (decl_var_2, decl_var_3): (Int, Float) = (1, 1.0)
2929

30+
/// Comment on package function
31+
package func second_package_function() {}
32+
33+
/// Comment on SPI function
34+
@_spi(DocSPI) public func second_spi_function() {}
35+
3036
#sourceLocation(file:"NonExistingSource.swift", line:100000)
3137
public func functionAfterPoundSourceLoc() {}

test/Serialization/comments.swift

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Test the case when we have a single file in a module.
22
//
33
// RUN: %empty-directory(%t)
4-
// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -emit-module-source-info-path %t/comments.swiftsourceinfo %s
4+
// RUN: %target-swift-frontend -module-name comments -package-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -emit-module-source-info-path %t/comments.swiftsourceinfo %s
55
// RUN: llvm-bcanalyzer %t/comments.swiftmodule | %FileCheck %s -check-prefix=BCANALYZER
66
// RUN: llvm-bcanalyzer %t/comments.swiftdoc | %FileCheck %s -check-prefix=BCANALYZER
77
// RUN: llvm-bcanalyzer %t/comments.swiftsourceinfo | %FileCheck %s -check-prefix=BCANALYZER
@@ -10,9 +10,9 @@
1010
// Test the case when we have a multiple files in a module.
1111
//
1212
// RUN: %empty-directory(%t)
13-
// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/first.swiftmodule -emit-module-doc -emit-module-doc-path %t/first.swiftdoc -primary-file %s %S/Inputs/def_comments.swift -emit-module-source-info-path %t/first.swiftsourceinfo
14-
// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/second.swiftmodule -emit-module-doc -emit-module-doc-path %t/second.swiftdoc %s -primary-file %S/Inputs/def_comments.swift -emit-module-source-info-path %t/second.swiftsourceinfo
15-
// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc %t/first.swiftmodule %t/second.swiftmodule -emit-module-source-info-path %t/comments.swiftsourceinfo
13+
// RUN: %target-swift-frontend -module-name comments -package-name comments -emit-module -emit-module-path %t/first.swiftmodule -emit-module-doc -emit-module-doc-path %t/first.swiftdoc -primary-file %s %S/Inputs/def_comments.swift -emit-module-source-info-path %t/first.swiftsourceinfo
14+
// RUN: %target-swift-frontend -module-name comments -package-name comments -emit-module -emit-module-path %t/second.swiftmodule -emit-module-doc -emit-module-doc-path %t/second.swiftdoc %s -primary-file %S/Inputs/def_comments.swift -emit-module-source-info-path %t/second.swiftsourceinfo
15+
// RUN: %target-swift-frontend -module-name comments -package-name comments -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc %t/first.swiftmodule %t/second.swiftmodule -emit-module-source-info-path %t/comments.swiftsourceinfo
1616
// RUN: llvm-bcanalyzer %t/comments.swiftmodule | %FileCheck %s -check-prefix=BCANALYZER
1717
// RUN: llvm-bcanalyzer %t/comments.swiftdoc | %FileCheck %s -check-prefix=BCANALYZER
1818
// RUN: llvm-bcanalyzer %t/comments.swiftsourceinfo | %FileCheck %s -check-prefix=BCANALYZER
@@ -60,16 +60,26 @@ public protocol P1 { }
6060
/// Comment for no member extension
6161
extension first_decl_class_1 : P1 {}
6262

63+
/// Comment on package function
64+
package func first_package_function() {}
65+
66+
/// Comment on SPI function
67+
@_spi(DocSPI) public func first_spi_function() {}
68+
6369
// FIRST: comments.swift:26:14: Class/first_decl_generic_class_1 RawComment=[/// first_decl_generic_class_1 Aaa.\n]
6470
// FIRST: comments.swift:28:3: Destructor/first_decl_generic_class_1.deinit RawComment=[/// deinit of first_decl_generic_class_1 Aaa.\n]
6571
// FIRST: comments.swift:33:14: Class/first_decl_class_1 RawComment=[/// first_decl_class_1 Aaa.\n]
6672
// FIRST: comments.swift:36:15: Func/first_decl_class_1.decl_func_1 RawComment=[/// decl_func_1 Aaa.\n]
6773
// FIRST: comments.swift:41:15: Func/first_decl_class_1.decl_func_2 RawComment=[/**\n * decl_func_3 Aaa.\n */]
6874
// FIRST: comments.swift:45:15: Func/first_decl_class_1.decl_func_3 RawComment=[/// decl_func_3 Aaa.\n/** Bbb. */]
75+
// FIRST: comments.swift:64:14: Func/first_package_function RawComment=[/// Comment on package function\n]
76+
// FIRST: comments.swift:67:27: Func/first_spi_function RawComment=[/// Comment on SPI function\n]
6977

7078
// SECOND: comments.swift:49:1: Extension/ RawComment=[/// Comment for bar1\n] BriefComment=[Comment for bar1]
7179
// SECOND: comments.swift:54:1: Extension/ RawComment=[/// Comment for bar2\n] BriefComment=[Comment for bar2]
7280
// SECOND: comments.swift:61:1: Extension/ RawComment=[/// Comment for no member extension\n] BriefComment=[Comment for no member extension]
81+
// SECOND: comments.swift:64:14: Func/first_package_function RawComment=[/// Comment on package function\n]
82+
// SECOND: comments.swift:67:27: Func/first_spi_function RawComment=[/// Comment on SPI function\n]
7383
// SECOND: Inputs/def_comments.swift:2:14: Class/second_decl_class_1 RawComment=[/// second_decl_class_1 Aaa.\n]
7484
// SECOND: Inputs/def_comments.swift:5:15: Struct/second_decl_struct_1
7585
// SECOND: Inputs/def_comments.swift:7:9: Accessor/second_decl_struct_1.<getter for second_decl_struct_1.instanceVar>
@@ -88,13 +98,23 @@ extension first_decl_class_1 : P1 {}
8898
// SECOND: Inputs/def_comments.swift:28:13: Var/decl_var_2 RawComment=none BriefComment=none DocCommentAsXML=none
8999
// SECOND: Inputs/def_comments.swift:28:25: Var/decl_var_3 RawComment=none BriefComment=none DocCommentAsXML=none
90100
// SECOND: Inputs/def_comments.swift:28:25: Var/decl_var_3 RawComment=none BriefComment=none DocCommentAsXML=none
101+
// SECOND: Inputs/def_comments.swift:31:14: Func/second_package_function RawComment=[/// Comment on package function\n]
102+
// SECOND: Inputs/def_comments.swift:34:27: Func/second_spi_function RawComment=[/// Comment on SPI function\n]
91103
// SECOND: NonExistingSource.swift:100000:13: Func/functionAfterPoundSourceLoc
92104

105+
// Package and SPI functions won't show up in the (public) swiftinterface
106+
// INTERFACE: comments.swift:26:14: Class/first_decl_generic_class_1 RawComment=[/// first_decl_generic_class_1 Aaa.\n]
107+
// INTERFACE: comments.swift:28:3: Destructor/first_decl_generic_class_1.deinit RawComment=[/// deinit of first_decl_generic_class_1 Aaa.\n]
108+
// INTERFACE: comments.swift:33:14: Class/first_decl_class_1 RawComment=[/// first_decl_class_1 Aaa.\n]
109+
// INTERFACE: comments.swift:36:15: Func/first_decl_class_1.decl_func_1 RawComment=[/// decl_func_1 Aaa.\n]
110+
// INTERFACE: comments.swift:41:15: Func/first_decl_class_1.decl_func_2 RawComment=[/**\n * decl_func_3 Aaa.\n */]
111+
// INTERFACE: comments.swift:45:15: Func/first_decl_class_1.decl_func_3 RawComment=[/// decl_func_3 Aaa.\n/** Bbb. */]
112+
93113
// Test the case when we have to import via a .swiftinterface file.
94114
//
95115
// RUN: %empty-directory(%t)
96116
// RUN: %empty-directory(%t/Hidden)
97-
// RUN: %target-swift-frontend -module-name comments -emit-module -emit-module-path %t/Hidden/comments.swiftmodule -emit-module-interface-path %t/comments.swiftinterface -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -emit-module-source-info-path %t/comments.swiftsourceinfo %s -enable-library-evolution -swift-version 5
117+
// RUN: %target-swift-frontend -module-name comments -package-name comments -emit-module -emit-module-path %t/Hidden/comments.swiftmodule -emit-module-interface-path %t/comments.swiftinterface -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -emit-module-source-info-path %t/comments.swiftsourceinfo %s -enable-library-evolution -swift-version 5
98118
// RUN: llvm-bcanalyzer %t/comments.swiftdoc | %FileCheck %s -check-prefix=BCANALYZER
99119
// RUN: llvm-bcanalyzer %t/comments.swiftsourceinfo | %FileCheck %s -check-prefix=BCANALYZER
100-
// RUN: %target-swift-ide-test -print-module-comments -module-to-print=comments -enable-swiftsourceinfo -source-filename %s -I %t -swift-version 5 | %FileCheck %s -check-prefix=FIRST
120+
// RUN: %target-swift-ide-test -print-module-comments -module-to-print=comments -enable-swiftsourceinfo -source-filename %s -I %t -swift-version 5 | %FileCheck %s -check-prefix=INTERFACE
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/Modules)
3+
// RUN: split-file %s %t
4+
5+
// RUN: %target-swift-frontend \
6+
// RUN: -emit-module \
7+
// RUN: -module-name DocBriefTest \
8+
// RUN: -package-name DocPackage \
9+
// RUN: -emit-module-path %t/Modules/DocBriefTest.swiftmodule \
10+
// RUN: -emit-module-source-info-path %t/Modules/DocBriefTest.swiftsourceinfo \
11+
// RUN: %t/Module.swift
12+
13+
//--- Module.swift
14+
package protocol P {
15+
/// This is a doc comment of P.foo
16+
///
17+
/// Do whatever.
18+
func foo()
19+
}
20+
21+
package struct S: P {
22+
public init() {}
23+
public func foo() {}
24+
}
25+
26+
//--- User.swift
27+
package import DocBriefTest
28+
29+
func test() {
30+
S().foo()
31+
}
32+
33+
// RUN: %sourcekitd-test -req=complete -pos=4:7 %t/User.swift -- %t/User.swift -I %t/Modules -target %target-triple -module-name DocBriefUser -package-name DocPackage -enable-experimental-feature AccessLevelOnImport | %FileCheck %s -check-prefix=CHECK
34+
35+
// CHECK: {
36+
// CHECK: key.results: [
37+
// CHECK-NEXT: {
38+
// CHECK-NEXT: key.kind: source.lang.swift.decl.function.method.instance,
39+
// CHECK-NEXT: key.name: "foo()",
40+
// CHECK-NEXT: key.sourcetext: "foo()",
41+
// CHECK-NEXT: key.description: "foo()",
42+
// CHECK-NEXT: key.typename: "Void",
43+
// CHECK-NEXT: key.doc.brief: "This is a doc comment of P.foo",
44+
// CHECK: }
45+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/Modules)
3+
// RUN: split-file %s %t
4+
5+
// RUN: %target-swift-frontend \
6+
// RUN: -emit-module \
7+
// RUN: -module-name DocBriefTest \
8+
// RUN: -emit-module-path %t/Modules/DocBriefTest.swiftmodule \
9+
// RUN: -emit-module-source-info-path %t/Modules/DocBriefTest.swiftsourceinfo \
10+
// RUN: %t/Module.swift
11+
12+
//--- Module.swift
13+
@_spi(SomeSPI)
14+
public protocol P {
15+
/// This is a doc comment of P.foo
16+
///
17+
/// Do whatever.
18+
func foo()
19+
}
20+
21+
@_spi(SomeSPI)
22+
public struct S: P {
23+
public init() {}
24+
public func foo() {}
25+
}
26+
27+
//--- User.swift
28+
@_spi(SomeSPI) import DocBriefTest
29+
30+
func test() {
31+
S().foo()
32+
}
33+
34+
// RUN: %sourcekitd-test -req=complete -pos=4:7 %t/User.swift -- %t/User.swift -I %t/Modules -target %target-triple -module-name DocBriefUser | %FileCheck %s -check-prefix=CHECK
35+
36+
// CHECK: {
37+
// CHECK: key.results: [
38+
// CHECK-NEXT: {
39+
// CHECK-NEXT: key.kind: source.lang.swift.decl.function.method.instance,
40+
// CHECK-NEXT: key.name: "foo()",
41+
// CHECK-NEXT: key.sourcetext: "foo()",
42+
// CHECK-NEXT: key.description: "foo()",
43+
// CHECK-NEXT: key.typename: "Void",
44+
// CHECK-NEXT: key.doc.brief: "This is a doc comment of P.foo",
45+
// CHECK: }

0 commit comments

Comments
 (0)