Default access for many synthesized members to 'internal'.

More detail: some members are intended to have the same the access as
their containing types. This doesn't fly for SE-0025 'private', which
would limit the members to only being accessed from lexically within
the type decl, instead anywhere the type itself can be seen. Instead,
follow the rule for user-written members---internal by default---and
then raise the access level to 'public' if necessary. This affects:

- enum cases
- deinitializers
- protocol requirements
- generic parameters
- implicit initializers
- inherited initializers
- derived conformance members
- synthesized typealiases for associated types
This commit is contained in:
Jordan Rose
2016-07-25 17:52:21 -07:00
parent a965e22ae4
commit c70a5a5d67
10 changed files with 93 additions and 46 deletions

View File

@@ -1917,9 +1917,9 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
ImplicitConstructorKind ICK) {
ASTContext &context = tc.Context;
SourceLoc Loc = decl->getLoc();
Accessibility accessLevel = decl->getFormalAccess();
if (!decl->hasClangNode())
accessLevel = std::min(accessLevel, Accessibility::Internal);
auto accessLevel = Accessibility::Internal;
if (decl->hasClangNode())
accessLevel = std::max(accessLevel, decl->getFormalAccess());
// Determine the parameter type of the implicit constructor.
SmallVector<ParamDecl*, 8> params;
@@ -2114,8 +2114,11 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
/*GenericParams=*/nullptr, classDecl);
ctor->setImplicit();
ctor->setAccessibility(std::min(classDecl->getFormalAccess(),
superclassCtor->getFormalAccess()));
Accessibility access = classDecl->getFormalAccess();
access = std::max(access, Accessibility::Internal);
access = std::min(access, superclassCtor->getFormalAccess());
ctor->setAccessibility(access);
// Make sure the constructor is only as available as its superclass's
// constructor.

View File

@@ -417,7 +417,8 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
interfaceType = FunctionType::get(selfType, methodType);
getterDecl->setInterfaceType(interfaceType);
getterDecl->setAccessibility(enumDecl->getFormalAccess());
getterDecl->setAccessibility(std::max(Accessibility::Internal,
enumDecl->getFormalAccess()));
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
@@ -433,7 +434,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
hashValueDecl->setImplicit();
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
nullptr, nullptr, SourceLoc());
hashValueDecl->setAccessibility(enumDecl->getFormalAccess());
hashValueDecl->setAccessibility(getterDecl->getFormalAccess());
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
hashValuePat->setType(intType);

View File

@@ -336,7 +336,8 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
}
initDecl->setInterfaceType(allocIfaceType);
initDecl->setInitializerInterfaceType(initIfaceType);
initDecl->setAccessibility(enumDecl->getFormalAccess());
initDecl->setAccessibility(std::max(Accessibility::Internal,
enumDecl->getFormalAccess()));
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration

View File

@@ -151,7 +151,8 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
} else
interfaceType = type;
getterDecl->setInterfaceType(interfaceType);
getterDecl->setAccessibility(typeDecl->getFormalAccess());
getterDecl->setAccessibility(std::max(typeDecl->getFormalAccess(),
Accessibility::Internal));
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
@@ -181,7 +182,7 @@ DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc,
propDecl->setImplicit();
propDecl->makeComputed(SourceLoc(), getterDecl, nullptr, nullptr,
SourceLoc());
propDecl->setAccessibility(typeDecl->getFormalAccess());
propDecl->setAccessibility(getterDecl->getFormalAccess());
propDecl->setInterfaceType(propertyInterfaceType);
Pattern *propPat = new (C) NamedPattern(propDecl, /*implicit*/ true);

View File

