Skip to content

Commit 62e07dc

Browse files
committed
[Static Mirror] Refactor gathering of associated types from a binary and add SwiftStaticMirror entry-point for it.
1 parent 6d97905 commit 62e07dc

File tree

8 files changed

+286
-19
lines changed

8 files changed

+286
-19
lines changed

include/swift-c/StaticMirror/BinaryScan.h

+55-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/// SWIFTSTATICMIRROR_VERSION_MINOR should increase when there are API additions.
2626
/// SWIFTSTATICMIRROR_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
2727
#define SWIFTSTATICMIRROR_VERSION_MAJOR 0
28-
#define SWIFTSTATICMIRROR_VERSION_MINOR 1
28+
#define SWIFTSTATICMIRROR_VERSION_MINOR 2 // Added associated-type gather
2929

3030
SWIFTSTATICMIRROR_BEGIN_DECLS
3131

@@ -42,11 +42,33 @@ typedef void *swift_static_mirror_t;
4242
typedef struct swift_static_mirror_conformance_info_s
4343
*swift_static_mirror_conformance_info_t;
4444

45+
/// Opaque container to details of an associated type specification.
46+
typedef struct swift_static_mirror_type_alias_s
47+
*swift_static_mirror_type_alias_t;
48+
49+
/// Opaque container to an associated type (typealias) info of a given type.
50+
typedef struct swift_static_mirror_associated_type_info_s
51+
*swift_static_mirror_associated_type_info_t;
52+
53+
typedef struct {
54+
swift_static_mirror_type_alias_t *type_aliases;
55+
size_t count;
56+
} swift_static_mirror_type_alias_set_t;
57+
58+
59+
typedef struct {
60+
swift_static_mirror_associated_type_info_t *associated_type_infos;
61+
size_t count;
62+
} swift_static_mirror_associated_type_info_set_t;
63+
4564
typedef struct {
4665
swift_static_mirror_conformance_info_t *conformances;
4766
size_t count;
4867
} swift_static_mirror_conformances_set_t;
4968

69+
70+
// swift_static_mirror_conformance_info query methods
71+
5072
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
5173
swift_static_mirror_conformance_info_get_type_name(
5274
swift_static_mirror_conformance_info_t);
@@ -63,6 +85,25 @@ SWIFTSTATICMIRROR_PUBLIC void
6385
swift_static_mirror_conformance_info_dispose(
6486
swift_static_mirror_conformance_info_t);
6587

