Skip to content

Commit c12d27b

Browse files
committed
[Sema] Hide the implementation of AccessScopeChecker
(and UsableFromInlineChecker) Preparation for the next commit's refactoring
1 parent 70ee6c2 commit c12d27b

File tree

3 files changed

+127
-134
lines changed

3 files changed

+127
-134
lines changed

lib/Sema/TypeCheckAccess.cpp

+104
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,76 @@ using namespace swift;
2929

3030
namespace {
3131

32+
/// A uniquely-typed boolean to reduce the chances of accidentally inverting
33+
/// a check.
34+
///
35+
/// \see checkTypeAccess
36+
enum class DowngradeToWarning: bool {
37+
No,
38+
Yes
39+
};
40+
41+
/// \see checkTypeAccess
42+
using CheckTypeAccessCallback =
43+
void(AccessScope, const TypeRepr *, DowngradeToWarning);
44+
45+
class AccessControlCheckerBase {
46+
protected:
47+
TypeChecker &TC;
48+
bool checkUsableFromInline;
49+
50+
void checkTypeAccessImpl(
51+
Type type, TypeRepr *typeRepr, AccessScope contextAccessScope,
52+
const DeclContext *useDC,
53+
llvm::function_ref<CheckTypeAccessCallback> diagnose);
54+
55+
void checkTypeAccess(
56+
Type type, TypeRepr *typeRepr, const ValueDecl *context,
57+
llvm::function_ref<CheckTypeAccessCallback> diagnose);
58+
59+
void checkTypeAccess(
60+
const TypeLoc &TL, const ValueDecl *context,
61+
llvm::function_ref<CheckTypeAccessCallback> diagnose) {
62+
return checkTypeAccess(TL.getType(), TL.getTypeRepr(), context, diagnose);
63+
}
64+
65+
void checkRequirementAccess(
66+
WhereClauseOwner source,
67+
AccessScope accessScope,
68+
const DeclContext *useDC,
69+
llvm::function_ref<CheckTypeAccessCallback> diagnose);
70+
71+
AccessControlCheckerBase(TypeChecker &TC, bool checkUsableFromInline)
72+
: TC(TC), checkUsableFromInline(checkUsableFromInline) {}
73+
74+
public:
75+
void checkGenericParamAccess(
76+
const GenericParamList *params,
77+
const Decl *owner,
78+
AccessScope accessScope,
79+
AccessLevel contextAccess);
80+
81+
void checkGenericParamAccess(
82+
const GenericParamList *params,
83+
const ValueDecl *owner);
84+
};
85+
86+
class AccessControlChecker : public AccessControlCheckerBase {
87+
public:
88+
explicit AccessControlChecker(TypeChecker &TC)
89+
: AccessControlCheckerBase(TC, /*checkUsableFromInline=*/false) {}
90+
91+
void check(Decl *D);
92+
};
93+
94+
class UsableFromInlineChecker : public AccessControlCheckerBase {
95+
public:
96+
explicit UsableFromInlineChecker(TypeChecker &TC)
97+
: AccessControlCheckerBase(TC, /*checkUsableFromInline=*/true) {}
98+
99+
void check(Decl *D);
100+
};
101+
32102
class TypeAccessScopeDiagnoser : private ASTWalker {
33103
AccessScope accessScope;
34104
const DeclContext *useDC;
@@ -1358,3 +1428,37 @@ void UsableFromInlineChecker::check(Decl *D) {
13581428
}
13591429
}
13601430
}
1431+
1432+
void swift::checkAccessControl(TypeChecker &TC, Decl *D) {
1433+
AccessControlChecker(TC).check(D);
1434+
UsableFromInlineChecker(TC).check(D);
1435+
}
1436+
1437+
void swift::checkExtensionGenericParamAccess(TypeChecker &TC,
1438+
const ExtensionDecl *ED,
1439+
AccessLevel userSpecifiedAccess) {
1440+
AccessScope desiredAccessScope = AccessScope::getPublic();
1441+
switch (userSpecifiedAccess) {
1442+
case AccessLevel::Private:
1443+
assert((ED->isInvalid() ||
1444+
ED->getDeclContext()->isModuleScopeContext()) &&
1445+
"non-top-level extensions make 'private' != 'fileprivate'");
1446+
LLVM_FALLTHROUGH;
1447+
case AccessLevel::FilePrivate: {
1448+
const DeclContext *DC = ED->getModuleScopeContext();
1449+
bool isPrivate = (userSpecifiedAccess == AccessLevel::Private);
1450+
desiredAccessScope = AccessScope(DC, isPrivate);
1451+
break;
1452+
}
1453+
case AccessLevel::Internal:
1454+
desiredAccessScope = AccessScope(ED->getModuleContext());
1455+
break;
1456+
case AccessLevel::Public:
1457+
case AccessLevel::Open:
1458+
break;
1459+
}
1460+
1461+
AccessControlChecker(TC).checkGenericParamAccess(ED->getGenericParams(), ED,
1462+
desiredAccessScope,
1463+
userSpecifiedAccess);
1464+
}

