[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:
Jordan Rose
2018-08-06 19:40:44 -07:00
committed by GitHub
parent 88d2feb44b
commit 59940b7f04
3 changed files with 119 additions and 3 deletions

View File

@@ -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;

View 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: {{^[}]$}}

View File

@@ -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(){{$}}