@@ -1371,7 +1371,7 @@ void TypeChecker::computeAccessibility(ValueDecl *D) {
validateAccessibility(generic);
Accessibility access = Accessibility::Internal;
if (isa<ProtocolDecl>(generic))
access = generic->getFormalAccess();
access = std::max(access, generic->getFormalAccess());
D->setAccessibility(access);
break;
}
@@ -3522,9 +3522,7 @@ public:
assocType->setIsBeingTypeChecked();
TC.checkDeclAttributesEarly(assocType);
if (!assocType->hasAccessibility())
assocType->setAccessibility(assocType->getProtocol()->getFormalAccess());
TC.validateAccessibility(assocType);
TC.checkInheritanceClause(assocType);
// Check the default definition, if there is one.
@@ -5785,12 +5783,7 @@ public:
TC.checkDeclAttributesEarly(EED);
EnumDecl *ED = EED->getParentEnum();
if (!EED->hasAccessibility())
EED->setAccessibility(ED->getFormalAccess());
TC.validateAccessibility(EED);
EED->setIsBeingTypeChecked();
// Only attempt to validate the argument type or raw value if the element
@@ -5811,6 +5804,7 @@ public:
// If we have a raw value, make sure there's a raw type as well.
if (auto *rawValue = EED->getRawValueExpr()) {
EnumDecl *ED = EED->getParentEnum();
if (!ED->hasRawType()) {
TC.diagnose(rawValue->getLoc(),diag::enum_raw_value_without_raw_type);
// Recover by setting the raw type as this element's type.
@@ -6522,7 +6516,8 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
if (!assocType->hasType())
assocType->computeType();
if (!typeParam->hasAccessibility())
typeParam->setAccessibility(nominal->getFormalAccess());
typeParam->setAccessibility(std::max(nominal->getFormalAccess(),
Accessibility::Internal));
break;
}
@@ -6543,7 +6538,8 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
if (!assocType->hasType())
assocType->computeType();
if (!typeParam->hasAccessibility())
typeParam->setAccessibility(fn->getFormalAccess());
typeParam->setAccessibility(std::max(fn->getFormalAccess(),
Accessibility::Internal));
break;
}
}
@@ -6905,7 +6901,8 @@ void TypeChecker::validateAccessibility(ValueDecl *D) {
auto assocType = cast<AssociatedTypeDecl>(D);
auto prot = assocType->getProtocol();
validateAccessibility(prot);
assocType->setAccessibility(prot->getFormalAccess());
assocType->setAccessibility(std::max(prot->getFormalAccess(),
Accessibility::Internal));
break;
}
@@ -6928,7 +6925,8 @@ void TypeChecker::validateAccessibility(ValueDecl *D) {
} else {
auto container = cast<NominalTypeDecl>(D->getDeclContext());
validateAccessibility(container);
D->setAccessibility(container->getFormalAccess());
D->setAccessibility(std::max(container->getFormalAccess(),
Accessibility::Internal));
}
break;
}

View File

