mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
swift-module-digester: diagnose any decl kind changes for nominal types.
This commit is contained in:
@@ -72,6 +72,8 @@ ERROR(super_class_removed,none,"%0 has removed its super class %1", (StringRef,
|
|||||||
|
|
||||||
ERROR(super_class_changed,none,"%0 has changed its super class from %1 to %2", (StringRef, StringRef, StringRef))
|
ERROR(super_class_changed,none,"%0 has changed its super class from %1 to %2", (StringRef, StringRef, StringRef))
|
||||||
|
|
||||||
|
ERROR(nominal_type_kind_changed,none,"%0 has been changed to a %1", (StringRef, StringRef))
|
||||||
|
|
||||||
#ifndef DIAG_NO_UNDEF
|
#ifndef DIAG_NO_UNDEF
|
||||||
# if defined(DIAG)
|
# if defined(DIAG)
|
||||||
# undef DIAG
|
# undef DIAG
|
||||||
|
|||||||
@@ -91,3 +91,6 @@ public protocol RequiementChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class SuperClassRemoval: C3 {}
|
public class SuperClassRemoval: C3 {}
|
||||||
|
|
||||||
|
public class ClassToStruct {}
|
||||||
|
public protocol ProtocolToEnum {}
|
||||||
|
|||||||
@@ -98,3 +98,6 @@ public protocol RequiementChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class SuperClassRemoval {}
|
public class SuperClassRemoval {}
|
||||||
|
|
||||||
|
public struct ClassToStruct {}
|
||||||
|
public enum ProtocolToEnum {}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ cake1: Var RemoveSetters.Value has removed its setter
|
|||||||
cake1: Var RequiementChanges.removedVar has been removed
|
cake1: Var RequiementChanges.removedVar has been removed
|
||||||
|
|
||||||
/* Moved Decls */
|
/* Moved Decls */
|
||||||
|
cake1: Class ClassToStruct has been changed to a Struct
|
||||||
|
cake1: Protocol ProtocolToEnum has been changed to a Enum
|
||||||
|
|
||||||
/* Renamed Decls */
|
/* Renamed Decls */
|
||||||
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
|
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ cake1: Var RemoveSetters.Value has removed its setter
|
|||||||
cake1: Var RequiementChanges.removedVar has been removed
|
cake1: Var RequiementChanges.removedVar has been removed
|
||||||
|
|
||||||
/* Moved Decls */
|
/* Moved Decls */
|
||||||
|
cake1: Class ClassToStruct has been changed to a Struct
|
||||||
|
cake1: Protocol ProtocolToEnum has been changed to a Enum
|
||||||
|
|
||||||
/* Renamed Decls */
|
/* Renamed Decls */
|
||||||
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
|
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
|
||||||
|
|||||||
@@ -764,6 +764,9 @@ bool SDKNode::operator==(const SDKNode &Other) const {
|
|||||||
if (Left->getSuperClassName() != Right->getSuperClassName()) {
|
if (Left->getSuperClassName() != Right->getSuperClassName()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (Left->getDeclKind() != Right->getDeclKind()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LLVM_FALLTHROUGH;
|
LLVM_FALLTHROUGH;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ static StringRef getCategoryName(uint32_t ID) {
|
|||||||
case LocalDiagID::removed_setter:
|
case LocalDiagID::removed_setter:
|
||||||
return "/* Removed Decls */";
|
return "/* Removed Decls */";
|
||||||
case LocalDiagID::moved_decl:
|
case LocalDiagID::moved_decl:
|
||||||
|
case LocalDiagID::nominal_type_kind_changed:
|
||||||
return "/* Moved Decls */";
|
return "/* Moved Decls */";
|
||||||
case LocalDiagID::renamed_decl:
|
case LocalDiagID::renamed_decl:
|
||||||
return "/* Renamed Decls */";
|
return "/* Renamed Decls */";
|
||||||
|
|||||||
@@ -677,6 +677,15 @@ static bool isOwnershipEquivalent(ReferenceOwnership Left,
|
|||||||
static void diagnoseNominalTypeDeclChange(SDKNodeDeclType *L, SDKNodeDeclType *R) {
|
static void diagnoseNominalTypeDeclChange(SDKNodeDeclType *L, SDKNodeDeclType *R) {
|
||||||
auto &Ctx = L->getSDKContext();
|
auto &Ctx = L->getSDKContext();
|
||||||
auto &Diags = Ctx.getDiags();
|
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> LeftMinusRight;
|
||||||
std::vector<StringRef> RightMinusLeft;
|
std::vector<StringRef> RightMinusLeft;
|
||||||
swift::ide::api::stringSetDifference(L->getAllProtocols(), R->getAllProtocols(),
|
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,
|
Diags.diagnose(SourceLoc(), diag::conformance_removed, L->getScreenInfo(), Name,
|
||||||
isProtocol);
|
isProtocol);
|
||||||
});
|
});
|
||||||
|
switch (DKind) {
|
||||||
// Adding inherited protocols can be API breaking.
|
case DeclKind::Protocol: {
|
||||||
if (isProtocol) {
|
|
||||||
std::for_each(RightMinusLeft.begin(), RightMinusLeft.end(), [&](StringRef Name) {
|
std::for_each(RightMinusLeft.begin(), RightMinusLeft.end(), [&](StringRef Name) {
|
||||||
Diags.diagnose(SourceLoc(), diag::conformance_added, L->getScreenInfo(),
|
Diags.diagnose(SourceLoc(), diag::conformance_added, L->getScreenInfo(),
|
||||||
Name);
|
Name);
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
auto LSuperClass = L->getSuperClassName();
|
case DeclKind::Class: {
|
||||||
auto RSuperClass = R->getSuperClassName();
|
auto LSuperClass = L->getSuperClassName();
|
||||||
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
|
auto RSuperClass = R->getSuperClassName();
|
||||||
if (RSuperClass.empty()) {
|
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
|
||||||
Diags.diagnose(SourceLoc(), diag::super_class_removed, L->getScreenInfo(),
|
if (RSuperClass.empty()) {
|
||||||
LSuperClass);
|
Diags.diagnose(SourceLoc(), diag::super_class_removed, L->getScreenInfo(),
|
||||||
} else {
|
LSuperClass);
|
||||||
// FIXME: This will be a false positive if the new subclass is a subclass
|
} else {
|
||||||
// of the old type.
|
// FIXME: This will be a false positive if the new subclass is a subclass
|
||||||
Diags.diagnose(SourceLoc(), diag::super_class_changed, L->getScreenInfo(),
|
// of the old type.
|
||||||
LSuperClass, RSuperClass);
|
Diags.diagnose(SourceLoc(), diag::super_class_changed, L->getScreenInfo(),
|
||||||
|
LSuperClass, RSuperClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user