88+
// swift_static_mirror_associated_type query methods
89+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
90+
swift_static_mirror_type_alias_get_type_alias_name(
91+
swift_static_mirror_type_alias_t);
92+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
93+
swift_static_mirror_type_alias_get_substituted_type_name(
94+
swift_static_mirror_type_alias_t);
95+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
96+
swift_static_mirror_type_alias_get_substituted_type_mangled_name(
97+
swift_static_mirror_type_alias_t);
98+
99+
// swift_static_mirror_associated_type_info query methods
100+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
101+
swift_static_mirror_associated_type_info_get_mangled_type_name(
102+
swift_static_mirror_associated_type_info_t);
103+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_type_alias_set_t*
104+
swift_static_mirror_associated_type_info_get_type_alias_set(
105+
swift_static_mirror_associated_type_info_t);
106+
66107
/// Create an \c swift_static_mirror_t instance.
67108
/// The returned \c swift_static_mirror_t is owned by the caller and must be
68109
/// disposed of using \c swift_static_mirror_dispose .
@@ -81,6 +122,19 @@ swift_static_mirror_conformances_set_create(
81122
SWIFTSTATICMIRROR_PUBLIC void swift_static_mirror_conformances_set_dispose(
82123
swift_static_mirror_conformances_set_t *);
83124

125+
/// Identify and collect all associated types of a given input type (by mangled name)
126+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_associated_type_info_set_t *
127+
swift_static_mirror_associated_type_info_set_create(
128+
swift_static_mirror_t, const char *);
129+
130+
/// Identify and collect associated types of all discovered types.
131+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_associated_type_info_set_t *
132+
swift_static_mirror_all_associated_type_info_set_create(
133+
swift_static_mirror_t);
134+
135+
SWIFTSTATICMIRROR_PUBLIC void swift_static_mirror_associated_type_info_set_dispose(
136+
swift_static_mirror_associated_type_info_set_t *);
137+
84138
SWIFTSTATICMIRROR_END_DECLS
85139

86140
#endif // SWIFT_C_BINARY_SCAN_H

include/swift/Reflection/TypeRefBuilder.h

+21
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,26 @@ struct ConformanceCollectionResult {
297297
std::vector<std::string> Errors;
298298
};
299299

300+
struct AssociatedType {
301+
std::string TypeAliasName;
302+
std::string SubstitutedTypeMangledName;
303+
std::string SubstitutedTypeFullyQualifiedName;
304+
std::string SubstitutedTypeDiagnosticPrintName;
305+
};
306+
307+
/// Info about a given type's associated type, as read out from an Image
308+
struct AssociatedTypeInfo {
309+
std::string MangledTypeName;
310+
std::string FullyQualifiedName;
311+
std::string ProtocolFullyQualifiedName;
312+
std::vector<AssociatedType> AssociatedTypes;
313+
};
314+
315+
struct AssociatedTypeCollectionResult {
316+
std::vector<AssociatedTypeInfo> AssociatedTypeInfos;
317+
std::vector<std::string> Errors;
318+
};
319+
300320
/// An implementation of MetadataReader's BuilderType concept for
301321
/// building TypeRefs, and parsing field metadata from any images
302322
/// it has been made aware of.
@@ -880,6 +900,7 @@ class TypeRefBuilder {
880900
void dumpTypeRef(RemoteRef<char> MangledName, std::ostream &stream,
881901
bool printTypeName = false);
882902
void dumpFieldSection(std::ostream &stream);
903+
AssociatedTypeCollectionResult collectAssociatedTypes(llvm::Optional<std::string> forMangledTypeName);
883904
void dumpAssociatedTypeSection(std::ostream &stream);
884905
void dumpBuiltinTypeSection(std::ostream &stream);
885906
void dumpCaptureSection(std::ostream &stream);

include/swift/StaticMirror/BinaryScanImpl.h

+11
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,15 @@ struct swift_static_mirror_conformance_info_s {
3030
swift_static_mirror_string_ref_t protocol_name;
3131
};
3232

33+
struct swift_static_mirror_type_alias_s {
34+
swift_static_mirror_string_ref_t type_alias_name;
35+
swift_static_mirror_string_ref_t substituted_type_name;
36+
swift_static_mirror_string_ref_t substituted_type_mangled_name;
37+
};
38+
39+
struct swift_static_mirror_associated_type_info_s {
40+
swift_static_mirror_string_ref_t mangled_type_name;
41+
swift_static_mirror_type_alias_set_t *type_alias_set;
42+
};
43+
3344
#endif // SWIFT_C_BINARY_SCAN_IMPL_H

include/swift/StaticMirror/BinaryScanningTool.h

+8
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ class BinaryScanningTool {
4646
reflection::ConformanceCollectionResult
4747
collectConformances(const std::vector<std::string> &protocolNames);
4848

49+
/// Collect all associated types of the specified type
50+
reflection::AssociatedTypeCollectionResult
51+
collectAssociatedTypes(const std::string &mangledTypeName);
52+
53+
/// Collect associated types of all discovered types
54+
reflection::AssociatedTypeCollectionResult
55+
collectAllAssociatedTypes();
56+
4957
private:
5058
// Note: binaryOrError and objectOrError own the memory for our ObjectFile;
5159
// once they go out of scope, we can no longer do anything.

lib/StaticMirror/BinaryScanningTool.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,14 @@ BinaryScanningTool::collectConformances(const std::vector<std::string> &protocol
7878
}
7979
}
8080

81+
AssociatedTypeCollectionResult
82+
BinaryScanningTool::collectAssociatedTypes(const std::string &mangledTypeName) {
83+
return Context->Builder.collectAssociatedTypes(mangledTypeName);
84+
}
85+
86+
AssociatedTypeCollectionResult
87+
BinaryScanningTool::collectAllAssociatedTypes() {
88+
return Context->Builder.collectAssociatedTypes(llvm::Optional<std::string>());
89+
}
8190
} // end namespace static_mirror
8291
} // end namespace swift