lib/Sema/TypeCheckAccess.h

+10-85
Original file line numberDiff line numberDiff line change
@@ -17,97 +17,22 @@
1717
#ifndef TYPECHECKACCESS_H
1818
#define TYPECHECKACCESS_H
1919

20-
#include "swift/AST/AccessScope.h"
21-
#include "swift/AST/TypeLoc.h"
22-
#include "llvm/ADT/STLExtras.h"
23-
2420
namespace swift {
2521

2622
class Decl;
27-
class DeclContext;
28-
class GenericParamList;
29-
class RequirementRepr;
3023
class TypeChecker;
31-
class ValueDecl;
32-
struct WhereClauseOwner;
3324

34-
/// A uniquely-typed boolean to reduce the chances of accidentally inverting
35-
/// a check.
25+
/// Checks the given declaration's signature does not reference any other
26+
/// declarations that are less visible than the declaration itself.
3627
///
37-
/// \see checkTypeAccess
38-
enum class DowngradeToWarning: bool {
39-
No,
40-
Yes
41-
};
42-
43-
/// \see checkTypeAccess
44-
using CheckTypeAccessCallback =
45-
void(AccessScope, const TypeRepr *, DowngradeToWarning);
46-
47-
class AccessControlCheckerBase {
48-
protected:
49-
TypeChecker &TC;
50-
bool checkUsableFromInline;
51-
52-
void checkTypeAccessImpl(
53-
Type type, TypeRepr *typeRepr, AccessScope contextAccessScope,
54-
const DeclContext *useDC,
55-
llvm::function_ref<CheckTypeAccessCallback> diagnose);
56-
57-
void checkTypeAccess(
58-
Type type, TypeRepr *typeRepr, const ValueDecl *context,
59-
llvm::function_ref<CheckTypeAccessCallback> diagnose);
60-
61-
void checkTypeAccess(
62-
const TypeLoc &TL, const ValueDecl *context,
63-
llvm::function_ref<CheckTypeAccessCallback> diagnose) {
64-
return checkTypeAccess(TL.getType(), TL.getTypeRepr(), context, diagnose);
65-
}
66-
67-
void checkRequirementAccess(
68-
WhereClauseOwner source,
69-
AccessScope accessScope,
70-
const DeclContext *useDC,
71-
llvm::function_ref<CheckTypeAccessCallback> diagnose);
72-
73-
AccessControlCheckerBase(TypeChecker &TC, bool checkUsableFromInline)
74-
: TC(TC), checkUsableFromInline(checkUsableFromInline) {}
75-
76-
public:
77-
void checkGenericParamAccess(
78-
const GenericParamList *params,
79-
const Decl *owner,
80-
AccessScope accessScope,
81-
AccessLevel contextAccess);
82-
83-
void checkGenericParamAccess(
84-
const GenericParamList *params,
85-
const ValueDecl *owner);
86-
};
87-
88-
class AccessControlChecker : public AccessControlCheckerBase {
89-
public:
90-
explicit AccessControlChecker(TypeChecker &TC)
91-
: AccessControlCheckerBase(TC, /*checkUsableFromInline=*/false) {}
92-
93-
void check(Decl *D);
94-
95-
static void checkAccessControl(TypeChecker &TC, Decl *D) {
96-
AccessControlChecker(TC).check(D);
97-
}
98-
};
99-
100-
class UsableFromInlineChecker : public AccessControlCheckerBase {
101-
public:
102-
explicit UsableFromInlineChecker(TypeChecker &TC)
103-
: AccessControlCheckerBase(TC, /*checkUsableFromInline=*/true) {}
104-
105-
void check(Decl *D);
106-
107-
static void checkUsableFromInline(TypeChecker &TC, Decl *D) {
108-
UsableFromInlineChecker(TC).check(D);
109-
}
110-
};
28+
/// \p D must be a ValueDecl or a Decl that can appear in a type context.
29+
void checkAccessControl(TypeChecker &TC, Decl *D);
30+
31+
/// Checks that the generic parameters of the given extension do not reference
32+
/// any other declarations that are less visible than the user-specified access
33+
/// on the extension.
34+
void checkExtensionGenericParamAccess(TypeChecker &TC, const ExtensionDecl *ED,
35+
AccessLevel userSpecifiedAccess);
11136

11237
} // end namespace swift
11338

