| 1 | //===-- Generators.cpp - Generator Registry ----------------------*- C++-*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "Generators.h" |
| 10 | |
| 11 | LLVM_INSTANTIATE_REGISTRY(clang::doc::GeneratorRegistry) |
| 12 | |
| 13 | namespace clang { |
| 14 | namespace doc { |
| 15 | |
| 16 | llvm::Expected<std::unique_ptr<Generator>> |
| 17 | findGeneratorByName(llvm::StringRef Format) { |
| 18 | for (const auto &Generator : GeneratorRegistry::entries()) { |
| 19 | if (Generator.getName() != Format) |
| 20 | continue; |
| 21 | return Generator.instantiate(); |
| 22 | } |
| 23 | return createStringError(EC: llvm::inconvertibleErrorCode(), |
| 24 | S: "can't find generator: " + Format); |
| 25 | } |
| 26 | |
| 27 | // Enum conversion |
| 28 | |
| 29 | std::string getTagType(TagTypeKind AS) { |
| 30 | switch (AS) { |
| 31 | case TagTypeKind::Class: |
| 32 | return "class" ; |
| 33 | case TagTypeKind::Union: |
| 34 | return "union" ; |
| 35 | case TagTypeKind::Interface: |
| 36 | return "interface" ; |
| 37 | case TagTypeKind::Struct: |
| 38 | return "struct" ; |
| 39 | case TagTypeKind::Enum: |
| 40 | return "enum" ; |
| 41 | } |
| 42 | llvm_unreachable("Unknown TagTypeKind" ); |
| 43 | } |
| 44 | |
| 45 | llvm::Error Generator::createResources(ClangDocContext &CDCtx) { |
| 46 | return llvm::Error::success(); |
| 47 | } |
| 48 | |
| 49 | // A function to add a reference to Info in Idx. |
| 50 | // Given an Info X with the following namespaces: [B,A]; a reference to X will |
| 51 | // be added in the children of a reference to B, which should be also a child of |
| 52 | // a reference to A, where A is a child of Idx. |
| 53 | // Idx |
| 54 | // |-- A |
| 55 | // |--B |
| 56 | // |--X |
| 57 | // If the references to the namespaces do not exist, they will be created. If |
| 58 | // the references already exist, the same one will be used. |
| 59 | void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) { |
| 60 | // Index pointer that will be moving through Idx until the first parent |
| 61 | // namespace of Info (where the reference has to be inserted) is found. |
| 62 | Index *I = &Idx; |
| 63 | // The Namespace vector includes the upper-most namespace at the end so the |
| 64 | // loop will start from the end to find each of the namespaces. |
| 65 | for (const auto &R : llvm::reverse(C: Info->Namespace)) { |
| 66 | // Look for the current namespace in the children of the index I is |
| 67 | // pointing. |
| 68 | auto It = llvm::find(Range&: I->Children, Val: R.USR); |
| 69 | if (It != I->Children.end()) { |
| 70 | // If it is found, just change I to point the namespace reference found. |
| 71 | I = &*It; |
| 72 | } else { |
| 73 | // If it is not found a new reference is created |
| 74 | I->Children.emplace_back(args: R.USR, args: R.Name, args: R.RefType, args: R.Path); |
| 75 | // I is updated with the reference of the new namespace reference |
| 76 | I = &I->Children.back(); |
| 77 | } |
| 78 | } |
| 79 | // Look for Info in the vector where it is supposed to be; it could already |
| 80 | // exist if it is a parent namespace of an Info already passed to this |
| 81 | // function. |
| 82 | auto It = llvm::find(Range&: I->Children, Val: Info->USR); |
| 83 | if (It == I->Children.end()) { |
| 84 | // If it is not in the vector it is inserted |
| 85 | I->Children.emplace_back(args: Info->USR, args: Info->extractName(), args: Info->IT, |
| 86 | args: Info->Path); |
| 87 | } else { |
| 88 | // If it not in the vector we only check if Path and Name are not empty |
| 89 | // because if the Info was included by a namespace it may not have those |
| 90 | // values. |
| 91 | if (It->Path.empty()) |
| 92 | It->Path = Info->Path; |
| 93 | if (It->Name.empty()) |
| 94 | It->Name = Info->extractName(); |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | // This anchor is used to force the linker to link in the generated object file |
| 99 | // and thus register the generators. |
| 100 | static int LLVM_ATTRIBUTE_UNUSED YAMLGeneratorAnchorDest = |
| 101 | YAMLGeneratorAnchorSource; |
| 102 | static int LLVM_ATTRIBUTE_UNUSED MDGeneratorAnchorDest = |
| 103 | MDGeneratorAnchorSource; |
| 104 | static int LLVM_ATTRIBUTE_UNUSED HTMLGeneratorAnchorDest = |
| 105 | HTMLGeneratorAnchorSource; |
| 106 | static int LLVM_ATTRIBUTE_UNUSED MHTMLGeneratorAnchorDest = |
| 107 | MHTMLGeneratorAnchorSource; |
| 108 | static int LLVM_ATTRIBUTE_UNUSED JSONGeneratorAnchorDest = |
| 109 | JSONGeneratorAnchorSource; |
| 110 | } // namespace doc |
| 111 | } // namespace clang |
| 112 | |