mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
swift-api-digester: teach the tool to serialize USRs for nominal type. (#15463)
This allows us to map back from a type to the declaration in the dump, so that we can perform more fine-grained analysis like whether a string has been changed to string enum.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
#import <Foundation.h>
|
||||
extern int ANTGlobalValue;
|
||||
|
||||
@interface NewType
|
||||
@@ -16,3 +17,7 @@ extern int ANTGlobalValue;
|
||||
-(void) ProtMemberFunc2;
|
||||
-(void) ProtMemberFunc3;
|
||||
@end
|
||||
|
||||
@interface AnimalStatusDescriptor
|
||||
- (nonnull AnimalStatusDescriptor *)animalStatusDescriptorByAddingAttributes:(nonnull NSDictionary<NSString*, id> *)attributes;
|
||||
@end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#import <objc_generics.h>
|
||||
extern int ANTGlobalValue;
|
||||
|
||||
@interface NewType
|
||||
@@ -14,3 +15,9 @@ extern int ANTGlobalValue;
|
||||
@protocol ObjcProt
|
||||
-(void) ProtMemberFunc;
|
||||
@end
|
||||
|
||||
typedef NSString * AnimalAttributeName NS_STRING_ENUM;
|
||||
|
||||
@interface AnimalStatusDescriptor
|
||||
- (nonnull AnimalStatusDescriptor *)animalStatusDescriptorByAddingAttributes:(nonnull NSDictionary<AnimalAttributeName, id> *)attributes;
|
||||
@end
|
||||
|
||||
@@ -35,3 +35,5 @@ public func foo2(_ a: Int = #line, b: S1) {}
|
||||
public enum Number: Int {
|
||||
case one
|
||||
}
|
||||
|
||||
public func foo3(_ a: [Int: String]) {}
|
||||
@@ -11,5 +11,6 @@ APINotesTest(APINotesTest.h): Func SwiftTypeWithMethodLeft.getPropertyA() has be
|
||||
APINotesTest(APINotesTest.h): Protocol SwiftTypeWithMethodLeft has been renamed to Protocol SwiftTypeWithMethodRight
|
||||
|
||||
/* Type Changes */
|
||||
APINotesTest(APINotesTest.h): Func AnimalStatusDescriptor.addingAttributes(_:) has parameter 0 type change from [String : Any] to [AnimalAttributeName : Any]
|
||||
|
||||
/* Decl Attribute changes */
|
||||
|
||||
@@ -1,4 +1,26 @@
|
||||
[
|
||||
{
|
||||
"DiffItemKind": "CommonDiffItem",
|
||||
"NodeKind": "Function",
|
||||
"NodeAnnotation": "TypeRewritten",
|
||||
"ChildIndex": "1:0",
|
||||
"LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
|
||||
"LeftComment": "String",
|
||||
"RightUsr": "",
|
||||
"RightComment": "AnimalAttributeName",
|
||||
"ModuleName": "APINotesTest"
|
||||
},
|
||||
{
|
||||
"DiffItemKind": "CommonDiffItem",
|
||||
"NodeKind": "Function",
|
||||
"NodeAnnotation": "TypeRewritten",
|
||||
"ChildIndex": "1:0",
|
||||
"LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
|
||||
"LeftComment": "String",
|
||||
"RightUsr": "",
|
||||
"RightComment": "AnimalAttributeName",
|
||||
"ModuleName": "APINotesTest"
|
||||
},
|
||||
{
|
||||
"DiffItemKind": "CommonDiffItem",
|
||||
"NodeKind": "Function",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"kind": "TypeNominal",
|
||||
"name": "C0",
|
||||
"printedName": "C0<T1, T2, T3>",
|
||||
"usr": "s:4cake2C0C",
|
||||
"children": [
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
@@ -188,7 +189,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "S1",
|
||||
"printedName": "S1"
|
||||
"printedName": "S1",
|
||||
"usr": "s:4cake2S1V"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -249,11 +251,13 @@
|
||||
"kind": "TypeNominal",
|
||||
"name": "Optional",
|
||||
"printedName": "C1?",
|
||||
"usr": "s:Sq",
|
||||
"children": [
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "C1",
|
||||
"printedName": "C1"
|
||||
"printedName": "C1",
|
||||
"usr": "s:4cake2C1C"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -277,11 +281,13 @@
|
||||
"kind": "TypeNominal",
|
||||
"name": "Optional",
|
||||
"printedName": "C1?",
|
||||
"usr": "s:Sq",
|
||||
"children": [
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "C1",
|
||||
"printedName": "C1"
|
||||
"printedName": "C1",
|
||||
"usr": "s:4cake2C1C"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -316,7 +322,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "C1",
|
||||
"printedName": "C1"
|
||||
"printedName": "C1",
|
||||
"usr": "s:4cake2C1C"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -337,7 +344,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "C1",
|
||||
"printedName": "C1"
|
||||
"printedName": "C1",
|
||||
"usr": "s:4cake2C1C"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -355,7 +363,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "C1",
|
||||
"printedName": "C1"
|
||||
"printedName": "C1",
|
||||
"usr": "s:4cake2C1C"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -379,12 +388,14 @@
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int",
|
||||
"hasDefaultArg": true
|
||||
"hasDefaultArg": true,
|
||||
"usr": "s:Si"
|
||||
},
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "S1",
|
||||
"printedName": "S1"
|
||||
"printedName": "S1",
|
||||
"usr": "s:4cake2S1V"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -406,12 +417,50 @@
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int",
|
||||
"hasDefaultArg": true
|
||||
"hasDefaultArg": true,
|
||||
"usr": "s:Si"
|
||||
},
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "S1",
|
||||
"printedName": "S1"
|
||||
"printedName": "S1",
|
||||
"usr": "s:4cake2S1V"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "Function",
|
||||
"name": "foo3",
|
||||
"printedName": "foo3(_:)",
|
||||
"declKind": "Func",
|
||||
"usr": "s:4cake4foo3yys10DictionaryVySiSSGF",
|
||||
"location": "",
|
||||
"moduleName": "cake",
|
||||
"children": [
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Void",
|
||||
"printedName": "()"
|
||||
},
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Dictionary",
|
||||
"printedName": "[Int : String]",
|
||||
"usr": "s:s10DictionaryV",
|
||||
"children": [
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int",
|
||||
"usr": "s:Si"
|
||||
},
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "String",
|
||||
"printedName": "String",
|
||||
"usr": "s:SS"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -447,7 +496,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Number",
|
||||
"printedName": "Number"
|
||||
"printedName": "Number",
|
||||
"usr": "s:4cake6NumberO"
|
||||
},
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
@@ -457,7 +507,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Number",
|
||||
"printedName": "Number"
|
||||
"printedName": "Number",
|
||||
"usr": "s:4cake6NumberO"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -477,7 +528,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int"
|
||||
"printedName": "Int",
|
||||
"usr": "s:Si"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -493,7 +545,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int"
|
||||
"printedName": "Int",
|
||||
"usr": "s:Si"
|
||||
},
|
||||
{
|
||||
"kind": "Getter",
|
||||
@@ -507,7 +560,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int"
|
||||
"printedName": "Int",
|
||||
"usr": "s:Si"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -526,18 +580,21 @@
|
||||
"kind": "TypeNominal",
|
||||
"name": "Optional",
|
||||
"printedName": "Number?",
|
||||
"usr": "s:Sq",
|
||||
"children": [
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Number",
|
||||
"printedName": "Number"
|
||||
"printedName": "Number",
|
||||
"usr": "s:4cake6NumberO"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int"
|
||||
"printedName": "Int",
|
||||
"usr": "s:Si"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -553,7 +610,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int"
|
||||
"printedName": "Int",
|
||||
"usr": "s:Si"
|
||||
},
|
||||
{
|
||||
"kind": "Getter",
|
||||
@@ -567,7 +625,8 @@
|
||||
{
|
||||
"kind": "TypeNominal",
|
||||
"name": "Int",
|
||||
"printedName": "Int"
|
||||
"printedName": "Int",
|
||||
"usr": "s:Si"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// RUN: %empty-directory(%t.mod)
|
||||
// RUN: %empty-directory(%t.sdk)
|
||||
// RUN: %empty-directory(%t.module-cache)
|
||||
// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesLeft
|
||||
// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesRight
|
||||
// RUN: %api-digester %clang-importer-sdk-nosource -dump-sdk -module APINotesTest -o %t.dump1.json -module-cache-path %t.module-cache -swift-version 3 -I %S/Inputs/APINotesLeft
|
||||
// RUN: %api-digester %clang-importer-sdk-nosource -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -swift-version 3 -I %S/Inputs/APINotesRight
|
||||
// RUN: %api-digester -diagnose-sdk -print-module -input-paths %t.dump1.json -input-paths %t.dump2.json > %t.result
|
||||
// RUN: diff -u %S/Outputs/apinotes-diags.txt %t.result
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// RUN: %empty-directory(%t.mod)
|
||||
// RUN: %empty-directory(%t.sdk)
|
||||
// RUN: %empty-directory(%t.module-cache)
|
||||
// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesLeft
|
||||
// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesRight
|
||||
// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 3 -I %S/Inputs/APINotesLeft
|
||||
// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 3 -I %S/Inputs/APINotesRight
|
||||
// RUN: %api-digester -compare-sdk --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result -json
|
||||
// RUN: diff -u %S/Outputs/apinotes-migrator-gen.json %t.result
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// RUN: %empty-directory(%t.mod)
|
||||
// RUN: %empty-directory(%t.sdk)
|
||||
// RUN: %empty-directory(%t.module-cache)
|
||||
// RUN: %swift -emit-module -o %t.mod/cake1.swiftmodule %S/Inputs/cake1.swift -parse-as-library -I %S/Inputs/APINotesLeft
|
||||
// RUN: %swift -emit-module -o %t.mod/cake2.swiftmodule %S/Inputs/cake2.swift -parse-as-library -I %S/Inputs/APINotesRight
|
||||
// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %t.mod -I %S/Inputs/APINotesLeft
|
||||
// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %t.mod -I %S/Inputs/APINotesRight
|
||||
// RUN: %swift -emit-module -o %t.mod/cake1.swiftmodule %S/Inputs/cake1.swift -parse-as-library -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource
|
||||
// RUN: %swift -emit-module -o %t.mod/cake2.swiftmodule %S/Inputs/cake2.swift -parse-as-library -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource
|
||||
// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 3 -I %t.mod -I %S/Inputs/APINotesLeft
|
||||
// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 3 -I %t.mod -I %S/Inputs/APINotesRight
|
||||
// RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json > %t.result
|
||||
// RUN: diff -u %S/Outputs/Cake.txt %t.result
|
||||
|
||||
@@ -511,9 +511,12 @@ bool SDKNodeType::classof(const SDKNode *N) {
|
||||
}
|
||||
|
||||
class SDKNodeTypeNominal : public SDKNodeType {
|
||||
StringRef USR;
|
||||
public:
|
||||
SDKNodeTypeNominal(SDKNodeInitInfo Info) : SDKNodeType(Info,
|
||||
SDKNodeKind::TypeNominal) {}
|
||||
SDKNodeKind::TypeNominal), USR(Info.USR) {}
|
||||
// Get the usr of the correspoding nominal type decl.
|
||||
StringRef getUsr() const { return USR; }
|
||||
static bool classof(const SDKNode *N);
|
||||
};
|
||||
|
||||
@@ -1286,6 +1289,10 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
|
||||
TypeInfo(TypeInfo) {
|
||||
if (isFunctionTypeNoEscape(Ty))
|
||||
TypeAttrs.push_back(TypeAttrKind::TAK_noescape);
|
||||
// If this is a nominal type, get its Usr.
|
||||
if (auto *ND = Ty->getAnyNominal()) {
|
||||
USR = calculateUsr(Ctx, ND);
|
||||
}
|
||||
}
|
||||
|
||||
SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD)
|
||||
@@ -1760,6 +1767,12 @@ namespace swift {
|
||||
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_hasDefaultArg).data(),
|
||||
HasDefault);
|
||||
}
|
||||
// Serialize nominal type's USR.
|
||||
if (auto NT = dyn_cast<SDKNodeTypeNominal>(value)) {
|
||||
auto Usr = NT->getUsr();
|
||||
if (!Usr.empty())
|
||||
out.mapRequired(getKeyContent(Ctx, KeyKind::KK_usr).data(), Usr);
|
||||
}
|
||||
}
|
||||
if (!value->isLeaf()) {
|
||||
ArrayRef<SDKNode *> Children = value->getChildren();
|
||||
@@ -3424,7 +3437,7 @@ static int compareSDKs(StringRef LeftPath, StringRef RightPath,
|
||||
|
||||
llvm::errs() << "Dumping diff to " << DiffPath << '\n';
|
||||
std::vector<OverloadedFuncInfo> Overloads;
|
||||
OverloadMemberFunctionEmitter::collectDiffItems(RightModule, Overloads);
|
||||
// OverloadMemberFunctionEmitter::collectDiffItems(RightModule, Overloads);
|
||||
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream Fs(DiffPath, EC, llvm::sys::fs::F_None);
|
||||
|
||||
Reference in New Issue
Block a user