stdlib/public/Reflection/TypeRefBuilder.cpp

+58-17
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/Remote/MetadataReader.h"
2626
#include <iomanip>
2727
#include <iostream>
28+
#include <sstream>
2829

2930
using namespace swift;
3031
using namespace reflection;
@@ -457,32 +458,72 @@ void TypeRefBuilder::dumpFieldSection(std::ostream &stream) {
457458
}
458459
}
459460

460-
void TypeRefBuilder::dumpAssociatedTypeSection(std::ostream &stream) {
461+
AssociatedTypeCollectionResult TypeRefBuilder::collectAssociatedTypes(
462+
llvm::Optional<std::string> forMangledTypeName) {
463+
AssociatedTypeCollectionResult result;
461464
for (const auto &sections : ReflectionInfos) {
462465
for (auto descriptor : sections.AssociatedType) {
463-
auto conformingTypeNode = demangleTypeRef(
464-
readTypeRef(descriptor, descriptor->ConformingTypeName));
465-
auto conformingTypeName = nodeToString(conformingTypeNode);
466+
auto typeRef = readTypeRef(descriptor, descriptor->ConformingTypeName);
467+
auto typeName = nodeToString(demangleTypeRef(typeRef));
468+
auto optionalMangledTypeName = normalizeReflectionName(typeRef);
466469
auto protocolNode = demangleTypeRef(
467470
readTypeRef(descriptor, descriptor->ProtocolTypeName));
468471
auto protocolName = nodeToString(protocolNode);
469472
clearNodeFactory();
470-
471-
stream << "- " << conformingTypeName << " : " << protocolName << "\n";
472-
473-
for (const auto &associatedTypeRef : *descriptor.getLocalBuffer()) {
474-
auto associatedType = descriptor.getField(associatedTypeRef);
475-
476-
std::string name =
477-
getTypeRefString(readTypeRef(associatedType, associatedType->Name))
478-
.str();
479-
stream << "typealias " << name << " = ";
480-
dumpTypeRef(
481-
readTypeRef(associatedType, associatedType->SubstitutedTypeName),
482-
stream);
473+
if (optionalMangledTypeName.hasValue()) {
474+
auto mangledTypeName =
475+
optionalMangledTypeName.getValue().insert(0, "$s");
476+
if (forMangledTypeName.hasValue()) {
477+
if (mangledTypeName != forMangledTypeName.getValue())
478+
continue;
479+
}
480+
std::vector<AssociatedType> associatedTypes;
481+
for (const auto &associatedTypeRef : *descriptor.getLocalBuffer()) {
482+
auto associatedType = descriptor.getField(associatedTypeRef);
483+
std::string typealiasTypeName =
484+
getTypeRefString(
485+
readTypeRef(associatedType, associatedType->Name))
486+
.str();
487+
488+
std::string mangledSubstitutedTypeName =
489+
std::string(associatedType->SubstitutedTypeName);
490+
auto substitutedTypeRef =
491+
readTypeRef(associatedType, associatedType->SubstitutedTypeName);
492+
auto optionalMangledSubstitutedTypeName =
493+
normalizeReflectionName(substitutedTypeRef);
494+
if (optionalMangledSubstitutedTypeName.hasValue()) {
495+
mangledSubstitutedTypeName =
496+
"$s" + optionalMangledSubstitutedTypeName.getValue();
497+
}
498+
auto substitutedDemangleTree = demangleTypeRef(substitutedTypeRef);
499+
auto substitutedTypeName = nodeToString(substitutedDemangleTree);
500+
std::stringstream OS;
501+
dumpTypeRef(substitutedTypeRef, OS);
502+
associatedTypes.emplace_back(
503+
AssociatedType{typealiasTypeName, mangledSubstitutedTypeName,
504+
substitutedTypeName, OS.str()});
505+
}
506+
result.AssociatedTypeInfos.emplace_back(AssociatedTypeInfo{
507+
mangledTypeName, typeName, protocolName, associatedTypes});
483508
}
484509
}
485510
}
511+
return result;
512+
}
513+
514+
void TypeRefBuilder::dumpAssociatedTypeSection(std::ostream &stream) {
515+
auto associatedTypeCollectionResult =
516+
collectAssociatedTypes(llvm::Optional<std::string>());
517+
for (const auto &info : associatedTypeCollectionResult.AssociatedTypeInfos) {
518+
stream << "- " << info.FullyQualifiedName << " : "
519+
<< info.ProtocolFullyQualifiedName << "\n";
520+
for (const auto &typeAlias : info.AssociatedTypes) {
521+
stream << "typealias " << typeAlias.TypeAliasName << " = "
522+
<< typeAlias.SubstitutedTypeFullyQualifiedName << "\n";
523+
stream << typeAlias.SubstitutedTypeDiagnosticPrintName;
524+
}
525+
stream << "\n";
526+
}
486527
}
487528

488529
void TypeRefBuilder::dumpBuiltinTypeSection(std::ostream &stream) {

tools/libStaticMirror/libStaticMirror.cpp

+116-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include "swift/StaticMirror/BinaryScanningTool.h"
1919
#include "swift/StaticMirror/BinaryScanImpl.h"
2020
#include "swift/DependencyScan/StringUtils.h"
21-
//#include "swift/Option/Options.h"
2221

2322
// FIXME: Code duplication with StringUtils.cpp
2423
namespace swift {
@@ -136,3 +135,119 @@ void swift_static_mirror_conformances_set_dispose(
136135
delete[] set->conformances;
137136
delete set;
138137
}
138+
139+
static swift_static_mirror_associated_type_info_set_t *
140+
convertAssociatedTypeQueryResult(
141+
const swift::reflection::AssociatedTypeCollectionResult &scanResult) {
142+
swift_static_mirror_associated_type_info_set_t *result =
143+
new swift_static_mirror_associated_type_info_set_t;
144+
result->count = scanResult.AssociatedTypeInfos.size();
145+
result->associated_type_infos = new swift_static_mirror_associated_type_info_t
146+
[scanResult.AssociatedTypeInfos.size()];
147+
148+
int associatedTypeInfoIndex = 0;
149+
for (const auto &assocTypeInfo : scanResult.AssociatedTypeInfos) {
150+
swift_static_mirror_associated_type_info_s *info =
151+
new swift_static_mirror_associated_type_info_s;
152+
info->mangled_type_name = swift::c_string_utils::create_clone(
153+
assocTypeInfo.MangledTypeName.c_str());
154+
info->type_alias_set = new swift_static_mirror_type_alias_set_t;
155+
info->type_alias_set->count = assocTypeInfo.AssociatedTypes.size();
156+
info->type_alias_set->type_aliases =
157+
new swift_static_mirror_type_alias_t[assocTypeInfo.AssociatedTypes
158+
.size()];
159+
int typealiasIndex = 0;
160+
for (const auto &typeAliasInfo : assocTypeInfo.AssociatedTypes) {
161+
swift_static_mirror_type_alias_s *typealiasDetails =
162+
new swift_static_mirror_type_alias_s;
163+
typealiasDetails->type_alias_name = swift::c_string_utils::create_clone(
164+
typeAliasInfo.TypeAliasName.c_str());
165+
typealiasDetails->substituted_type_name =
166+
swift::c_string_utils::create_clone(
167+
typeAliasInfo.SubstitutedTypeFullyQualifiedName.c_str());
168+
typealiasDetails->substituted_type_mangled_name =
169+
swift::c_string_utils::create_clone(
170+
typeAliasInfo.SubstitutedTypeMangledName.c_str());
171+
info->type_alias_set->type_aliases[typealiasIndex] =
172+
typealiasDetails;
173+
typealiasIndex += 1;
174+
}
175+
result->associated_type_infos[associatedTypeInfoIndex] = info;
176+
associatedTypeInfoIndex += 1;
177+
}
178+
return result;
179+
}
180+
181+
swift_static_mirror_associated_type_info_set_t *
182+
swift_static_mirror_associated_type_info_set_create(
183+
swift_static_mirror_t static_mirror, const char *forTypeName) {
184+
BinaryScanningTool *scanTool = unwrap(static_mirror);
185+
auto scanResult = scanTool->collectAssociatedTypes(forTypeName);
186+
return convertAssociatedTypeQueryResult(scanResult);
187+
}
188+
189+
/// Identify and collect associated types of all discovered types.
190+
swift_static_mirror_associated_type_info_set_t *
191+
swift_static_mirror_all_associated_type_info_set_create(
192+
swift_static_mirror_t static_mirror) {
193+
BinaryScanningTool *scanTool = unwrap(static_mirror);
194+
auto scanResult = scanTool->collectAllAssociatedTypes();
195+
return convertAssociatedTypeQueryResult(scanResult);
196+
}
197+
198+
// swift_static_mirror_associated_type query methods
199+
swift_static_mirror_string_ref_t
200+
swift_static_mirror_type_alias_get_type_alias_name(
201+
swift_static_mirror_type_alias_t type_alias) {
202+
return type_alias->type_alias_name;
203+
}
204+
swift_static_mirror_string_ref_t
205+
swift_static_mirror_type_alias_get_substituted_type_name(
206+
swift_static_mirror_type_alias_t type_alias) {
207+
return type_alias->substituted_type_name;
208+
}
209+
swift_static_mirror_string_ref_t
210+
swift_static_mirror_type_alias_get_substituted_type_mangled_name(
211+
swift_static_mirror_type_alias_t type_alias) {
212+
return type_alias->substituted_type_mangled_name;
213+
}
214+
215+
// swift_static_mirror_associated_type_info query methods
216+
swift_static_mirror_string_ref_t
217+
swift_static_mirror_associated_type_info_get_mangled_type_name(
218+
swift_static_mirror_associated_type_info_t associated_type_info) {
219+
return associated_type_info->mangled_type_name;
220+
}
221+
swift_static_mirror_type_alias_set_t*
222+
swift_static_mirror_associated_type_info_get_type_alias_set(
223+
swift_static_mirror_associated_type_info_t associated_type_info) {
224+
return associated_type_info->type_alias_set;
225+
}
226+
227+
void swift_static_mirror_type_alias_dispose(swift_static_mirror_type_alias_t type_alias) {
228+
swift_static_mirror_string_dispose(type_alias->substituted_type_mangled_name);
229+
swift_static_mirror_string_dispose(type_alias->substituted_type_name);
230+
swift_static_mirror_string_dispose(type_alias->type_alias_name);
231+
delete type_alias;
232+
}
233+
234+
void swift_static_mirror_type_alias_set_dispose(swift_static_mirror_type_alias_set_t *type_alias_set) {
235+
for (size_t i = 0; i < type_alias_set->count; ++i) {
236+
swift_static_mirror_type_alias_dispose(type_alias_set->type_aliases[i]);
237+
}
238+
delete[] type_alias_set->type_aliases;
239+
delete type_alias_set;
240+
}
241+
242+
void swift_static_mirror_associated_type_info_dispose(swift_static_mirror_associated_type_info_t associated_type_info) {
243+
swift_static_mirror_string_dispose(associated_type_info->mangled_type_name);
244+
swift_static_mirror_type_alias_set_dispose(associated_type_info->type_alias_set);
245+
}
246+
247+
void swift_static_mirror_associated_type_info_set_dispose(swift_static_mirror_associated_type_info_set_t *associated_type_info_set) {
248+
for (size_t i = 0; i < associated_type_info_set->count; ++i) {
249+
swift_static_mirror_associated_type_info_dispose(associated_type_info_set->associated_type_infos[i]);
250+
}
251+
delete[] associated_type_info_set->associated_type_infos;
252+
delete associated_type_info_set;
253+
}

0 commit comments

Comments
 (0)