Skip to content

Commit b2c821a

Browse files
committed
[llvm][Support] Introduced scalar type names in YAMLGenerateSchema
Since now, when creating a YAML Schema, the type of all scalars is a 'string', this may be a bit strange. For example if you start typing number in IDE, it will complain that 'string' was expected. This patch fixes it by introducing new optional TypeNameTrait. Is is optional in order not to break backward compatibility.
1 parent 7a22c9c commit b2c821a

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed

llvm/include/llvm/Support/YAMLTraits.h

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ enum class QuotingType { None, Single, Double };
145145
/// return StringRef();
146146
/// }
147147
/// static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
148+
/// static constexpr StringRef typeName = "string";
148149
/// };
149150
template <typename T, typename Enable = void> struct ScalarTraits {
150151
// Must provide:
@@ -158,6 +159,9 @@ template <typename T, typename Enable = void> struct ScalarTraits {
158159
//
159160
// Function to determine if the value should be quoted.
160161
// static QuotingType mustQuote(StringRef);
162+
//
163+
// Optional, for GeneratingSchema:
164+
// static constexpr StringRef typeName = "string";
161165
};
162166

163167
/// This class should be specialized by type that requires custom conversion
@@ -175,6 +179,7 @@ template <typename T, typename Enable = void> struct ScalarTraits {
175179
/// // return empty string on success, or error string
176180
/// return StringRef();
177181
/// }
182+
/// static constexpr StringRef typeName = "string";
178183
/// };
179184
template <typename T> struct BlockScalarTraits {
180185
// Must provide:
@@ -189,6 +194,7 @@ template <typename T> struct BlockScalarTraits {
189194
// Optional:
190195
// static StringRef inputTag(T &Val, std::string Tag)
191196
// static void outputTag(const T &Val, raw_ostream &Out)
197+
// static constexpr StringRef typeName = "string";
192198
};
193199

194200
/// This class should be specialized by type that requires custom conversion
@@ -211,6 +217,7 @@ template <typename T> struct BlockScalarTraits {
211217
/// static QuotingType mustQuote(const MyType &Value, StringRef) {
212218
/// return QuotingType::Single;
213219
/// }
220+
/// static constexpr StringRef typeName = "integer";
214221
/// };
215222
template <typename T> struct TaggedScalarTraits {
216223
// Must provide:
@@ -226,6 +233,9 @@ template <typename T> struct TaggedScalarTraits {
226233
//
227234
// Function to determine if the value should be quoted.
228235
// static QuotingType mustQuote(const T &Value, StringRef Scalar);
236+
//
237+
// Optional:
238+
// static constexpr StringRef typeName = "string";
229239
};
230240

231241
/// This class should be specialized by any type that needs to be converted
@@ -442,6 +452,14 @@ template <class T> struct has_CustomMappingTraits {
442452
is_detected<check, CustomMappingTraits<T>>::value;
443453
};
444454

455+
// Test if typeName is defined on type T.
456+
template <typename T> struct has_TypeNameTraits {
457+
template <class U>
458+
using check = std::is_same<decltype(&U::typeName), StringRef>;
459+
460+
static constexpr bool value = is_detected<check, T>::value;
461+
};
462+
445463
// Test if flow is defined on type T.
446464
template <typename T> struct has_FlowTraits {
447465
template <class U> using check = decltype(&U::flow);
@@ -925,13 +943,19 @@ std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
925943
ScalarTraits<T>::output(Val, io.getContext(), Buffer);
926944
StringRef Str = Buffer.str();
927945
io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
928-
} else {
946+
} else if (io.getKind() == IOKind::Inputting) {
929947
StringRef Str;
930948
io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
931949
StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
932950
if (!Result.empty()) {
933951
io.setError(Twine(Result));
934952
}
953+
} else {
954+
StringRef TypeName = "string";
955+
if constexpr (has_TypeNameTraits<ScalarTraits<T>>::value) {
956+
TypeName = ScalarTraits<T>::typeName;
957+
}
958+
io.scalarString(TypeName, QuotingType::None);
935959
}
936960
}
937961

@@ -944,13 +968,19 @@ yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
944968
BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
945969
StringRef Str(Storage);
946970
YamlIO.blockScalarString(Str);
947-
} else {
971+
} else if (YamlIO.getKind() == IOKind::Inputting) {
948972
StringRef Str;
949973
YamlIO.blockScalarString(Str);
950974
StringRef Result =
951975
BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
952976
if (!Result.empty())
953977
YamlIO.setError(Twine(Result));
978+
} else {
979+
StringRef TypeName = "string";
980+
if constexpr (has_TypeNameTraits<ScalarTraits<T>>::value) {
981+
TypeName = ScalarTraits<T>::typeName;
982+
}
983+
YamlIO.blockScalarString(TypeName);
954984
}
955985
}
956986

@@ -966,7 +996,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
966996
StringRef ScalarStr(ScalarStorage);
967997
io.scalarString(ScalarStr,
968998
TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
969-
} else {
999+
} else if (io.getKind() == IOKind::Inputting) {
9701000
std::string Tag;
9711001
io.scalarTag(Tag);
9721002
StringRef Str;
@@ -976,6 +1006,12 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
9761006
if (!Result.empty()) {
9771007
io.setError(Twine(Result));
9781008
}
1009+
} else {
1010+
StringRef TypeName = "string";
1011+
if constexpr (has_TypeNameTraits<ScalarTraits<T>>::value) {
1012+
TypeName = ScalarTraits<T>::typeName;
1013+
}
1014+
io.scalarString(TypeName, QuotingType::None);
9791015
}
9801016
}
9811017

@@ -1056,11 +1092,15 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
10561092
io.beginMapping();
10571093
CustomMappingTraits<T>::output(io, Val);
10581094
io.endMapping();
1059-
} else {
1095+
} else if (io.getKind() == IOKind::Inputting) {
10601096
io.beginMapping();
10611097
for (StringRef key : io.keys())
10621098
CustomMappingTraits<T>::inputOne(io, key, Val);
10631099
io.endMapping();
1100+
} else {
1101+
io.beginMapping();
1102+
CustomMappingTraits<T>::inputOne(io, "additionalProperties", Val);
1103+
io.endMapping();
10641104
}
10651105
}
10661106

