Be way more conservative about marking dependencies as non-cascading (#13214)

Being part of the type of a private declaration isn't sufficient,
because that could be used for the inferred type of a non-private
variable/constant/property.

Also, introduce a new kind of dependency test that shows both that a
file A changes its interface based on a change in another file B, and
that the swiftdeps output for file A includes the dependency on file B
as cascading.

https://bugs.swift.org/browse/SR-6149
This commit is contained in:
Jordan Rose
2017-12-01 18:35:18 -08:00
committed by GitHub
parent da14cd79a6
commit ace0f56e9c
15 changed files with 187 additions and 59 deletions

View File

@@ -612,48 +612,23 @@ DeclContext::isCascadingContextForLookup(bool functionsAreNonCascading) const {
// FIXME: Pattern initializers at top-level scope end up here.
return true;
case DeclContextKind::AbstractFunctionDecl: {
case DeclContextKind::AbstractFunctionDecl:
if (functionsAreNonCascading)
return false;
auto *AFD = cast<AbstractFunctionDecl>(this);
if (AFD->hasAccess())
return AFD->getFormalAccess() > AccessLevel::FilePrivate;
break;
}
case DeclContextKind::SubscriptDecl: {
auto *SD = cast<SubscriptDecl>(this);
if (SD->hasAccess())
return SD->getFormalAccess() > AccessLevel::FilePrivate;
case DeclContextKind::SubscriptDecl:
break;
}
case DeclContextKind::Module:
case DeclContextKind::FileUnit:
return true;
case DeclContextKind::GenericTypeDecl: {
auto *nominal = cast<GenericTypeDecl>(this);
if (nominal->hasAccess())
return nominal->getFormalAccess() > AccessLevel::FilePrivate;
case DeclContextKind::GenericTypeDecl:
break;
}
case DeclContextKind::ExtensionDecl: {
auto *extension = cast<ExtensionDecl>(this);
if (extension->hasDefaultAccessLevel())
return extension->getDefaultAccessLevel() > AccessLevel::FilePrivate;
// FIXME: duplicated from computeDefaultAccessLevel in TypeCheckDecl.cpp.
if (auto *AA = extension->getAttrs().getAttribute<AccessControlAttr>())
return AA->getAccess() > AccessLevel::FilePrivate;
if (Type extendedTy = extension->getExtendedType()) {
// Need to check if extendedTy is ErrorType
if (extendedTy->getAnyNominal())
return extendedTy->getAnyNominal()->isCascadingContextForLookup(true);
}
break;
}
case DeclContextKind::ExtensionDecl:
return true;
}
return getParent()->isCascadingContextForLookup(true);