@@ -801,6 +801,7 @@ void TypeChecker::finalizeGenericParamList(ArchetypeBuilder &builder,
access = nominal->getFormalAccess();
else
access = Accessibility::Internal;
access = std::max(access, Accessibility::Internal);
// Wire up the archetypes.
for (auto GP : *genericParams) {

View File

@@ -1960,7 +1960,14 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
// Inject the typealias into the nominal decl that conforms to the protocol.
if (auto nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext()) {
TC.computeAccessibility(nominal);
aliasDecl->setAccessibility(nominal->getFormalAccess());
// FIXME: Ideally this would use the protocol's access too---that is,
// a typealias added for an internal protocol shouldn't need to be
// public---but that can be problematic if the same type conforms to two
// protocols with different access levels.
Accessibility aliasAccess = nominal->getFormalAccess();
aliasAccess = std::max(aliasAccess, Accessibility::Internal);
aliasDecl->setAccessibility(aliasAccess);
if (nominal == DC) {
nominal->addMember(aliasDecl);
} else {

View File

@@ -3036,7 +3036,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
elem->setInterfaceType(interfaceType);
if (isImplicit)
elem->setImplicit();
elem->setAccessibility(cast<EnumDecl>(DC)->getFormalAccess());
elem->setAccessibility(std::max(cast<EnumDecl>(DC)->getFormalAccess(),
Accessibility::Internal));
break;
}
@@ -3203,7 +3204,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
/*selfpat*/nullptr, DC);
declOrOffset = dtor;
dtor->setAccessibility(cast<ClassDecl>(DC)->getFormalAccess());
dtor->setAccessibility(std::max(cast<ClassDecl>(DC)->getFormalAccess(),
Accessibility::Internal));
auto *selfParams = readParameterList();
selfParams->get(0)->setImplicit(); // self is implicit.

View File

@@ -112,16 +112,16 @@ public class TestPublicABC : ProtocolAPrivate, ProtocolBInternal, ProtocolCPubli
// TEST_INTERNAL_ABC: Begin completions, 15 items
// TEST_INTERNAL_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolA: TagPA) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFunc(x: TagPA) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFunc(x: TagPA) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolB: TagPB) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFunc(x: TagPB) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFuncOptional(x: TagPB) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolC: TagPC) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoCFunc(x: TagPC) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoCFuncOptional(x: TagPC) {|}{{; name=.+$}}
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRW: TagPA
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRO: TagPA
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRW: TagPA
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRO: TagPA
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRW: TagPB
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRO: TagPB
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoCVarRW: TagPC
@@ -130,16 +130,16 @@ public class TestPublicABC : ProtocolAPrivate, ProtocolBInternal, ProtocolCPubli
// TEST_PUBLIC_ABC: Begin completions, 15 items
// TEST_PUBLIC_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolA: TagPA) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFunc(x: TagPA) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFunc(x: TagPA) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolB: TagPB) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFunc(x: TagPB) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFuncOptional(x: TagPB) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolC: TagPC) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: public func protoCFunc(x: TagPC) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: public func protoCFuncOptional(x: TagPC) {|}{{; name=.+$}}
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRW: TagPA
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRO: TagPA
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRW: TagPA
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRO: TagPA
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRW: TagPB
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRO: TagPB
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: public var protoCVarRW: TagPC

View File

@@ -29,8 +29,8 @@ struct BA_DefaultStruct {
private struct BB_PrivateStruct {
// CHECK: internal var x
var x = 0
// CHECK: private init(x: Int)
// CHECK: private init()
// CHECK: internal init(x: Int)
// CHECK: internal init()
} // CHECK: {{^[}]}}
// CHECK-LABEL: internal{{(\*/)?}} struct BC_InternalStruct {
@@ -60,8 +60,8 @@ public struct BE_PublicStructPrivateMembers {
fileprivate struct BF_FilePrivateStruct {
// CHECK: {{^}} internal var x
var x = 0
// CHECK: {{^}} fileprivate init(x: Int)
// CHECK: {{^}} fileprivate init()
// CHECK: {{^}} internal init(x: Int)
// CHECK: {{^}} internal init()
} // CHECK: {{^[}]}}
@@ -69,7 +69,7 @@ fileprivate struct BF_FilePrivateStruct {
private class CA_PrivateClass {
// CHECK: {{^}} deinit
deinit {}
// CHECK: private init()
// CHECK: internal init()
} // CHECK: {{^[}]}}
// CHECK-LABEL: internal{{(\*/)?}} class CB_InternalClass
@@ -94,7 +94,7 @@ private enum DA_PrivateEnum {
case Foo, Bar
// CHECK: internal init()
init() { self = .Foo }
// CHECK: private var hashValue
// CHECK: internal var hashValue
} // CHECK: {{^[}]}}
// CHECK-LABEL: internal{{(\*/)?}} enum DB_InternalEnum {
@@ -122,9 +122,9 @@ public enum DC_PublicEnum {
private protocol EA_PrivateProtocol {
// CHECK: {{^}} associatedtype Foo
associatedtype Foo
// CHECK: private var Bar
// CHECK: internal var Bar
var Bar: Int { get }
// CHECK: private func baz()
// CHECK: internal func baz()
func baz()
} // CHECK: {{^[}]}}
@@ -325,19 +325,52 @@ extension HC_PrivateProtocol where Assoc == HC_PrivateStruct {
func constrained() {}
} // CHECK: {{^[}]}}
public protocol IA_PublicAssocTypeProto {
associatedtype PublicValue
var publicValue: PublicValue { get }
}
fileprivate protocol IB_FilePrivateAssocTypeProto {
associatedtype FilePrivateValue
var filePrivateValue: FilePrivateValue { get }
}
// CHECK-LABEL: public{{(\*/)?}} class IC_PublicAssocTypeImpl : IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
public class IC_PublicAssocTypeImpl: IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
public var publicValue: Int = 0
public var filePrivateValue: Int = 0
// CHECK-DAG: {{^}} public typealias PublicValue
// CHECK-DAG: {{^}} public typealias FilePrivateValue
} // CHECK: {{^[}]}}
// CHECK-LABEL: private{{(\*/)?}} class ID_PrivateAssocTypeImpl : IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
private class ID_PrivateAssocTypeImpl: IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
public var publicValue: Int = 0
public var filePrivateValue: Int = 0
// CHECK-DAG: {{^}} internal typealias PublicValue
// CHECK-DAG: {{^}} internal typealias FilePrivateValue
} // CHECK: {{^[}]}}
// CHECK-LABEL: class MultipleAttributes {
class MultipleAttributes {
// CHECK: {{^}} final {{(/\*)?private(\*/)?}} func foo()
final private func foo() {}
}
} // CHECK: {{^[}]}}
// CHECK-LABEL: public{{(\*/)?}} class PublicInitBase {
public class PublicInitBase {
// CHECK: {{^}} {{(/\*)?public(\*/)?}} init()
public init() {}
}
// CHECK: {{^}} {{(/\*)?fileprivate(\*/)?}} init(other: PublicInitBase)
fileprivate init(other: PublicInitBase) {}
} // CHECK: {{^[}]}}
// CHECK-LABEL: public{{(\*/)?}} class PublicInitInheritor : PublicInitBase {
public class PublicInitInheritor : PublicInitBase {
// CHECK: {{^}} public init()
}
// CHECK: {{^}} fileprivate init(other: PublicInitBase)
} // CHECK: {{^[}]}}
// CHECK-LABEL: {{(/\*)?private(\*/)?}} class PublicInitPrivateInheritor : PublicInitBase {
private class PublicInitPrivateInheritor : PublicInitBase {
// CHECK: {{^}} internal init()
// CHECK: {{^}} fileprivate init(other: PublicInitBase)
} // CHECK: {{^[}]}}