Skip to content

Commit 912285b

Browse files
authored
Merge pull request #41606 from rintaro/sourcekit-ifacegen-rdar79927502
[SourceKit] Print custom attributes in interface-gen requests
2 parents 04db521 + a185d21 commit 912285b

File tree

12 files changed

+160
-25
lines changed

12 files changed

+160
-25
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly,
494494
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
495495
84)
496496
DECL_ATTR(_custom, Custom,
497-
OnAnyDecl | UserInaccessible |
497+
OnAnyDecl | RejectByParser |
498498
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
499499
85)
500500
SIMPLE_DECL_ATTR(propertyWrapper, PropertyWrapper,

lib/AST/Attr.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -685,17 +685,11 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
685685
AttributeVector attributes;
686686
AttributeVector modifiers;
687687

688-
CustomAttr *FuncBuilderAttr = nullptr;
689-
if (auto *VD = dyn_cast_or_null<ValueDecl>(D)) {
690-
FuncBuilderAttr = VD->getAttachedResultBuilder();
691-
}
692688
for (auto DA : llvm::reverse(FlattenedAttrs)) {
693689
// Always print result builder attribute.
694-
bool isResultBuilderAttr = DA == FuncBuilderAttr;
695690
if (!Options.PrintImplicitAttrs && DA->isImplicit())
696691
continue;
697692
if (!Options.PrintUserInaccessibleAttrs &&
698-
!isResultBuilderAttr &&
699693
DeclAttribute::isUserInaccessible(DA->getKind()))
700694
continue;
701695
if (Options.excludeAttrKind(DA->getKind()))
@@ -851,6 +845,18 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
851845
break;
852846
}
853847
case DAK_Custom: {
848+
849+
auto attr = cast<CustomAttr>(this);
850+
if (auto type = attr->getType()) {
851+
// Print custom attributes only if the attribute decl is accessible.
852+
// FIXME: rdar://85477478 They should be rejected.
853+
if (auto attrDecl = type->getNominalOrBoundGenericNominal()) {
854+
if (attrDecl->getFormalAccess() < Options.AccessFilter) {
855+
return false;
856+
}
857+
}
858+
}
859+
854860
if (!Options.IsForSwiftInterface)
855861
break;
856862
// For Swift interface, we should print result builder attributes

test/IDE/print_clang_objc_effectful_properties.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232
// CHECK-NEXT: var fromNullableHandler: String { get async }
3333

3434
// CHECK: @available(*, renamed: "getter:mainDogProp()")
35-
// CHECK-NEXT: func getMainDog(_ completion: @escaping @Sendable (String) -> Void)
35+
// CHECK-NEXT: func getMainDog(_ completion: @escaping @MainActor (String) -> Void)
3636
// CHECK-NEXT: var mainDogProp: String { get async }
3737

3838
// CHECK: @available(*, renamed: "regularMainDog()")
39-
// CHECK-NEXT: func regularMainDog(_ completion: @escaping @Sendable (String) -> Void)
39+
// CHECK-NEXT: func regularMainDog(_ completion: @escaping @MainActor (String) -> Void)
4040
// CHECK-NEXT: @discardableResult
4141
// CHECK-NEXT: func regularMainDog() async -> String
4242
// CHECK: }

test/IDE/print_swift_module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public func returnsAlias() -> Alias<Int> {
2828
}
2929

3030
@resultBuilder
31-
struct BridgeBuilder {
31+
public struct BridgeBuilder {
3232
static func buildBlock(_: Any...) {}
3333
}
3434

test/SourceKit/Inputs/concurrency/gen_concurrency.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ class ClassWithAsyncAndHandler {
22
@available(*, renamed: "foo(_:)")
33
func foo(_ operation: String, completionHandler handler: @escaping (Int) -> Void) {}
44
func foo(_ operation: String) async -> Int { 0 }
5+
6+
@MainActor
7+
func mainActorMethod() {}
58
}

test/SourceKit/Inputs/concurrency/header_concurrency.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
@interface ClassWithHandlerMethod
44
-(void)methodWithHandler:(NSString *)operation completionHandler:(void (^)(NSInteger))handler;
5+
6+
-(void)mainActorMethod __attribute__((__swift_attr__("@UIActor")));
57
@end
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// REQUIRES: concurrency
2+
3+
// RUN: %empty-directory(%t)
4+
5+
// RUN: %sourcekitd-test -req=interface-gen %s -- %s -target %target-triple -module-name MyModule | %FileCheck %s --check-prefix=SWIFTSOURCE
6+
7+
// RUN: %target-swift-frontend -emit-module -module-name MyModule -o %t/MyModule.swiftmodule %s
8+
// RUN: %sourcekitd-test -req=interface-gen -module MyModule -- -target %target-triple -I %t | %FileCheck %s --check-prefix=SWIFTMODULE
9+
// RUN: %sourcekitd-test -req=doc-info -module MyModule -- -target %target-triple -I %t | %FileCheck %s --check-prefix=DOCINFO
10+
11+
@available(SwiftStdlib 5.1, *)
12+
@globalActor
13+
public struct PublicActor {
14+
public actor MyActor { }
15+
public static let shared = MyActor()
16+
}
17+
18+
@available(SwiftStdlib 5.1, *)
19+
@globalActor
20+
struct InternalActor {
21+
actor MyActor { }
22+
static let shared = MyActor()
23+
}
24+
25+
@propertyWrapper
26+
public struct PublicOrLess {
27+
private var threshold: Int
28+
private var number: Int = 0
29+
30+
public init(wrappedValue: Int, threshold: Int) {
31+
self.threshold = threshold
32+
self.wrappedValue = wrappedValue
33+
}
34+
public var wrappedValue: Int {
35+
get { return number }
36+
set { number = min(newValue, 12) }
37+
}
38+
}
39+
40+
@propertyWrapper
41+
struct InternalOrLess {
42+
private var threshold: Int
43+
private var number: Int = 0
44+
45+
init(wrappedValue: Int, threshold: Int) {
46+
self.threshold = threshold
47+
self.wrappedValue = wrappedValue
48+
}
49+
var wrappedValue: Int {
50+
get { return number }
51+
set { number = min(newValue, 12) }
52+
}
53+
}
54+
55+
@resultBuilder
56+
public struct PublicBuilder {
57+
public static func buildBlock(_ val: Int) -> Int { val }
58+
}
59+
60+
@resultBuilder
61+
struct InternalBuilder {
62+
static func buildBlock(_ val: Int) -> Int { val }
63+
}
64+
65+
66+
public struct TestStruct {
67+
68+
@MainActor public func mainActorMethod() {}
69+
@MainActor(unsafe) public func mainActorUnsafeMethod() {}
70+
71+
@available(SwiftStdlib 5.1, *)
72+
@PublicActor public func publicActorMethod() {}
73+
@available(SwiftStdlib 5.1, *)
74+
@InternalActor public func internalActorMethod() {}
75+
76+
@PublicOrLess(threshold: 12) public var publicOrLess = 13
77+
@InternalOrLess(threshold: 42) public var internalOrLess = 56
78+
79+
@PublicBuilder public var publicBuilderVal: Int { 1 }
80+
@InternalBuilder public var internalBuilderVal: Int { 1 }
81+
}
82+
83+
// SWIFTSOURCE: public struct TestStruct {
84+
// SWIFTSOURCE: @MainActor public func mainActorMethod()
85+
// SWIFTSOURCE: @MainActor public func mainActorUnsafeMethod()
86+
// SWIFTSOURCE: @MyModule.PublicActor public func publicActorMethod()
87+
// SWIFTSOURCE: @MyModule.InternalActor public func internalActorMethod()
88+
// SWIFTSOURCE: @MyModule.PublicOrLess public var publicOrLess: Int { get set }
89+
// SWIFTSOURCE: @MyModule.InternalOrLess public var internalOrLess: Int { get set }
90+
// SWIFTSOURCE: @MyModule.PublicBuilder public var publicBuilderVal: Int { get }
91+
// SWIFTSOURCE: @MyModule.InternalBuilder public var internalBuilderVal: Int { get }
92+
// SWIFTSOURCE: }
93+
94+
// SWIFTMODULE: public struct TestStruct {
95+
// SWIFTMODULE: @MainActor public func mainActorMethod()
96+
// SWIFTMODULE: @MainActor public func mainActorUnsafeMethod()
97+
// SWIFTMODULE: @MyModule.PublicActor public func publicActorMethod()
98+
// SWIFTMODULE: public func internalActorMethod()
99+
// SWIFTMODULE: @MyModule.PublicOrLess public var publicOrLess: Int
100+
// SWIFTMODULE: public var internalOrLess: Int
101+
// SWIFTMODULE: @MyModule.PublicBuilder public var publicBuilderVal: Int { get }
102+
// SWIFTMODULE: public var internalBuilderVal: Int { get }
103+
// SWIFTMODULE: }
104+
105+
// DOCINFO: struct TestStruct {
106+
// DOCINFO: @MainActor func mainActorMethod()
107+
// DOCINFO: @MainActor func mainActorUnsafeMethod()
108+
// DOCINFO: @MyModule.PublicActor func publicActorMethod()
109+
// DOCINFO: func internalActorMethod()
110+
// DOCINFO: @MyModule.PublicOrLess var publicOrLess: Int
111+
// DOCINFO: var internalOrLess: Int
112+
// DOCINFO: @MyModule.PublicBuilder var publicBuilderVal: Int { get }
113+
// DOCINFO: var internalBuilderVal: Int { get }
114+
// DOCINFO: }

test/SourceKit/InterfaceGen/gen_objc_concurrency.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@
1111
// SWIFT-GEN-INTERFACE-NEXT: internal func foo(_ operation: String, completionHandler handler: @escaping (Int) -> Void)
1212
// SWIFT-GEN-INTERFACE: internal func foo(_ operation: String) async -> Int
1313

14+
// SWIFT-GEN-INTERFACE: @MainActor internal func mainActorMethod()
15+
16+
1417
// RUN: %sourcekitd-test -req=interface-gen -using-swift-args -header %S/../Inputs/concurrency/header_concurrency.h -- %s -Xfrontend -enable-objc-interop -import-objc-header %S/../Inputs/concurrency/header_concurrency.h -sdk %clang-importer-sdk | %FileCheck %s --check-prefix=OBJC-GEN-INTERFACE
1518

1619
// But don't print @available if it was implicitly added to an imported Clang decl (rdar://76685011).
1720
// OBJC-GEN-INTERFACE-LABEL: class ClassWithHandlerMethod {
1821
// OBJC-GEN-INTERFACE-NOT: @available
1922
// OBJC-GEN-INTERFACE: func method(withHandler operation: String!, completionHandler handler: (@Sendable (Int) -> Void)!)
2023
// OBJC-GEN-INTERFACE: func method(withHandler operation: String!) async -> Int
24+
25+
// OBJC-GEN-INTERFACE: @MainActor open func mainActorMethod()

test/attr/attributes.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,5 @@ enum E1 {
342342

343343
func foo() -> @_nonEphemeral UnsafeMutableRawPointer? { return nil } // expected-error {{attribute can only be applied to declarations, not types}}
344344
}
345+
346+
@_custom func testCustomAttribute() {} // expected-error {{unknown attribute '_custom'}}

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,12 @@ static bool reportModuleDocInfo(CompilerInvocation Invocation,
10861086
ASTContext &Ctx = CI.getASTContext();
10871087
registerIDERequestFunctions(Ctx.evaluator);
10881088

1089+
// Load implict imports so that Clang importer can use it.
1090+
for (auto unloadedImport :
1091+
CI.getMainModule()->getImplicitImportInfo().AdditionalUnloadedImports) {
1092+
(void)Ctx.getModule(unloadedImport.module.getModulePath());
1093+
}
1094+
10891095
SourceTextInfo IFaceInfo;
10901096
if (getModuleInterfaceInfo(Ctx, ModuleName, IFaceInfo))
10911097
return true;

tools/SourceKit/lib/SwiftLang/SwiftEditorInterfaceGen.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,10 @@ SwiftInterfaceGenContext::create(StringRef DocumentName,
381381
ASTContext &Ctx = CI.getASTContext();
382382
CloseClangModuleFiles scopedCloseFiles(*Ctx.getClangModuleLoader());
383383

384-
// Load standard library so that Clang importer can use it.
385-
auto *Stdlib = Ctx.getModuleByIdentifier(Ctx.StdlibModuleName);
386-
if (!Stdlib) {
387-
ErrMsg = "Could not load the stdlib module";
388-
return nullptr;
384+
// Load implict imports so that Clang importer can use them.
385+
for (auto unloadedImport :
386+
CI.getMainModule()->getImplicitImportInfo().AdditionalUnloadedImports) {
387+
(void)Ctx.getModule(unloadedImport.module.getModulePath());
389388
}
390389

391390
if (IsModule) {

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,11 +2960,10 @@ static int doPrintModules(const CompilerInvocation &InitInvok,
29602960
registerIDERequestFunctions(CI.getASTContext().evaluator);
29612961
auto &Context = CI.getASTContext();
29622962

2963-
// Load standard library so that Clang importer can use it.
2964-
auto *Stdlib = getModuleByFullName(Context, Context.StdlibModuleName);
2965-
if (!Stdlib) {
2966-
llvm::errs() << "Failed loading stdlib\n";
2967-
return 1;
2963+
// Load implict imports so that Clang importer can use it.
2964+
for (auto unloadedImport :
2965+
CI.getMainModule()->getImplicitImportInfo().AdditionalUnloadedImports) {
2966+
(void)Context.getModule(unloadedImport.module.getModulePath());
29682967
}
29692968

29702969
// If needed, load _Concurrency library so that the Clang importer can use it.
@@ -3028,11 +3027,10 @@ static int doPrintHeaders(const CompilerInvocation &InitInvok,
30283027
registerIDERequestFunctions(CI.getASTContext().evaluator);
30293028
auto &Context = CI.getASTContext();
30303029

3031-
// Load standard library so that Clang importer can use it.
3032-
auto *Stdlib = getModuleByFullName(Context, Context.StdlibModuleName);
3033-
if (!Stdlib) {
3034-
llvm::errs() << "Failed loading stdlib\n";
3035-
return 1;
3030+
// Load implict imports so that Clang importer can use it.
3031+
for (auto unloadedImport :
3032+
CI.getMainModule()->getImplicitImportInfo().AdditionalUnloadedImports) {
3033+
(void)Context.getModule(unloadedImport.module.getModulePath());
30363034
}
30373035

30383036
auto &FEOpts = Invocation.getFrontendOptions();

0 commit comments

Comments
 (0)