Skip to content

Conversation

@tgs-sc
Copy link
Contributor

@tgs-sc tgs-sc commented Oct 23, 2025

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.

This PR depends on #133284

@llvmbot
Copy link
Member

llvmbot commented Oct 23, 2025

@llvm/pr-subscribers-llvm-support

Author: Timur Golubovich (tgs-sc)

Changes

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.

This PR depends on #133284


Patch is 45.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/164826.diff

8 Files Affected:

  • (added) llvm/include/llvm/Support/YAMLGenerateSchema.h (+400)
  • (modified) llvm/include/llvm/Support/YAMLTraits.h (+109-29)
  • (modified) llvm/lib/Support/CMakeLists.txt (+1)
  • (added) llvm/lib/Support/YAMLGenerateSchema.cpp (+285)
  • (modified) llvm/lib/Support/YAMLTraits.cpp (+4)
  • (modified) llvm/unittests/Support/CMakeLists.txt (+1)
  • (added) llvm/unittests/Support/YAMLGenerateSchemaTest.cpp (+124)
  • (modified) llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn (+1)
diff --git a/llvm/include/llvm/Support/YAMLGenerateSchema.h b/llvm/include/llvm/Support/YAMLGenerateSchema.h
new file mode 100644
index 0000000000000..ce699092c0e8e
--- /dev/null
+++ b/llvm/include/llvm/Support/YAMLGenerateSchema.h
@@ -0,0 +1,400 @@
+//===- llvm/Support/YAMLGenerateSchema.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_YAMLGENERATE_SCHEMA_H
+#define LLVM_SUPPORT_YAMLGENERATE_SCHEMA_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/YAMLTraits.h"
+
+namespace llvm {
+
+namespace json {
+class Value;
+}
+
+namespace yaml {
+
+class GenerateSchema : public IO {
+public:
+  GenerateSchema(raw_ostream &RO);
+  ~GenerateSchema() override = default;
+
+  IOKind getKind() const override;
+  bool outputting() const override;
+  bool mapTag(StringRef, bool) override;
+  void beginMapping() override;
+  void endMapping() override;
+  bool preflightKey(StringRef, bool, bool, bool &, void *&) override;
+  void postflightKey(void *) override;
+  std::vector<StringRef> keys() override;
+  void beginFlowMapping() override;
+  void endFlowMapping() override;
+  unsigned beginSequence() override;
+  void endSequence() override;
+  bool preflightElement(unsigned, void *&) override;
+  void postflightElement(void *) override;
+  unsigned beginFlowSequence() override;
+  bool preflightFlowElement(unsigned, void *&) override;
+  void postflightFlowElement(void *) override;
+  void endFlowSequence() override;
+  void beginEnumScalar() override;
+  bool matchEnumScalar(StringRef, bool) override;
+  bool matchEnumFallback() override;
+  void endEnumScalar() override;
+  bool beginBitSetScalar(bool &) override;
+  bool bitSetMatch(StringRef, bool) override;
+  void endBitSetScalar() override;
+  void scalarString(StringRef &, QuotingType) override;
+  void blockScalarString(StringRef &) override;
+  void scalarTag(std::string &) override;
+  NodeKind getNodeKind() override;
+  void setError(const Twine &message) override;
+  std::error_code error() override;
+  bool canElideEmptySequence() override;
+
+  bool preflightDocument();
+  void postflightDocument();
+
+  class SchemaNode {
+  public:
+    virtual json::Value toJSON() const = 0;
+
+    virtual ~SchemaNode() = default;
+  };
+
+  enum class PropertyKind : uint8_t {
+    UserDefined,
+    Properties,
+    AdditionalProperties,
+    Required,
+    Optional,
+    Type,
+    Enum,
+    Items,
+    FlowStyle,
+  };
+
+  class SchemaProperty : public SchemaNode {
+    StringRef Name;
+    PropertyKind Kind;
+
+  public:
+    SchemaProperty(StringRef Name, PropertyKind Kind)
+        : Name(Name), Kind(Kind) {}
+
+    PropertyKind getKind() const { return Kind; }
+
+    StringRef getName() const { return Name; }
+  };
+
+  class Schema;
+
+  class UserDefinedProperty final : public SchemaProperty {
+    Schema *Value;
+
+  public:
+    UserDefinedProperty(StringRef Name, Schema *Value)
+        : SchemaProperty(Name, PropertyKind::UserDefined), Value(Value) {}
+
+    Schema *getSchema() const { return Value; }
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::UserDefined;
+    }
+  };
+
+  class PropertiesProperty final : public SchemaProperty,
+                                   SmallVector<UserDefinedProperty *, 8> {
+  public:
+    using BaseVector = SmallVector<UserDefinedProperty *, 8>;
+
+    PropertiesProperty()
+        : SchemaProperty("properties", PropertyKind::Properties) {}
+
+    using BaseVector::begin;
+    using BaseVector::emplace_back;
+    using BaseVector::end;
+    using BaseVector::size;
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::Properties;
+    }
+  };
+
+  class AdditionalPropertiesProperty final : public SchemaProperty {
+    Schema *Value;
+
+  public:
+    AdditionalPropertiesProperty(Schema *Value = nullptr)
+        : SchemaProperty("additionalProperties",
+                         PropertyKind::AdditionalProperties),
+          Value(Value) {}
+
+    Schema *getSchema() const { return Value; }
+
+    void setSchema(Schema *S) { Value = S; }
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::AdditionalProperties;
+    }
+  };
+
+  class RequiredProperty final : public SchemaProperty,
+                                 SmallVector<StringRef, 4> {
+  public:
+    using BaseVector = SmallVector<StringRef, 4>;
+
+    RequiredProperty() : SchemaProperty("required", PropertyKind::Required) {}
+
+    using BaseVector::begin;
+    using BaseVector::emplace_back;
+    using BaseVector::end;
+    using BaseVector::size;
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::Required;
+    }
+  };
+
+  class OptionalProperty final : public SchemaProperty,
+                                 SmallVector<StringRef, 4> {
+  public:
+    using BaseVector = SmallVector<StringRef, 4>;
+
+    OptionalProperty() : SchemaProperty("optional", PropertyKind::Optional) {}
+
+    using BaseVector::begin;
+    using BaseVector::emplace_back;
+    using BaseVector::end;
+    using BaseVector::size;
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::Optional;
+    }
+  };
+
+  class TypeProperty final : public SchemaProperty {
+    StringRef Value;
+
+  public:
+    TypeProperty(StringRef Value)
+        : SchemaProperty("type", PropertyKind::Type), Value(Value) {}
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::Type;
+    }
+  };
+
+  class EnumProperty final : public SchemaProperty, SmallVector<StringRef, 4> {
+  public:
+    using BaseVector = SmallVector<StringRef, 4>;
+
+    EnumProperty() : SchemaProperty("enum", PropertyKind::Enum) {}
+
+    using BaseVector::begin;
+    using BaseVector::emplace_back;
+    using BaseVector::end;
+    using BaseVector::size;
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::Enum;
+    }
+  };
+
+  class ItemsProperty final : public SchemaProperty {
+    Schema *Value;
+
+  public:
+    ItemsProperty(Schema *Value = nullptr)
+        : SchemaProperty("items", PropertyKind::Items), Value(Value) {}
+
+    Schema *getSchema() const { return Value; }
+
+    void setSchema(Schema *S) { Value = S; }
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::Items;
+    }
+  };
+
+  enum class FlowStyle : bool {
+    Block,
+    Flow,
+  };
+
+  class FlowStyleProperty final : public SchemaProperty {
+    FlowStyle Style;
+
+  public:
+    FlowStyleProperty(FlowStyle Style = FlowStyle::Block)
+        : SchemaProperty("flowStyle", PropertyKind::FlowStyle), Style(Style) {}
+
+    void setStyle(FlowStyle S) { Style = S; }
+
+    FlowStyle getStyle() const { return Style; }
+
+    json::Value toJSON() const override;
+
+    static bool classof(const SchemaProperty *Property) {
+      return Property->getKind() == PropertyKind::FlowStyle;
+    }
+  };
+
+  class Schema final : public SchemaNode, SmallVector<SchemaProperty *, 8> {
+  public:
+    using BaseVector = SmallVector<SchemaProperty *, 8>;
+
+    Schema() = default;
+
+    using BaseVector::begin;
+    using BaseVector::emplace_back;
+    using BaseVector::end;
+    using BaseVector::size;
+
+    json::Value toJSON() const override;
+  };
+
+private:
+  std::vector<std::unique_ptr<SchemaNode>> SchemaNodes;
+  SmallVector<Schema *, 8> Schemas;
+  raw_ostream &RO;
+  SchemaNode *Root = nullptr;
+
+  template <typename PropertyType, typename... PropertyArgs>
+  PropertyType *createProperty(PropertyArgs &&...Args) {
+    std::unique_ptr<PropertyType> UPtr =
+        std::make_unique<PropertyType>(std::forward<PropertyArgs>(Args)...);
+    PropertyType *Ptr = UPtr.get();
+    SchemaNodes.emplace_back(std::move(UPtr));
+    return Ptr;
+  }
+
+  template <typename PropertyType, typename... PropertyArgs>
+  PropertyType *getOrCreateProperty(Schema &S, PropertyArgs... Args) {
+    auto Found = std::find_if(S.begin(), S.end(), [](SchemaProperty *Property) {
+      return isa<PropertyType>(Property);
+    });
+    if (Found != S.end()) {
+      return cast<PropertyType>(*Found);
+    }
+    PropertyType *Created =
+        createProperty<PropertyType>(std::forward<PropertyArgs>(Args)...);
+    S.emplace_back(Created);
+    return Created;
+  }
+
+  Schema *createSchema() {
+    std::unique_ptr<Schema> UPtr = std::make_unique<Schema>();
+    Schema *Ptr = UPtr.get();
+    SchemaNodes.emplace_back(std::move(UPtr));
+    return Ptr;
+  }
+
+  Schema *getTopSchema() const {
+    return Schemas.empty() ? nullptr : Schemas.back();
+  }
+};
+
+// Define non-member operator<< so that Output can stream out document list.
+template <typename T>
+inline std::enable_if_t<has_DocumentListTraits<T>::value, GenerateSchema &>
+operator<<(GenerateSchema &Gen, T &DocList) {
+  EmptyContext Ctx;
+  Gen.preflightDocument();
+  yamlize(Gen, DocumentListTraits<T>::element(Gen, DocList, 0), true, Ctx);
+  Gen.postflightDocument();
+  return Gen;
+}
+
+// Define non-member operator<< so that Output can stream out a map.
+template <typename T>
+inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value,
+                        GenerateSchema &>
+operator<<(GenerateSchema &Gen, T &Map) {
+  EmptyContext Ctx;
+  Gen.preflightDocument();
+  yamlize(Gen, Map, true, Ctx);
+  Gen.postflightDocument();
+  return Gen;
+}
+
+// Define non-member operator<< so that Output can stream out a sequence.
+template <typename T>
+inline std::enable_if_t<has_SequenceTraits<T>::value, GenerateSchema &>
+operator<<(GenerateSchema &Gen, T &Seq) {
+  EmptyContext Ctx;
+  Gen.preflightDocument();
+  yamlize(Gen, Seq, true, Ctx);
+  Gen.postflightDocument();
+  return Gen;
+}
+
+// Define non-member operator<< so that Output can stream out a block scalar.
+template <typename T>
+inline std::enable_if_t<has_BlockScalarTraits<T>::value, GenerateSchema &>
+operator<<(GenerateSchema &Gen, T &Val) {
+  EmptyContext Ctx;
+  Gen.preflightDocument();
+  yamlize(Gen, Val, true, Ctx);
+  Gen.postflightDocument();
+  return Gen;
+}
+
+// Define non-member operator<< so that Output can stream out a string map.
+template <typename T>
+inline std::enable_if_t<has_CustomMappingTraits<T>::value, GenerateSchema &>
+operator<<(GenerateSchema &Gen, T &Val) {
+  EmptyContext Ctx;
+  Gen.preflightDocument();
+  yamlize(Gen, Val, true, Ctx);
+  Gen.postflightDocument();
+  return Gen;
+}
+
+// Define non-member operator<< so that Output can stream out a polymorphic
+// type.
+template <typename T>
+inline std::enable_if_t<has_PolymorphicTraits<T>::value, GenerateSchema &>
+operator<<(GenerateSchema &Gen, T &Val) {
+  EmptyContext Ctx;
+  Gen.preflightDocument();
+  yamlize(Gen, Val, true, Ctx);
+  Gen.postflightDocument();
+  return Gen;
+}
+
+// Provide better error message about types missing a trait specialization
+template <typename T>
+inline std::enable_if_t<missingTraits<T, EmptyContext>::value, GenerateSchema &>
+operator<<(GenerateSchema &Gen, T &seq) {
+  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+  return Gen;
+}
+
+} // namespace yaml
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_YAMLGENERATE_SCHEMA_H
diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h
index 3d36f41ca1a04..f92e26e6424a1 100644
--- a/llvm/include/llvm/Support/YAMLTraits.h
+++ b/llvm/include/llvm/Support/YAMLTraits.h
@@ -145,6 +145,7 @@ enum class QuotingType { None, Single, Double };
 ///        return StringRef();
 ///      }
 ///      static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
