mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
swift-module-digester: diagnose any decl kind changes for nominal types.
This commit is contained in:
@@ -677,6 +677,15 @@ static bool isOwnershipEquivalent(ReferenceOwnership Left,
|
||||
static void diagnoseNominalTypeDeclChange(SDKNodeDeclType *L, SDKNodeDeclType *R) {
|
||||
auto &Ctx = L->getSDKContext();
|
||||
auto &Diags = Ctx.getDiags();
|
||||
|
||||
if (L->getDeclKind() != R->getDeclKind()) {
|
||||
Diags.diagnose(SourceLoc(), diag::nominal_type_kind_changed,
|
||||
L->getScreenInfo(), getDeclKindStr(R->getDeclKind()));
|
||||
return;
|
||||
}
|
||||
|
||||
assert(L->getDeclKind() == R->getDeclKind());
|
||||
auto DKind = L->getDeclKind();
|
||||
std::vector<StringRef> LeftMinusRight;
|
||||
std::vector<StringRef> RightMinusLeft;
|
||||
swift::ide::api::stringSetDifference(L->getAllProtocols(), R->getAllProtocols(),
|
||||
@@ -686,26 +695,32 @@ static void diagnoseNominalTypeDeclChange(SDKNodeDeclType *L, SDKNodeDeclType *R
|
||||
Diags.diagnose(SourceLoc(), diag::conformance_removed, L->getScreenInfo(), Name,
|
||||
isProtocol);
|
||||
});
|
||||
|
||||
// Adding inherited protocols can be API breaking.
|
||||
if (isProtocol) {
|
||||
switch (DKind) {
|
||||
case DeclKind::Protocol: {
|
||||
std::for_each(RightMinusLeft.begin(), RightMinusLeft.end(), [&](StringRef Name) {
|
||||
Diags.diagnose(SourceLoc(), diag::conformance_added, L->getScreenInfo(),
|
||||
Name);
|
||||
});
|
||||
break;
|
||||
}
|
||||
auto LSuperClass = L->getSuperClassName();
|
||||
auto RSuperClass = R->getSuperClassName();
|
||||
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
|
||||
if (RSuperClass.empty()) {
|
||||
Diags.diagnose(SourceLoc(), diag::super_class_removed, L->getScreenInfo(),
|
||||
LSuperClass);
|
||||
} else {
|
||||
// FIXME: This will be a false positive if the new subclass is a subclass
|
||||
// of the old type.
|
||||
Diags.diagnose(SourceLoc(), diag::super_class_changed, L->getScreenInfo(),
|
||||
LSuperClass, RSuperClass);
|
||||
case DeclKind::Class: {
|
||||
auto LSuperClass = L->getSuperClassName();
|
||||
auto RSuperClass = R->getSuperClassName();
|
||||
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
|
||||
if (RSuperClass.empty()) {
|
||||
Diags.diagnose(SourceLoc(), diag::super_class_removed, L->getScreenInfo(),
|
||||
LSuperClass);
|
||||
} else {
|
||||
// FIXME: This will be a false positive if the new subclass is a subclass
|
||||
// of the old type.
|
||||
Diags.diagnose(SourceLoc(), diag::super_class_changed, L->getScreenInfo(),
|
||||
LSuperClass, RSuperClass);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user