mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ModuleInterface] Filter using access control and @usableFromInline (#18521)
These are the parts of a (resilient) module that affect the public interface and ABI; everything else is uninteresting. Or at least ought to be.
This commit is contained in:
@@ -71,7 +71,24 @@ PrintOptions PrintOptions::printTextualInterfaceFile() {
|
||||
result.PrintIfConfig = false;
|
||||
result.FullyQualifiedTypes = true;
|
||||
result.SkipImports = true;
|
||||
result.AccessFilter = AccessLevel::Public;
|
||||
|
||||
class UsableFromInlineOnly : public ShouldPrintChecker {
|
||||
bool shouldPrint(const Decl *D, PrintOptions &options) override {
|
||||
if (auto *VD = dyn_cast<ValueDecl>(D)) {
|
||||
AccessScope accessScope =
|
||||
VD->getFormalAccessScope(/*useDC*/nullptr,
|
||||
/*treatUsableFromInlineAsPublic*/true);
|
||||
if (!accessScope.isPublic())
|
||||
return false;
|
||||
}
|
||||
return ShouldPrintChecker::shouldPrint(D, options);
|
||||
}
|
||||
};
|
||||
result.CurrentPrintabilityChecker = std::make_shared<UsableFromInlineOnly>();
|
||||
|
||||
// FIXME: We don't really need 'public' on everything; we could just change
|
||||
// the default to 'public' and mark the 'internal' things.
|
||||
result.PrintAccess = true;
|
||||
|
||||
// FIXME: We'll need the actual default parameter expression.
|
||||
result.PrintDefaultParameterPlaceholder = false;
|
||||
|
||||
99
test/ModuleInterface/access-filter.swift
Normal file
99
test/ModuleInterface/access-filter.swift
Normal file
@@ -0,0 +1,99 @@
|
||||
// RUN: %target-swift-frontend -emit-interface-path %t.swiftinterface -emit-module -o /dev/null %s
|
||||
// RUN: %FileCheck %s < %t.swiftinterface
|
||||
// RUN: %FileCheck -check-prefix NEGATIVE %s < %t.swiftinterface
|
||||
|
||||
// NEGATIVE-NOT: BAD
|
||||
|
||||
// CHECK: public func publicFn(){{$}}
|
||||
public func publicFn() {}
|
||||
internal func internalFn_BAD() {}
|
||||
private func privateFn_BAD() {}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal func ufiFn(){{$}}
|
||||
@usableFromInline internal func ufiFn() {}
|
||||
|
||||
|
||||
// CHECK: public struct PublicStruct {{[{]$}}
|
||||
public struct PublicStruct {
|
||||
// CHECK: public func publicMethod(){{$}}
|
||||
public func publicMethod() {}
|
||||
internal func internalMethod_BAD() {}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal func ufiMethod(){{$}}
|
||||
@usableFromInline internal func ufiMethod() {}
|
||||
} // CHECK: {{^[}]$}}
|
||||
|
||||
internal struct InternalStruct_BAD {
|
||||
public func publicMethod_BAD() {}
|
||||
internal func internalMethod_BAD() {}
|
||||
@usableFromInline internal func ufiMethod_BAD() {}
|
||||
}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal struct UFIStruct {{[{]$}}
|
||||
@usableFromInline
|
||||
internal struct UFIStruct {
|
||||
// FIXME: Arguably this should be downgraded to "@usableFromInline internal".
|
||||
// CHECK: public func publicMethod(){{$}}
|
||||
public func publicMethod() {}
|
||||
internal func internalMethod_BAD() {}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal func ufiMethod(){{$}}
|
||||
@usableFromInline internal func ufiMethod() {}
|
||||
} // CHECK: {{^[}]$}}
|
||||
|
||||
// CHECK: public protocol PublicProto {{[{]$}}
|
||||
public protocol PublicProto {
|
||||
} // CHECK: {{^[}]$}}
|
||||
|
||||
// CHECK: extension PublicProto {{[{]$}}
|
||||
extension PublicProto {
|
||||
// CHECK: public func publicMethod(){{$}}
|
||||
public func publicMethod() {}
|
||||
internal func internalMethod_BAD() {}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal func ufiMethod(){{$}}
|
||||
@usableFromInline internal func ufiMethod() {}
|
||||
} // CHECK: {{^[}]$}}
|
||||
|
||||
// FIXME: We shouldn't print access on extensions in textual interface files.
|
||||
// CHECK: {{^}}public extension PublicProto {{[{]$}}
|
||||
public extension PublicProto {
|
||||
// CHECK: public func publicExtPublicMethod(){{$}}
|
||||
func publicExtPublicMethod() {}
|
||||
internal func publicExtInternalMethod_BAD() {}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal func publicExtUFIMethod(){{$}}
|
||||
@usableFromInline internal func publicExtUFIMethod() {}
|
||||
}
|
||||
|
||||
internal protocol InternalProto_BAD {
|
||||
}
|
||||
|
||||
extension InternalProto_BAD {
|
||||
public func publicMethod_BAD() {}
|
||||
internal func internalMethod_BAD() {}
|
||||
@usableFromInline internal func ufiMethod_BAD() {}
|
||||
}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal protocol UFIProto {{[{]$}}
|
||||
@usableFromInline
|
||||
internal protocol UFIProto {
|
||||
} // CHECK: {{^[}]$}}
|
||||
|
||||
// CHECK: extension UFIProto {{[{]$}}
|
||||
extension UFIProto {
|
||||
// CHECK: public func publicMethod(){{$}}
|
||||
public func publicMethod() {}
|
||||
internal func internalMethod_BAD() {}
|
||||
|
||||
// CHECK: @usableFromInline
|
||||
// CHECK-NEXT: internal func ufiMethod(){{$}}
|
||||
@usableFromInline internal func ufiMethod() {}
|
||||
} // CHECK: {{^[}]$}}
|
||||
@@ -3,7 +3,7 @@
|
||||
// RUN: %target-swift-frontend -emit-module -o %t/other~partial.swiftmodule %s -primary-file %S/Inputs/other.swift -module-name main
|
||||
// RUN: %target-swift-frontend -merge-modules -emit-module -o /dev/null -emit-interface-path - %t/main~partial.swiftmodule -module-name main %t/other~partial.swiftmodule | %FileCheck %s
|
||||
|
||||
// CHECK: {{^}}func verySimpleFunction(){{$}}
|
||||
// CHECK: {{^}}public func verySimpleFunction(){{$}}
|
||||
public func verySimpleFunction() {}
|
||||
|
||||
// CHECK: {{^}}func otherFileFunction(){{$}}
|
||||
// CHECK: {{^}}public func otherFileFunction(){{$}}
|
||||
|
||||
Reference in New Issue
Block a user