lib/Sema/TypeCheckDecl.cpp

+13-49
Original file line numberDiff line numberDiff line change
@@ -2622,8 +2622,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
26222622

26232623
TC.checkDeclAttributes(PBD);
26242624

2625-
AccessControlChecker::checkAccessControl(TC, PBD);
2626-
UsableFromInlineChecker::checkUsableFromInline(TC, PBD);
2625+
checkAccessControl(TC, PBD);
26272626

26282627
// If the initializers in the PBD aren't checked yet, do so now.
26292628
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
@@ -2643,8 +2642,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
26432642

26442643
TC.checkDeclAttributes(SD);
26452644

2646-
AccessControlChecker::checkAccessControl(TC, SD);
2647-
UsableFromInlineChecker::checkUsableFromInline(TC, SD);
2645+
checkAccessControl(TC, SD);
26482646

26492647
if (!checkOverrides(SD)) {
26502648
// If a subscript has an override attribute but does not override
@@ -2667,8 +2665,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
26672665
TC.validateDecl(TAD);
26682666
TC.checkDeclAttributes(TAD);
26692667

2670-
AccessControlChecker::checkAccessControl(TC, TAD);
2671-
UsableFromInlineChecker::checkUsableFromInline(TC, TAD);
2668+
checkAccessControl(TC, TAD);
26722669
}
26732670

26742671
void visitAssociatedTypeDecl(AssociatedTypeDecl *AT) {
@@ -2689,8 +2686,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
26892686
proto->getName());
26902687
}
26912688

2692-
AccessControlChecker::checkAccessControl(TC, AT);
2693-
UsableFromInlineChecker::checkUsableFromInline(TC, AT);
2689+
checkAccessControl(TC, AT);
26942690

26952691
// Trigger the checking for overridden declarations.
26962692
(void)AT->getOverriddenDecls();
@@ -2763,8 +2759,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
27632759

27642760
checkInheritanceClause(ED);
27652761

2766-
AccessControlChecker::checkAccessControl(TC, ED);
2767-
UsableFromInlineChecker::checkUsableFromInline(TC, ED);
2762+
checkAccessControl(TC, ED);
27682763

27692764
if (ED->hasRawType() && !ED->isObjC()) {
27702765
// ObjC enums have already had their raw values checked, but pure Swift
@@ -2795,8 +2790,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
27952790

27962791
checkInheritanceClause(SD);
27972792

2798-
AccessControlChecker::checkAccessControl(TC, SD);
2799-
UsableFromInlineChecker::checkUsableFromInline(TC, SD);
2793+
checkAccessControl(TC, SD);
28002794

28012795
SD->getAllConformances();
28022796

@@ -3028,8 +3022,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
30283022

30293023
checkInheritanceClause(CD);
30303024

3031-
AccessControlChecker::checkAccessControl(TC, CD);
3032-
UsableFromInlineChecker::checkUsableFromInline(TC, CD);
3025+
checkAccessControl(TC, CD);
30333026

30343027
TC.checkDeclCircularity(CD);
30353028
TC.ConformanceContexts.push_back(CD);
@@ -3067,8 +3060,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
30673060

30683061
TC.checkDeclAttributes(PD);
30693062

3070-
AccessControlChecker::checkAccessControl(TC, PD);
3071-
UsableFromInlineChecker::checkUsableFromInline(TC, PD);
3063+
checkAccessControl(TC, PD);
30723064

30733065
checkInheritanceClause(PD);
30743066
checkProtocolSelfRequirements(PD, PD);
@@ -3158,8 +3150,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
31583150
TC.checkProtocolSelfRequirements(FD);
31593151
}
31603152

3161-
AccessControlChecker::checkAccessControl(TC, FD);
3162-
UsableFromInlineChecker::checkUsableFromInline(TC, FD);
3153+
checkAccessControl(TC, FD);
31633154

31643155
if (!checkOverrides(FD)) {
31653156
// If a method has an 'override' keyword but does not
@@ -3194,8 +3185,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
31943185
TC.validateDecl(EED);
31953186
TC.checkDeclAttributes(EED);
31963187

3197-
AccessControlChecker::checkAccessControl(TC, EED);
3198-
UsableFromInlineChecker::checkUsableFromInline(TC, EED);
3188+
checkAccessControl(TC, EED);
31993189
}
32003190

32013191
void visitExtensionDecl(ExtensionDecl *ED) {
@@ -3244,33 +3234,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
32443234
if (!ED->isInvalid())
32453235
TC.checkDeclAttributes(ED);
32463236

3247-
if (auto *AA = ED->getAttrs().getAttribute<AccessControlAttr>()) {
3248-
const auto access = AA->getAccess();
3249-
AccessScope desiredAccessScope = AccessScope::getPublic();
3250-
switch (access) {
3251-
case AccessLevel::Private:
3252-
assert((ED->isInvalid() ||
3253-
ED->getDeclContext()->isModuleScopeContext()) &&
3254-
"non-top-level extensions make 'private' != 'fileprivate'");
3255-
LLVM_FALLTHROUGH;
3256-
case AccessLevel::FilePrivate: {
3257-
const DeclContext *DC = ED->getModuleScopeContext();
3258-
bool isPrivate = access == AccessLevel::Private;
3259-
desiredAccessScope = AccessScope(DC, isPrivate);
3260-
break;
3261-
}
3262-
case AccessLevel::Internal:
3263-
desiredAccessScope = AccessScope(ED->getModuleContext());
3264-
break;
3265-
case AccessLevel::Public:
3266-
case AccessLevel::Open:
3267-
break;
3268-
}
3269-
3270-
AccessControlChecker ACC(TC);
3271-
ACC.checkGenericParamAccess(ED->getGenericParams(), ED,
3272-
desiredAccessScope, access);
3273-
}
3237+
if (auto *AA = ED->getAttrs().getAttribute<AccessControlAttr>())
3238+
checkExtensionGenericParamAccess(TC, ED, AA->getAccess());
32743239

32753240
// Trigger the creation of all of the conformances associated with this
32763241
// nominal type.
@@ -3407,8 +3372,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
34073372

34083373
TC.checkDeclAttributes(CD);
34093374

3410-
AccessControlChecker::checkAccessControl(TC, CD);
3411-
UsableFromInlineChecker::checkUsableFromInline(TC, CD);
3375+
checkAccessControl(TC, CD);
34123376

34133377
if (requiresDefinition(CD) && !CD->hasBody()) {
34143378
// Complain if we should have a body.

0 commit comments

Comments
 (0)