@@ -24,68 +24,76 @@ using namespace swift;
2424AccessScopeChecker::AccessScopeChecker (const DeclContext *useDC,
2525 bool treatUsableFromInlineAsPublic)
2626 : File(useDC->getParentSourceFile ()),
27- TreatUsableFromInlineAsPublic(treatUsableFromInlineAsPublic),
28- Context(File->getASTContext ()) {}
27+ TreatUsableFromInlineAsPublic(treatUsableFromInlineAsPublic) {}
2928
3029bool
31- AccessScopeChecker::visitDecl (ValueDecl *VD) {
32- if (!VD || isa<GenericTypeParamDecl>(VD))
30+ AccessScopeChecker::visitDecl (const ValueDecl *VD) {
31+ if (isa<GenericTypeParamDecl>(VD))
3332 return true ;
3433
3534 auto AS = VD->getFormalAccessScope (File, TreatUsableFromInlineAsPublic);
3635 Scope = Scope->intersectWith (AS);
3736 return Scope.hasValue ();
3837}
3938
40- TypeReprAccessScopeChecker::TypeReprAccessScopeChecker (const DeclContext *useDC,
41- bool treatUsableFromInlineAsPublic)
42- : AccessScopeChecker(useDC, treatUsableFromInlineAsPublic) {
39+ bool TypeReprIdentFinder::walkToTypeReprPost (TypeRepr *TR) {
40+ auto CITR = dyn_cast<ComponentIdentTypeRepr>(TR);
41+ if (!CITR || !CITR->getBoundDecl ())
42+ return true ;
43+ return Callback (CITR);
4344}
4445
45- bool
46- TypeReprAccessScopeChecker::walkToTypeReprPre (TypeRepr *TR) {
47- if (auto CITR = dyn_cast<ComponentIdentTypeRepr>(TR))
48- return visitDecl (CITR->getBoundDecl ());
49- return true ;
46+ Optional<AccessScope>
47+ AccessScopeChecker::getAccessScope (TypeRepr *TR, const DeclContext *useDC,
48+ bool treatUsableFromInlineAsPublic) {
49+ AccessScopeChecker checker (useDC, treatUsableFromInlineAsPublic);
50+ TR->walk (TypeReprIdentFinder ([&](const ComponentIdentTypeRepr *typeRepr) {
51+ return checker.visitDecl (typeRepr->getBoundDecl ());
52+ }));
53+ return checker.Scope ;
5054}
5155
52- bool
53- TypeReprAccessScopeChecker::walkToTypeReprPost (TypeRepr *TR) {
54- return Scope.hasValue ();
55- }
56+ TypeWalker::Action TypeDeclFinder::walkToTypePre (Type T) {
57+ if (auto *TAT = dyn_cast<TypeAliasType>(T.getPointer ()))
58+ return visitTypeAliasType (TAT);
5659
57- Optional<AccessScope>
58- TypeReprAccessScopeChecker::getAccessScope (TypeRepr *TR, const DeclContext *useDC,
59- bool treatUsableFromInlineAsPublic) {
60- TypeReprAccessScopeChecker checker (useDC, treatUsableFromInlineAsPublic);
61- TR->walk (checker);
62- return checker.Scope ;
60+ // FIXME: We're looking through sugar here so that we visit, e.g.,
61+ // Swift.Array when we see `[Int]`. But that means we do redundant work when
62+ // we see sugar that's purely structural, like `(Int)`. Fortunately, paren
63+ // types are the only such purely structural sugar at the time this comment
64+ // was written, and they're not so common in the first place.
65+ if (auto *BGT = T->getAs <BoundGenericType>())
66+ return visitBoundGenericType (BGT);
67+ if (auto *NT = T->getAs <NominalType>())
68+ return visitNominalType (NT);
69+
70+ return Action::Continue;
6371}
6472
65- TypeAccessScopeChecker::TypeAccessScopeChecker (const DeclContext *useDC,
66- bool treatUsableFromInlineAsPublic)
67- : AccessScopeChecker(useDC, treatUsableFromInlineAsPublic) {}
73+ TypeWalker::Action
74+ SimpleTypeDeclFinder::visitNominalType (const NominalType *ty) {
75+ return Callback (ty->getDecl ());
76+ }
6877
6978TypeWalker::Action
70- TypeAccessScopeChecker::walkToTypePre (Type T) {
71- ValueDecl *VD;
72- if (auto *BNAD = dyn_cast<TypeAliasType>(T.getPointer ()))
73- VD = BNAD->getDecl ();
74- else if (auto *NTD = T->getAnyNominal ())
75- VD = NTD;
76- else
77- VD = nullptr ;
78-
79- if (!visitDecl (VD))
80- return Action::Stop;
79+ SimpleTypeDeclFinder::visitBoundGenericType (const BoundGenericType *ty) {
80+ return Callback (ty->getDecl ());
81+ }
8182
82- return Action::Continue;
83+ TypeWalker::Action
84+ SimpleTypeDeclFinder::visitTypeAliasType (const TypeAliasType *ty) {
85+ return Callback (ty->getDecl ());
8386}
8487
88+
8589Optional<AccessScope>
86- TypeAccessScopeChecker::getAccessScope (Type T, const DeclContext *useDC,
87- bool treatUsableFromInlineAsPublic) {
88- TypeAccessScopeChecker checker (useDC, treatUsableFromInlineAsPublic);
89- T.walk (checker);
90+ AccessScopeChecker::getAccessScope (Type T, const DeclContext *useDC,
91+ bool treatUsableFromInlineAsPublic) {
92+ AccessScopeChecker checker (useDC, treatUsableFromInlineAsPublic);
93+ T.walk (SimpleTypeDeclFinder ([&](const ValueDecl *VD) {
94+ if (checker.visitDecl (VD))
95+ return TypeWalker::Action::Continue;
96+ return TypeWalker::Action::Stop;
97+ }));
9098 return checker.Scope ;
9199}
0 commit comments