Skip to content

Commit bc87e9b

Browse files
authored
Merge pull request swiftlang#19511 from nkcsgexi/decl-kind-change
swift-module-digester: diagnose any decl kind changes for nominal types.
2 parents c67d4ab + d0cd97e commit bc87e9b

File tree

8 files changed

+46
-15
lines changed

8 files changed

+46
-15
lines changed

include/swift/AST/DiagnosticsModuleDiffer.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ ERROR(super_class_removed,none,"%0 has removed its super class %1", (StringRef,
7272

7373
ERROR(super_class_changed,none,"%0 has changed its super class from %1 to %2", (StringRef, StringRef, StringRef))
7474

75+
ERROR(nominal_type_kind_changed,none,"%0 has been changed to a %1", (StringRef, StringRef))
76+
7577
#ifndef DIAG_NO_UNDEF
7678
# if defined(DIAG)
7779
# undef DIAG

test/api-digester/Inputs/cake1.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,6 @@ public protocol RequiementChanges {
9191
}
9292

9393
public class SuperClassRemoval: C3 {}
94+
95+
public class ClassToStruct {}
96+
public protocol ProtocolToEnum {}

test/api-digester/Inputs/cake2.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,6 @@ public protocol RequiementChanges {
9898
}
9999

100100
public class SuperClassRemoval {}
101+
102+
public struct ClassToStruct {}
103+
public enum ProtocolToEnum {}

test/api-digester/Outputs/Cake-abi.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ cake1: Var RemoveSetters.Value has removed its setter
1616
cake1: Var RequiementChanges.removedVar has been removed
1717

1818
/* Moved Decls */
19+
cake1: Class ClassToStruct has been changed to a Struct
20+
cake1: Protocol ProtocolToEnum has been changed to a Enum
1921

2022
/* Renamed Decls */
2123
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)

test/api-digester/Outputs/Cake.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ cake1: Var RemoveSetters.Value has removed its setter
1616
cake1: Var RequiementChanges.removedVar has been removed
1717

1818
/* Moved Decls */
19+
cake1: Class ClassToStruct has been changed to a Struct
20+
cake1: Protocol ProtocolToEnum has been changed to a Enum
1921

2022
/* Renamed Decls */
2123
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)

tools/swift-api-digester/ModuleAnalyzerNodes.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,9 @@ bool SDKNode::operator==(const SDKNode &Other) const {
764764
if (Left->getSuperClassName() != Right->getSuperClassName()) {
765765
return false;
766766
}
767+
if (Left->getDeclKind() != Right->getDeclKind()) {
768+
return false;
769+
}
767770
}
768771
LLVM_FALLTHROUGH;
769772
}

tools/swift-api-digester/ModuleDiagsConsumer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static StringRef getCategoryName(uint32_t ID) {
3636
case LocalDiagID::removed_setter:
3737
return "/* Removed Decls */";
3838
case LocalDiagID::moved_decl:
39+
case LocalDiagID::nominal_type_kind_changed:
3940
return "/* Moved Decls */";
4041
case LocalDiagID::renamed_decl:
4142
return "/* Renamed Decls */";

tools/swift-api-digester/swift-api-digester.cpp

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,15 @@ static bool isOwnershipEquivalent(ReferenceOwnership Left,
677677
static void diagnoseNominalTypeDeclChange(SDKNodeDeclType *L, SDKNodeDeclType *R) {
678678
auto &Ctx = L->getSDKContext();
679679
auto &Diags = Ctx.getDiags();
680+
681+
if (L->getDeclKind() != R->getDeclKind()) {
682+
Diags.diagnose(SourceLoc(), diag::nominal_type_kind_changed,
683+
L->getScreenInfo(), getDeclKindStr(R->getDeclKind()));
684+
return;
685+
}
686+
687+
assert(L->getDeclKind() == R->getDeclKind());
688+
auto DKind = L->getDeclKind();
680689
std::vector<StringRef> LeftMinusRight;
681690
std::vector<StringRef> RightMinusLeft;
682691
swift::ide::api::stringSetDifference(L->getAllProtocols(), R->getAllProtocols(),
@@ -686,26 +695,32 @@ static void diagnoseNominalTypeDeclChange(SDKNodeDeclType *L, SDKNodeDeclType *R
686695
Diags.diagnose(SourceLoc(), diag::conformance_removed, L->getScreenInfo(), Name,
687696
isProtocol);
688697
});
689-
690-
// Adding inherited protocols can be API breaking.
691-
if (isProtocol) {
698+
switch (DKind) {
699+
case DeclKind::Protocol: {
692700
std::for_each(RightMinusLeft.begin(), RightMinusLeft.end(), [&](StringRef Name) {
693701
Diags.diagnose(SourceLoc(), diag::conformance_added, L->getScreenInfo(),
694702
Name);
695703
});
696-
}
697-
auto LSuperClass = L->getSuperClassName();
698-
auto RSuperClass = R->getSuperClassName();
699-
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
700-
if (RSuperClass.empty()) {
701-
Diags.diagnose(SourceLoc(), diag::super_class_removed, L->getScreenInfo(),
702-
LSuperClass);
703-
} else {
704-
// FIXME: This will be a false positive if the new subclass is a subclass
705-
// of the old type.
706-
Diags.diagnose(SourceLoc(), diag::super_class_changed, L->getScreenInfo(),
707-
LSuperClass, RSuperClass);
704+
break;
705+
}
706+
case DeclKind::Class: {
707+
auto LSuperClass = L->getSuperClassName();
708+
auto RSuperClass = R->getSuperClassName();
709+
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
710+
if (RSuperClass.empty()) {
711+
Diags.diagnose(SourceLoc(), diag::super_class_removed, L->getScreenInfo(),
712+
LSuperClass);
713+
} else {
714+
// FIXME: This will be a false positive if the new subclass is a subclass
715+
// of the old type.
716+
Diags.diagnose(SourceLoc(), diag::super_class_changed, L->getScreenInfo(),
717+
LSuperClass, RSuperClass);
718+
}
708719
}
720+
break;
721+
}
722+
default:
723+
break;
709724
}
710725
}
711726

0 commit comments

Comments
 (0)