+///      static constexpr StringRef typeName = "string";
 ///    };
 template <typename T, typename Enable = void> struct ScalarTraits {
   // Must provide:
@@ -158,6 +159,9 @@ template <typename T, typename Enable = void> struct ScalarTraits {
   //
   // Function to determine if the value should be quoted.
   // static QuotingType mustQuote(StringRef);
+  //
+  // Optional, for GeneratingSchema:
+  // static constexpr StringRef typeName = "string";
 };
 
 /// This class should be specialized by type that requires custom conversion
@@ -175,6 +179,7 @@ template <typename T, typename Enable = void> struct ScalarTraits {
 ///        // return empty string on success, or error string
 ///        return StringRef();
 ///      }
+///      static constexpr StringRef typeName = "string";
 ///    };
 template <typename T> struct BlockScalarTraits {
   // Must provide:
@@ -189,6 +194,7 @@ template <typename T> struct BlockScalarTraits {
   // Optional:
   // static StringRef inputTag(T &Val, std::string Tag)
   // static void outputTag(const T &Val, raw_ostream &Out)
+  // static constexpr StringRef typeName = "string";
 };
 
 /// This class should be specialized by type that requires custom conversion
@@ -211,6 +217,7 @@ template <typename T> struct BlockScalarTraits {
 ///      static QuotingType mustQuote(const MyType &Value, StringRef) {
 ///        return QuotingType::Single;
 ///      }
+///      static constexpr StringRef typeName = "integer";
 ///    };
 template <typename T> struct TaggedScalarTraits {
   // Must provide:
@@ -226,6 +233,9 @@ template <typename T> struct TaggedScalarTraits {
   //
   // Function to determine if the value should be quoted.
   // static QuotingType mustQuote(const T &Value, StringRef Scalar);
+  //
+  // Optional:
+  // static constexpr StringRef typeName = "string";
 };
 
 /// This class should be specialized by any type that needs to be converted
@@ -442,6 +452,14 @@ template <class T> struct has_CustomMappingTraits {
       is_detected<check, CustomMappingTraits<T>>::value;
 };
 
+// Test if typeName is defined on type T.
+template <typename T> struct has_TypeNameTraits {
+  template <class U>
+  using check = std::is_same<decltype(&U::typeName), StringRef>;
+
+  static constexpr bool value = is_detected<check, T>::value;
+};
+
 // Test if flow is defined on type T.
 template <typename T> struct has_FlowTraits {
   template <class U> using check = decltype(&U::flow);
@@ -683,12 +701,19 @@ struct unvalidatedMappingTraits
                                 !has_MappingValidateTraits<T, Context>::value> {
 };
 
+enum class IOKind : uint8_t {
+  Outputting,
+  Inputting,
+  GeneratingSchema,
+};
+
 // Base class for Input and Output.
 class LLVM_ABI IO {
 public:
   IO(void *Ctxt = nullptr);
   virtual ~IO();
 
+  virtual IOKind getKind() const = 0;
   virtual bool outputting() const = 0;
 
   virtual unsigned beginSequence() = 0;
@@ -732,7 +757,8 @@ class LLVM_ABI IO {
   virtual void setAllowUnknownKeys(bool Allow);
 
   template <typename T> void enumCase(T &Val, StringRef Str, const T ConstVal) {
-    if (matchEnumScalar(Str, outputting() && Val == ConstVal)) {
+    if (matchEnumScalar(Str,
+                        getKind() == IOKind::Outputting && Val == ConstVal)) {
       Val = ConstVal;
     }
   }
@@ -740,7 +766,8 @@ class LLVM_ABI IO {
   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
   template <typename T>
   void enumCase(T &Val, StringRef Str, const uint32_t ConstVal) {
-    if (matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal))) {
+    if (matchEnumScalar(Str, getKind() == IOKind::Outputting &&
+                                 Val == static_cast<T>(ConstVal))) {
       Val = ConstVal;
     }
   }
@@ -757,7 +784,8 @@ class LLVM_ABI IO {
 
   template <typename T>
   void bitSetCase(T &Val, StringRef Str, const T ConstVal) {
-    if (bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal)) {
+    if (bitSetMatch(Str, getKind() == IOKind::Outputting &&
+                             (Val & ConstVal) == ConstVal)) {
       Val = static_cast<T>(Val | ConstVal);
     }
   }
@@ -765,21 +793,24 @@ class LLVM_ABI IO {
   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
   template <typename T>
   void bitSetCase(T &Val, StringRef Str, const uint32_t ConstVal) {
-    if (bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal)) {
+    if (bitSetMatch(Str, getKind() == IOKind::Outputting &&
+                             (Val & ConstVal) == ConstVal)) {
       Val = static_cast<T>(Val | ConstVal);
     }
   }
 
   template <typename T>
   void maskedBitSetCase(T &Val, StringRef Str, T ConstVal, T Mask) {
-    if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
+    if (bitSetMatch(Str, getKind() == IOKind::Outputting &&
+                             (Val & Mask) == ConstVal))
       Val = Val | ConstVal;
   }
 
   template <typename T>
   void maskedBitSetCase(T &Val, StringRef Str, uint32_t ConstVal,
                         uint32_t Mask) {
-    if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
+    if (bitSetMatch(Str, getKind() == IOKind::Outputting &&
+                             (Val & Mask) == ConstVal))
       Val = Val | ConstVal;
   }
 
@@ -844,7 +875,8 @@ class LLVM_ABI IO {
                              bool Required, Context &Ctx) {
     void *SaveInfo;
     bool UseDefault;
-    const bool sameAsDefault = outputting() && Val == DefaultValue;
+    const bool sameAsDefault =
+        (getKind() == IOKind::Outputting) && Val == DefaultValue;
     if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
                            SaveInfo)) {
       yamlize(*this, Val, Required, Ctx);
@@ -905,45 +937,57 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
 template <typename T>
 std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
                                                            EmptyContext &Ctx) {
-  if (io.outputting()) {
+  if (io.getKind() == IOKind::Outputting) {
     SmallString<128> Storage;
     raw_svector_ostream Buffer(Storage);
     ScalarTraits<T>::output(Val, io.getContext(), Buffer);
     StringRef Str = Buffer.str();
     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
-  } else {
+  } else if (io.getKind() == IOKind::Inputting) {
     StringRef Str;
     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
     StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
     if (!Result.empty()) {
       io.setError(Twine(Result));
     }
+  } else {
+    StringRef TypeName = "string";
+    if constexpr (has_TypeNameTraits<ScalarTraits<T>>::value) {
+      TypeName = ScalarTraits<T>::typeName;
+    }
+    io.scalarString(TypeName, QuotingType::None);
   }
 }
 
 template <typename T>
 std::enable_if_t<has_BlockScalarTraits<T>::value, void>
 yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
-  if (YamlIO.outputting()) {
+  if (YamlIO.getKind() == IOKind::Outputting) {
     std::string Storage;
     raw_string_ostream Buffer(Storage);
     BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
     StringRef Str(Storage);
     YamlIO.blockScalarString(Str);
-  } else {
+  } else if (YamlIO.getKind() == IOKind::Inputting) {
     StringRef Str;
     YamlIO.blockScalarString(Str);
     StringRef Result =
         BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
     if (!Result.empty())
       YamlIO.setError(Twine(Result));
+  } else {
+    StringRef TypeName = "string";
+    if constexpr (has_TypeNameTraits<ScalarTraits<T>>::value) {
+      TypeName = ScalarTraits<T>::typeName;
+    }
+    YamlIO.blockScalarString(TypeName);
   }
 }
 
 template <typename T>
 std::enable_if_t<has_TaggedScalarTraits<T>::value, void>
 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
-  if (io.outputting()) {
+  if (io.getKind() == IOKind::Outputting) {
     std::string ScalarStorage, TagStorage;
     raw_strin...
[truncated]

Introduced a way for generating schema for validating input YAML. This can be
useful to see the full structure of the input YAML file for different llvm
based tools that use existing YAML parser, for example clang-format,
clang-tidy e.t.c. This commit also can be useful for yaml-language-server.
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.
@tgs-sc tgs-sc force-pushed the users/tgs-sc/improve-auto-generate-yaml-scheme branch from b2c821a to 3a45a13 Compare October 23, 2025 15:30
@EugeneZelenko
Copy link
Contributor

Does GitHub allow to change target branch on the fly? It's hart to see differences on top of #133284 now.

@tgs-sc
Copy link
Contributor Author

tgs-sc commented Oct 27, 2025

Does GitHub allow to change target branch on the fly? It's hart to see differences on top of #133284 now.

Well, I can not see my branch in the list of them because I don't have commit access to create it in llvm-project repository. But theoretically, if it was present, I could do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants