Skip to content

Commit 4ac647b

Browse files
authored
Merge pull request #41680 from artemcm/StaticMirrorFields
[Static Mirror] Refactor gathering of field types from a binary and add SwiftStaticMirror entry-points for collection of field types.
2 parents 25d9f37 + 02e1588 commit 4ac647b

File tree

8 files changed

+412
-72
lines changed

8 files changed

+412
-72
lines changed

include/swift-c/StaticMirror/BinaryScan.h

Lines changed: 76 additions & 20 deletions
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 2 // Added associated-type gather
28+
#define SWIFTSTATICMIRROR_VERSION_MINOR 3 // Added filed type info gather
2929

3030
SWIFTSTATICMIRROR_BEGIN_DECLS
3131

@@ -42,6 +42,18 @@ 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 a field info (property type or enum case)
46+
typedef struct swift_static_mirror_field_info_s
47+
*swift_static_mirror_field_info_t;
48+
49+
/// Opaque container to a property type info
50+
typedef struct swift_static_mirror_property_info_s
51+
*swift_static_mirror_property_info_t;
52+
53+
/// Opaque container to an enum case info
54+
typedef struct swift_static_mirror_enum_case_info_s
55+
*swift_static_mirror_enum_case_info_t;
56+
4557
/// Opaque container to details of an associated type specification.
4658
typedef struct swift_static_mirror_type_alias_s
4759
*swift_static_mirror_type_alias_t;
@@ -55,7 +67,6 @@ typedef struct {
5567
size_t count;
5668
} swift_static_mirror_type_alias_set_t;
5769

58-
5970
typedef struct {
6071
swift_static_mirror_associated_type_info_t *associated_type_infos;
6172
size_t count;
@@ -66,26 +77,35 @@ typedef struct {
6677
size_t count;
6778
} swift_static_mirror_conformances_set_t;
6879

80+
typedef struct {
81+
swift_static_mirror_property_info_t *properties;
82+
size_t count;
83+
} swift_static_mirror_property_info_set_t;
6984

70-
// swift_static_mirror_conformance_info query methods
85+
typedef struct {
86+
swift_static_mirror_enum_case_info_t *enum_cases;
87+
size_t count;
88+
} swift_static_mirror_enum_case_info_set_t;
89+
90+
typedef struct {
91+
swift_static_mirror_field_info_t *field_infos;
92+
size_t count;
93+
} swift_static_mirror_field_info_set_t;
7194

95+
// swift_static_mirror_conformance_info query methods
7296
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
7397
swift_static_mirror_conformance_info_get_type_name(
7498
swift_static_mirror_conformance_info_t);
75-
7699
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
77100
swift_static_mirror_conformance_info_get_protocol_name(
78101
swift_static_mirror_conformance_info_t);
79-
80102
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
81103
swift_static_mirror_conformance_info_get_mangled_type_name(
82104
swift_static_mirror_conformance_info_t);
105+
SWIFTSTATICMIRROR_PUBLIC void swift_static_mirror_conformance_info_dispose(
106+
swift_static_mirror_conformance_info_t);
83107

84-
SWIFTSTATICMIRROR_PUBLIC void
85-
swift_static_mirror_conformance_info_dispose(
86-
swift_static_mirror_conformance_info_t);
87-
88-
// swift_static_mirror_associated_type query methods
108+
// swift_static_mirror_associated_type_info query methods
89109
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
90110
swift_static_mirror_type_alias_get_type_alias_name(
91111
swift_static_mirror_type_alias_t);
@@ -100,41 +120,77 @@ SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
100120
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
101121
swift_static_mirror_associated_type_info_get_mangled_type_name(
102122
swift_static_mirror_associated_type_info_t);
103-
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_type_alias_set_t*
123+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_type_alias_set_t *
104124
swift_static_mirror_associated_type_info_get_type_alias_set(
105125
swift_static_mirror_associated_type_info_t);
106126

127+
// swift_static_mirror_field_info query methods
128+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
129+
swift_static_mirror_field_info_get_mangled_type_name(
130+
swift_static_mirror_field_info_t);
131+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_property_info_set_t *
132+
swift_static_mirror_field_info_get_property_info_set(
133+
swift_static_mirror_field_info_t);
134+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_enum_case_info_set_t *
135+
swift_static_mirror_field_info_get_enum_case_info_set(
136+
swift_static_mirror_field_info_t);
137+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
138+
swift_static_mirror_property_info_get_label(
139+
swift_static_mirror_property_info_t);
140+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
141+
swift_static_mirror_property_info_get_type_name(
142+
swift_static_mirror_property_info_t);
143+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
144+
swift_static_mirror_property_info_get_mangled_type_name(
145+
swift_static_mirror_property_info_t);
146+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_string_ref_t
147+
swift_static_mirror_enum_case_info_get_label(
148+
swift_static_mirror_enum_case_info_t);
149+
107150
/// Create an \c swift_static_mirror_t instance.
108151
/// The returned \c swift_static_mirror_t is owned by the caller and must be
109152
/// disposed of using \c swift_static_mirror_dispose .
110153
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_t
111154
swift_static_mirror_create(int, const char **, const char *);
112155

113156
SWIFTSTATICMIRROR_PUBLIC void
114-
swift_static_mirror_dispose(swift_static_mirror_t);
157+
swift_static_mirror_dispose(swift_static_mirror_t);
115158

116159
/// Identify and collect all types conforming to any of the protocol names
117160
/// specified as arguments
118161
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_conformances_set_t *
119-
swift_static_mirror_conformances_set_create(
120-
swift_static_mirror_t, int, const char **);
162+
swift_static_mirror_conformances_set_create(swift_static_mirror_t, int,
163+
const char **);
121164

122165
SWIFTSTATICMIRROR_PUBLIC void swift_static_mirror_conformances_set_dispose(
123166
swift_static_mirror_conformances_set_t *);
124167

125-
/// Identify and collect all associated types of a given input type (by mangled name)
168+
/// Identify and collect all associated types of a given input type (by mangled
169+
/// name)
126170
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 *);
171+
swift_static_mirror_associated_type_info_set_create(swift_static_mirror_t,
172+
const char *);
129173

