Skip to content

Commit 4dad880

Browse files
authored
Merge pull request swiftlang#19523 from nkcsgexi/class-chain-analysis
swift-module-digester: fix a false positive when diagnosing super class changes.
2 parents 32883bd + 2182f53 commit 4dad880

File tree

9 files changed

+38
-18
lines changed

9 files changed

+38
-18
lines changed

include/swift/IDE/DigesterEnums.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ KEY(declAttributes)
109109
KEY(declKind)
110110
KEY(ownership)
111111
KEY(superclassUsr)
112-
KEY(superclassName)
112+
KEY(superclassNames)
113113
KEY(hasDefaultArg)
114114
KEY(conformingProtocols)
115115
KEY(enumRawTypeName)

test/api-digester/Inputs/cake1.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,5 @@ public class SuperClassRemoval: C3 {}
9494

9595
public class ClassToStruct {}
9696
public protocol ProtocolToEnum {}
97+
98+
public class SuperClassChange: C7 {}

test/api-digester/Inputs/cake2.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ public class C7: P1 {
7171
public func foo(_ a: Int, _ b: Int) {}
7272
}
7373

74+
public class C8: C7 {}
75+
7476
public protocol P3: P1, P4 {}
7577

7678
public protocol P4 {}
@@ -101,3 +103,5 @@ public class SuperClassRemoval {}
101103

102104
public struct ClassToStruct {}
103105
public enum ProtocolToEnum {}
106+
107+
public class SuperClassChange: C8 {}

test/api-digester/Outputs/cake-abi.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,9 @@
198198
"location": "",
199199
"moduleName": "cake",
200200
"superclassUsr": "s:4cake2C0C",
201-
"superclassName": "C0",
201+
"superclassNames": [
202+
"C0"
203+
],
202204
"children": [
203205
{
204206
"kind": "Function",

test/api-digester/Outputs/cake.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@
205205
"location": "",
206206
"moduleName": "cake",
207207
"superclassUsr": "s:4cake2C0C",
208-
"superclassName": "C0",
208+
"superclassNames": [
209+
"C0"
210+
],
209211
"children": [
210212
{
211213
"kind": "Function",

test/api-digester/Outputs/clang-module-dump.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"location": "",
1313
"moduleName": "Foo",
1414
"superclassUsr": "c:objc(cs)NSObject",
15-
"superclassName": "NSObject",
15+
"superclassNames": [
16+
"NSObject"
17+
],
1618
"conformingProtocols": [
1719
"ObjcProt",
1820
"NSObjectProtocol"

tools/swift-api-digester/ModuleAnalyzerNodes.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct swift::ide::api::SDKNodeInitInfo {
4848
std::vector<TypeAttrKind> TypeAttrs;
4949
std::vector<StringRef> ConformingProtocols;
5050
StringRef SuperclassUsr;
51-
StringRef SuperclassName;
51+
std::vector<StringRef> SuperclassNames;
5252
StringRef EnumRawTypeName;
5353
bool hasDefaultArgument = false;
5454
StringRef GenericSig;
@@ -101,7 +101,7 @@ SDKNodeTypeAlias::SDKNodeTypeAlias(SDKNodeInitInfo Info):
101101

102102
SDKNodeDeclType::SDKNodeDeclType(SDKNodeInitInfo Info):
103103
SDKNodeDecl(Info, SDKNodeKind::DeclType), SuperclassUsr(Info.SuperclassUsr),
104-
SuperclassName(Info.SuperclassName),
104+
SuperclassNames(Info.SuperclassNames),
105105
ConformingProtocols(Info.ConformingProtocols),
106106
EnumRawTypeName(Info.EnumRawTypeName) {}
107107

@@ -570,8 +570,12 @@ SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx,
570570
case KeyKind::KK_superclassUsr:
571571
Info.SuperclassUsr = GetScalarString(Pair.getValue());
572572
break;
573-
case KeyKind::KK_superclassName:
574-
Info.SuperclassName = GetScalarString(Pair.getValue());
573+
case KeyKind::KK_superclassNames:
574+
assert(Info.SuperclassNames.empty());
575+
for (auto &Name : *cast<llvm::yaml::SequenceNode>(Pair.getValue())) {
576+
Info.SuperclassNames.push_back(GetScalarString(&Name));
577+
}
578+
break;
575579
break;
576580
case KeyKind::KK_genericSig:
577581
Info.GenericSig = GetScalarString(Pair.getValue());
@@ -1072,7 +1076,10 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD)
10721076
if (auto *CD = dyn_cast_or_null<ClassDecl>(VD)) {
10731077
if (auto *Super = CD->getSuperclassDecl()) {
10741078
SuperclassUsr = calculateUsr(Ctx, Super);
1075-
SuperclassName = Super->getName().str();
1079+
while(Super) {
1080+
SuperclassNames.push_back(Super->getName().str());
1081+
Super = Super->getSuperclassDecl();
1082+
}
10761083
}
10771084
}
10781085

@@ -1521,10 +1528,10 @@ struct ObjectTraits<SDKNode *> {
15211528
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_superclassUsr).data(),
15221529
Super);
15231530
}
1524-
auto SuperName = TD->getSuperClassName();
1525-
if (!SuperName.empty()) {
1526-
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_superclassName).data(),
1527-
SuperName);
1531+
auto SuperNames = TD->getClassInheritanceChain();
1532+
if (!SuperNames.empty()) {
1533+
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_superclassNames).data(),
1534+
SuperNames);
15281535
}
15291536
auto Pros = TD->getAllProtocols();
15301537
if (!Pros.empty()) {

tools/swift-api-digester/ModuleAnalyzerNodes.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,17 @@ class SDKNodeVectorViewer::ViewerIterator :
407407

408408
class SDKNodeDeclType : public SDKNodeDecl {
409409
StringRef SuperclassUsr;
410-
StringRef SuperclassName;
410+
std::vector<StringRef> SuperclassNames;
411411
std::vector<StringRef> ConformingProtocols;
412412
StringRef EnumRawTypeName;
413413
public:
414414
SDKNodeDeclType(SDKNodeInitInfo Info);
415415
static bool classof(const SDKNode *N);
416416
StringRef getSuperClassUsr() const { return SuperclassUsr; }
417-
StringRef getSuperClassName() const { return SuperclassName; }
417+
ArrayRef<StringRef> getClassInheritanceChain() const { return SuperclassNames; }
418+
StringRef getSuperClassName() const {
419+
return SuperclassNames.empty() ? StringRef() : SuperclassNames.front();
420+
};
418421
ArrayRef<StringRef> getAllProtocols() const { return ConformingProtocols; }
419422

420423
#define NOMINAL_TYPE_DECL(ID, PARENT) \

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,7 @@ static void diagnoseNominalTypeDeclChange(SDKNodeDeclType *L, SDKNodeDeclType *R
710710
if (RSuperClass.empty()) {
711711
Diags.diagnose(SourceLoc(), diag::super_class_removed, L->getScreenInfo(),
712712
LSuperClass);
713-
} else {
714-
// FIXME: This will be a false positive if the new subclass is a subclass
715-
// of the old type.
713+
} else if (!contains(R->getClassInheritanceChain(), LSuperClass)) {
716714
Diags.diagnose(SourceLoc(), diag::super_class_changed, L->getScreenInfo(),
717715
LSuperClass, RSuperClass);
718716
}

0 commit comments

Comments
 (0)