@@ -1121,6 +1161,7 @@ template <> struct ScalarTraits<bool> {
11211161
LLVM_ABI static void output(const bool &, void *, raw_ostream &);
11221162
LLVM_ABI static StringRef input(StringRef, void *, bool &);
11231163
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1164+
static constexpr StringRef typeName = "boolean";
11241165
};
11251166

11261167
template <> struct ScalarTraits<StringRef> {
@@ -1139,60 +1180,70 @@ template <> struct ScalarTraits<uint8_t> {
11391180
LLVM_ABI static void output(const uint8_t &, void *, raw_ostream &);
11401181
LLVM_ABI static StringRef input(StringRef, void *, uint8_t &);
11411182
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1183+
static constexpr StringRef typeName = "integer";
11421184
};
11431185

11441186
template <> struct ScalarTraits<uint16_t> {
11451187
LLVM_ABI static void output(const uint16_t &, void *, raw_ostream &);
11461188
LLVM_ABI static StringRef input(StringRef, void *, uint16_t &);
11471189
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1190+
static constexpr StringRef typeName = "integer";
11481191
};
11491192

11501193
template <> struct ScalarTraits<uint32_t> {
11511194
LLVM_ABI static void output(const uint32_t &, void *, raw_ostream &);
11521195
LLVM_ABI static StringRef input(StringRef, void *, uint32_t &);
11531196
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1197+
static constexpr StringRef typeName = "integer";
11541198
};
11551199

11561200
template <> struct ScalarTraits<uint64_t> {
11571201
LLVM_ABI static void output(const uint64_t &, void *, raw_ostream &);
11581202
LLVM_ABI static StringRef input(StringRef, void *, uint64_t &);
11591203
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1204+
static constexpr StringRef typeName = "integer";
11601205
};
11611206

11621207
template <> struct ScalarTraits<int8_t> {
11631208
LLVM_ABI static void output(const int8_t &, void *, raw_ostream &);
11641209
LLVM_ABI static StringRef input(StringRef, void *, int8_t &);
11651210
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1211+
static constexpr StringRef typeName = "integer";
11661212
};
11671213

11681214
template <> struct ScalarTraits<int16_t> {
11691215
LLVM_ABI static void output(const int16_t &, void *, raw_ostream &);
11701216
LLVM_ABI static StringRef input(StringRef, void *, int16_t &);
11711217
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1218+
static constexpr StringRef typeName = "integer";
11721219
};
11731220

11741221
template <> struct ScalarTraits<int32_t> {
11751222
LLVM_ABI static void output(const int32_t &, void *, raw_ostream &);
11761223
LLVM_ABI static StringRef input(StringRef, void *, int32_t &);
11771224
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1225+
static constexpr StringRef typeName = "integer";
11781226
};
11791227

11801228
template <> struct ScalarTraits<int64_t> {
11811229
LLVM_ABI static void output(const int64_t &, void *, raw_ostream &);
11821230
LLVM_ABI static StringRef input(StringRef, void *, int64_t &);
11831231
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1232+
static constexpr StringRef typeName = "integer";
11841233
};
11851234

11861235
template <> struct ScalarTraits<float> {
11871236
LLVM_ABI static void output(const float &, void *, raw_ostream &);
11881237
LLVM_ABI static StringRef input(StringRef, void *, float &);
11891238
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1239+
static constexpr StringRef typeName = "number";
11901240
};
11911241

11921242
template <> struct ScalarTraits<double> {
11931243
LLVM_ABI static void output(const double &, void *, raw_ostream &);
11941244
LLVM_ABI static StringRef input(StringRef, void *, double &);
11951245
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1246+
static constexpr StringRef typeName = "number";
11961247
};
11971248

11981249
// For endian types, we use existing scalar Traits class for the underlying
@@ -1220,6 +1271,10 @@ struct ScalarTraits<support::detail::packed_endian_specific_integral<
12201271
static QuotingType mustQuote(StringRef Str) {
12211272
return ScalarTraits<value_type>::mustQuote(Str);
12221273
}
1274+
1275+
static constexpr StringRef typeName = has_TypeNameTraits<value_type>::value
1276+
? ScalarTraits<value_type>::typeName
1277+
: "string";
12231278
};
12241279