130174
/// Identify and collect associated types of all discovered types.
131175
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);
176+
swift_static_mirror_all_associated_type_info_set_create(
177+
swift_static_mirror_t);
134178

135-
SWIFTSTATICMIRROR_PUBLIC void swift_static_mirror_associated_type_info_set_dispose(
179+
SWIFTSTATICMIRROR_PUBLIC void
180+
swift_static_mirror_associated_type_info_set_dispose(
136181
swift_static_mirror_associated_type_info_set_t *);
137182

183+
/// Identify and collect all field types of a given input type (by mangled name)
184+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_field_info_set_t *
185+
swift_static_mirror_field_info_set_create(swift_static_mirror_t, const char *);
186+
187+
/// Identify and collect field types of all discovered types.
188+
SWIFTSTATICMIRROR_PUBLIC swift_static_mirror_field_info_set_t *
189+
swift_static_mirror_all_field_info_set_create(swift_static_mirror_t);
190+
191+
SWIFTSTATICMIRROR_PUBLIC void swift_static_mirror_field_info_set_dispose(
192+
swift_static_mirror_field_info_set_t *);
193+
138194
SWIFTSTATICMIRROR_END_DECLS
139195

140196
#endif // SWIFT_C_BINARY_SCAN_H

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ struct AssociatedType {
304304
std::string SubstitutedTypeDiagnosticPrintName;
305305
};
306306

307-
/// Info about a given type's associated type, as read out from an Image
307+
/// Info about all of a given type's associated types, as read out from an Image
308308
struct AssociatedTypeInfo {
309309
std::string MangledTypeName;
310310
std::string FullyQualifiedName;
@@ -317,6 +317,30 @@ struct AssociatedTypeCollectionResult {
317317
std::vector<std::string> Errors;
318318
};
319319

320+
struct PropertyTypeInfo {
321+
std::string Label;
322+
std::string TypeMangledName;
323+
std::string TypeFullyQualifiedName;
324+
std::string TypeDiagnosticPrintName;
325+
};
326+
327+
struct EnumCaseInfo {
328+
std::string Label;
329+
};
330+
331+
/// Info about all of a given type's fields, as read out from an Image
332+
struct FieldMetadata {
333+
std::string MangledTypeName;
334+
std::string FullyQualifiedName;
335+
std::vector<PropertyTypeInfo> Properties;
336+
std::vector<EnumCaseInfo> EnumCases;
337+
};
338+
339+
struct FieldTypeCollectionResult {
340+
std::vector<FieldMetadata> FieldInfos;
341+
std::vector<std::string> Errors;
342+
};
343+
320344
/// An implementation of MetadataReader's BuilderType concept for
321345
/// building TypeRefs, and parsing field metadata from any images
322346
/// it has been made aware of.
@@ -899,6 +923,7 @@ class TypeRefBuilder {
899923

900924
void dumpTypeRef(RemoteRef<char> MangledName, std::ostream &stream,
901925
bool printTypeName = false);
926+
FieldTypeCollectionResult collectFieldTypes(llvm::Optional<std::string> forMangledTypeName);
902927
void dumpFieldSection(std::ostream &stream);
903928
AssociatedTypeCollectionResult collectAssociatedTypes(llvm::Optional<std::string> forMangledTypeName);
904929
void dumpAssociatedTypeSection(std::ostream &stream);

include/swift/StaticMirror/BinaryScanImpl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,20 @@ struct swift_static_mirror_associated_type_info_s {
4141
swift_static_mirror_type_alias_set_t *type_alias_set;
4242
};
4343

44+
struct swift_static_mirror_enum_case_info_s {
45+
swift_static_mirror_string_ref_t label;
46+
};
47+
48+
struct swift_static_mirror_property_info_s {
49+
swift_static_mirror_string_ref_t label;
50+
swift_static_mirror_string_ref_t type_name;
51+
swift_static_mirror_string_ref_t mangled_type_name;
52+
};
53+
54+
struct swift_static_mirror_field_info_s {
55+
swift_static_mirror_string_ref_t mangled_type_name;
56+
swift_static_mirror_property_info_set_t *property_set;
57+
swift_static_mirror_enum_case_info_set_t *enum_case_set;
58+
};
59+
4460
#endif // SWIFT_C_BINARY_SCAN_IMPL_H

include/swift/StaticMirror/BinaryScanningTool.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ class BinaryScanningTool {
5454
reflection::AssociatedTypeCollectionResult
5555
collectAllAssociatedTypes();
5656

57+
/// Collect all field type infos of the specified type
58+
reflection::FieldTypeCollectionResult
59+
collectFieldTypes(const std::string &mangledTypeName);
60+
61+
/// Collect field type infos of all discovered types
62+
reflection::FieldTypeCollectionResult
63+
collectAllFieldTypes();
64+
5765
private:
5866
// Note: binaryOrError and objectOrError own the memory for our ObjectFile;
5967
// once they go out of scope, we can no longer do anything.

lib/StaticMirror/BinaryScanningTool.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,15 @@ AssociatedTypeCollectionResult
8787
BinaryScanningTool::collectAllAssociatedTypes() {
8888
return Context->Builder.collectAssociatedTypes(llvm::Optional<std::string>());
8989
}
90+
91+
FieldTypeCollectionResult
92+
BinaryScanningTool::collectFieldTypes(const std::string &mangledTypeName) {
93+
return Context->Builder.collectFieldTypes(mangledTypeName);
94+
}
95+
96+
FieldTypeCollectionResult
97+
BinaryScanningTool::collectAllFieldTypes() {
98+
return Context->Builder.collectFieldTypes(llvm::Optional<std::string>());
99+
}
90100
} // end namespace static_mirror
91101
} // end namespace swift

stdlib/public/Reflection/TypeRefBuilder.cpp

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -432,30 +432,76 @@ void TypeRefBuilder::dumpTypeRef(RemoteRef<char> MangledName,
432432
stream << "\n";
433433
}
434434

435-
void TypeRefBuilder::dumpFieldSection(std::ostream &stream) {
435+
FieldTypeCollectionResult TypeRefBuilder::collectFieldTypes(
436+
llvm::Optional<std::string> forMangledTypeName) {
437+
FieldTypeCollectionResult result;
436438
for (const auto &sections : ReflectionInfos) {
437439
for (auto descriptor : sections.Field) {
438-
auto TypeDemangling =
439-
demangleTypeRef(readTypeRef(descriptor, descriptor->MangledTypeName));
440-
auto TypeName = nodeToString(TypeDemangling);
440+
auto typeRef = readTypeRef(descriptor, descriptor->MangledTypeName);
441+
auto typeName = nodeToString(demangleTypeRef(typeRef));
442+
auto optionalMangledTypeName = normalizeReflectionName(typeRef);
441443
clearNodeFactory();
442-
stream << TypeName.c_str() << "\n";
443-
for (size_t i = 0; i < TypeName.size(); ++i)
444-
stream << "-";
445-
stream << "\n";
446-
for (auto &fieldRef : *descriptor.getLocalBuffer()) {
447-
auto field = descriptor.getField(fieldRef);
448-
auto fieldName = getTypeRefString(readTypeRef(field, field->FieldName));
449-
stream.write(fieldName.data(), fieldName.size());
450-
if (field->hasMangledTypeName()) {
451-
stream << ": ";
452-
dumpTypeRef(readTypeRef(field, field->MangledTypeName), stream);
453-
} else {
454-
stream << "\n\n";
444+
if (optionalMangledTypeName.hasValue()) {
445+
auto mangledTypeName =
446+
optionalMangledTypeName.getValue().insert(0, "$s");
447+
if (forMangledTypeName.hasValue()) {
448+
if (mangledTypeName != forMangledTypeName.getValue())
449+
continue;
455450
}
451+
452+
std::vector<PropertyTypeInfo> properties;
453+
std::vector<EnumCaseInfo> enumCases;
454+
for (auto &fieldRef : *descriptor.getLocalBuffer()) {
455+
auto field = descriptor.getField(fieldRef);
456+
auto fieldName = getTypeRefString(readTypeRef(field, field->FieldName));
457+
if (field->hasMangledTypeName()) {
458+
std::string mangledFieldTypeName =
459+
std::string(field->MangledTypeName);
460+
auto fieldTypeRef = readTypeRef(field, field->MangledTypeName);
461+
auto optionalMangledfieldTypeName =
462+
normalizeReflectionName(fieldTypeRef);
463+
if (optionalMangledfieldTypeName.hasValue()) {
464+
mangledFieldTypeName =
465+
"$s" + optionalMangledfieldTypeName.getValue();
466+
}
467+
auto fieldTypeDemangleTree = demangleTypeRef(fieldTypeRef);
468+
auto fieldTypeName = nodeToString(fieldTypeDemangleTree);
469+
std::stringstream OS;
470+
dumpTypeRef(fieldTypeRef, OS);
471+
properties.emplace_back(PropertyTypeInfo{fieldName.str(),
472+
mangledFieldTypeName,
473+
fieldTypeName, OS.str()});
474+
} else {
475+
enumCases.emplace_back(EnumCaseInfo{fieldName.str()});
476+
}
477+
}
478+
result.FieldInfos.emplace_back(FieldMetadata{
479+
mangledTypeName, typeName, properties, enumCases});
456480
}
457481
}
458482
}
483+
484+
return result;
485+
}
486+
487+
void TypeRefBuilder::dumpFieldSection(std::ostream &stream) {
488+
auto fieldInfoCollectionResult =
489+
collectFieldTypes(llvm::Optional<std::string>());
490+
for (const auto &info : fieldInfoCollectionResult.FieldInfos) {
491+
stream << info.FullyQualifiedName << "\n";
492+
for (size_t i = 0; i < info.FullyQualifiedName.size(); ++i)
493+
stream << "-";
494+
stream << "\n";
495+
for (const auto &field : info.Properties) {
496+
stream << field.Label;
497+
stream << ": ";
498+
stream << field.TypeDiagnosticPrintName;
499+
}
500+
for (const auto &field : info.EnumCases) {
501+
stream << field.Label;
502+
stream << "\n\n";
503+
}
504+
}
459505
}
460506

461507
AssociatedTypeCollectionResult TypeRefBuilder::collectAssociatedTypes(

0 commit comments

Comments
 (0)