blob: f1a57dcf72dcee01144b5fbf7677e9c18b54c568 [file] [log] [blame]
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "rs_bindings_from_cc/ir.h"
#include <stdint.h>
#include <optional>
#include <ostream>
#include <string>
#include <utility>
#include <variant>
#include <vector>
#include "base/integral_types.h"
#include "rs_bindings_from_cc/bazel_types.h"
#include "third_party/absl/strings/string_view.h"
#include "third_party/json/src/json.hpp"
#include "util/gtl/labs/string_type.h"
#include "util/intops/strong_int.h"
namespace rs_bindings_from_cc {
template <class T>
static std::vector<nlohmann::json> VectorToJson(const std::vector<T>& v) {
std::vector<nlohmann::json> result;
result.reserve(v.size());
for (const T& t : v) {
result.push_back(t.ToJson());
}
return result;
}
nlohmann::json HeaderName::ToJson() const {
nlohmann::json result;
result["name"] = name_;
return result;
}
nlohmann::json RsType::ToJson() const {
nlohmann::json result;
if (decl_id.has_value()) {
result["decl_id"] = decl_id->value();
} else {
result["name"] = name;
}
result["type_args"] = VectorToJson(type_args);
return result;
}
nlohmann::json CcType::ToJson() const {
nlohmann::json result;
if (decl_id.has_value()) {
result["decl_id"] = decl_id->value();
} else {
result["name"] = name;
}
result["is_const"] = is_const;
result["type_args"] = VectorToJson(type_args);
return result;
}
nlohmann::json MappedType::ToJson() const {
nlohmann::json result;
result["rs_type"] = rs_type.ToJson();
result["cc_type"] = cc_type.ToJson();
return result;
}
nlohmann::json Identifier::ToJson() const {
nlohmann::json result;
result["identifier"] = identifier_;
return result;
}
nlohmann::json FuncParam::ToJson() const {
nlohmann::json result;
result["type"] = type.ToJson();
result["identifier"] = identifier.ToJson();
return result;
}
static std::string SpecialNameToString(SpecialName special_name) {
switch (special_name) {
case SpecialName::kDestructor:
return "Destructor";
case SpecialName::kConstructor:
return "Constructor";
}
}
std::ostream& operator<<(std::ostream& o, const SpecialName& special_name) {
return o << SpecialNameToString(special_name);
}
nlohmann::json MemberFuncMetadata::ToJson() const {
nlohmann::json meta;
meta["for_type"] = for_type.ToJson();
if (instance_method_metadata.has_value()) {
nlohmann::json instance;
absl::string_view reference;
switch (instance_method_metadata->reference) {
case MemberFuncMetadata::kLValue:
reference = "LValue";
break;
case MemberFuncMetadata::kRValue:
reference = "RValue";
break;
case MemberFuncMetadata::kUnqualified:
reference = "Unqualified";
break;
}
instance["reference"] = reference;
instance["is_const"] = instance_method_metadata->is_const;
instance["is_virtual"] = instance_method_metadata->is_virtual;
meta["instance_method_metadata"] = std::move(instance);
}
return meta;
}
nlohmann::json Func::ToJson() const {
nlohmann::json func;
if (auto* id = std::get_if<Identifier>(&name)) {
func["name"]["Identifier"] = id->ToJson();
} else {
func["name"][SpecialNameToString(std::get<SpecialName>(name))] = nullptr;
}
func["decl_id"] = decl_id.value();
func["owning_target"] = owning_target.value();
if (doc_comment) {
func["doc_comment"] = *doc_comment;
}
func["mangled_name"] = mangled_name;
func["return_type"] = return_type.ToJson();
func["params"] = VectorToJson(params);
func["is_inline"] = is_inline;
if (member_func_metadata.has_value()) {
func["member_func_metadata"] = member_func_metadata->ToJson();
}
nlohmann::json item;
item["Func"] = std::move(func);
return item;
}
static std::string AccessToString(AccessSpecifier access) {
switch (access) {
case kPublic:
return "Public";
case kProtected:
return "Protected";
case kPrivate:
return "Private";
}
}
std::ostream& operator<<(std::ostream& o, const AccessSpecifier& access) {
return o << AccessToString(access);
}
nlohmann::json Field::ToJson() const {
nlohmann::json result;
result["identifier"] = identifier.ToJson();
if (doc_comment) {
result["doc_comment"] = *doc_comment;
}
result["type"] = type.ToJson();
result["access"] = AccessToString(access);
result["offset"] = offset;
return result;
}
static std::string SpecialMemberDefinitionToString(
SpecialMemberFunc::Definition def) {
switch (def) {
case SpecialMemberFunc::Definition::kTrivial:
return "Trivial";
case SpecialMemberFunc::Definition::kNontrivialMembers:
return "NontrivialMembers";
case SpecialMemberFunc::Definition::kNontrivialSelf:
return "NontrivialSelf";
case SpecialMemberFunc::Definition::kDeleted:
return "Deleted";
}
}
std::ostream& operator<<(std::ostream& o,
const SpecialMemberFunc::Definition& definition) {
return o << SpecialMemberDefinitionToString(definition);
}
nlohmann::json SpecialMemberFunc::ToJson() const {
nlohmann::json result;
result["definition"] = SpecialMemberDefinitionToString(definition);
result["access"] = AccessToString(access);
return result;
}
nlohmann::json Record::ToJson() const {
nlohmann::json record;
record["identifier"] = identifier.ToJson();
record["decl_id"] = decl_id.value();
record["owning_target"] = owning_target.value();
if (doc_comment) {
record["doc_comment"] = *doc_comment;
}
record["fields"] = VectorToJson(fields);
record["size"] = size;
record["alignment"] = alignment;
record["copy_constructor"] = copy_constructor.ToJson();
record["move_constructor"] = move_constructor.ToJson();
record["destructor"] = destructor.ToJson();
record["is_trivial_abi"] = is_trivial_abi;
nlohmann::json item;
item["Record"] = std::move(record);
return item;
}
nlohmann::json SourceLoc::ToJson() const {
nlohmann::json source_loc;
source_loc["filename"] = filename;
source_loc["line"] = line;
source_loc["column"] = column;
return source_loc;
}
nlohmann::json UnsupportedItem::ToJson() const {
nlohmann::json unsupported;
unsupported["name"] = name;
unsupported["message"] = message;
unsupported["source_loc"] = source_loc.ToJson();
nlohmann::json item;
item["UnsupportedItem"] = std::move(unsupported);
return item;
}
nlohmann::json Comment::ToJson() const {
nlohmann::json comment;
comment["text"] = text;
nlohmann::json item;
item["Comment"] = std::move(comment);
return item;
}
nlohmann::json IR::ToJson() const {
std::vector<nlohmann::json> json_items;
json_items.reserve(items.size());
for (const auto& item : items) {
std::visit([&](auto&& item) { json_items.push_back(item.ToJson()); }, item);
}
nlohmann::json result;
result["used_headers"] = VectorToJson(used_headers);
result["current_target"] = current_target.value();
result["items"] = std::move(json_items);
return result;
}
} // namespace rs_bindings_from_cc