12251280
template <typename value_type, llvm::endianness endian, size_t alignment>
@@ -1652,24 +1707,28 @@ template <> struct ScalarTraits<Hex8> {
16521707
LLVM_ABI static void output(const Hex8 &, void *, raw_ostream &);
16531708
LLVM_ABI static StringRef input(StringRef, void *, Hex8 &);
16541709
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1710+
static constexpr StringRef typeName = "integer";
16551711
};
16561712

16571713
template <> struct ScalarTraits<Hex16> {
16581714
LLVM_ABI static void output(const Hex16 &, void *, raw_ostream &);
16591715
LLVM_ABI static StringRef input(StringRef, void *, Hex16 &);
16601716
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1717+
static constexpr StringRef typeName = "integer";
16611718
};
16621719

16631720
template <> struct ScalarTraits<Hex32> {
16641721
LLVM_ABI static void output(const Hex32 &, void *, raw_ostream &);
16651722
LLVM_ABI static StringRef input(StringRef, void *, Hex32 &);
16661723
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1724+
static constexpr StringRef typeName = "integer";
16671725
};
16681726

16691727
template <> struct ScalarTraits<Hex64> {
16701728
LLVM_ABI static void output(const Hex64 &, void *, raw_ostream &);
16711729
LLVM_ABI static StringRef input(StringRef, void *, Hex64 &);
16721730
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1731+
static constexpr StringRef typeName = "integer";
16731732
};
16741733

16751734
template <> struct ScalarTraits<VersionTuple> {

llvm/lib/Support/YAMLGenerateSchema.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ void GenerateSchema::endBitSetScalar() { endEnumScalar(); }
172172
void GenerateSchema::scalarString(StringRef &Val, QuotingType) {
173173
Schema *Top = getTopSchema();
174174
assert(Top);
175-
TypeProperty *Type = createProperty<TypeProperty>("string");
175+
TypeProperty *Type = createProperty<TypeProperty>(Val);
176176
Top->emplace_back(Type);
177177
}
178178

@@ -224,7 +224,6 @@ json::Value GenerateSchema::AdditionalPropertiesProperty::toJSON() const {
224224
return Value->toJSON();
225225
}
226226

227-
228227
json::Value GenerateSchema::RequiredProperty::toJSON() const {
229228
json::Array JSONArray;
230229
for (StringRef Value : *this) {

llvm/unittests/Support/YAMLGenerateSchemaTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ TEST(ObjectYAMLGenerateSchema, SimpleSchema) {
8181
],
8282
"properties": {
8383
"age": {
84-
"type": "string"
84+
"type": "integer"
8585
},
8686
"babies": {
8787
"flowStyle": "block",

0 commit comments

Comments
 (0)