2023-04-21 14:27:55 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <optional>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <variant>
|
|
|
|
|
#include <memory>
|
2023-05-02 15:18:08 +03:00
|
|
|
#include <unordered_set>
|
2023-05-03 15:03:57 +03:00
|
|
|
#include <unordered_map>
|
2023-04-21 14:27:55 +03:00
|
|
|
|
2023-04-17 11:14:33 +03:00
|
|
|
// for clangd
|
2023-05-21 17:00:59 +03:00
|
|
|
#include "error_handling.hpp"
|
2023-05-22 16:03:50 +03:00
|
|
|
#include "typeclass_graph.hpp"
|
2023-04-21 14:27:55 +03:00
|
|
|
#include "utils.hpp"
|
2023-04-17 11:14:33 +03:00
|
|
|
|
2023-04-21 14:27:55 +03:00
|
|
|
namespace info::type {
|
2023-04-17 11:14:33 +03:00
|
|
|
|
2023-07-02 18:28:16 +03:00
|
|
|
// TODO: implement DeduceContext
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
// TODO: move in constructors
|
2023-04-17 11:14:33 +03:00
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
class TypeManager;
|
|
|
|
|
|
2023-05-19 15:05:12 +03:00
|
|
|
class AbstractType { // latter will be found in context
|
2023-05-02 15:18:08 +03:00
|
|
|
public:
|
2023-05-05 16:35:13 +03:00
|
|
|
AbstractType(utils::AbstractTypeModifier modifier,
|
2023-05-22 16:03:50 +03:00
|
|
|
utils::IdType graph_id,
|
|
|
|
|
info::TypeclassGraph& typeclass_graph)
|
2023-05-17 11:51:14 +03:00
|
|
|
: modifier_(modifier),
|
2023-05-22 16:03:50 +03:00
|
|
|
graph_id_(graph_id),
|
|
|
|
|
typeclass_graph_(typeclass_graph) {}
|
2023-05-17 11:51:14 +03:00
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const AbstractType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const AbstractType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const AbstractType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-22 16:03:50 +03:00
|
|
|
utils::IdType GetGraphId() {
|
|
|
|
|
return graph_id_;
|
2023-05-20 00:01:54 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-22 16:03:50 +03:00
|
|
|
bool HasTypeclass(utils::IdType graph_id) { // TODO: cache dependencies set
|
|
|
|
|
return graph_id == graph_id_ || typeclass_graph_.GetDependenciesSet(graph_id_).count(graph_id) != 0;
|
2023-05-17 11:51:14 +03:00
|
|
|
}
|
|
|
|
|
|
2023-07-02 18:28:16 +03:00
|
|
|
std::string GetName() const {
|
|
|
|
|
return typeclass_graph_.GetVertex(graph_id_).name;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const {
|
2023-05-23 20:05:48 +03:00
|
|
|
return "Abstract " + std::to_string(graph_id_) + " ( " + typeclass_graph_.GetVertex(graph_id_).name + " )";
|
2023-05-22 01:25:12 +03:00
|
|
|
}
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
2023-05-05 16:35:13 +03:00
|
|
|
utils::AbstractTypeModifier modifier_;
|
2023-05-22 16:03:50 +03:00
|
|
|
utils::IdType graph_id_;
|
|
|
|
|
info::TypeclassGraph& typeclass_graph_;
|
2023-05-02 15:18:08 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class DefinedType {
|
|
|
|
|
public:
|
|
|
|
|
DefinedType() = default;
|
|
|
|
|
DefinedType(utils::IdType type_id,
|
|
|
|
|
utils::IdType type,
|
2023-05-13 18:53:54 +03:00
|
|
|
utils::ClassModifier class_modifier,
|
2023-05-02 15:18:08 +03:00
|
|
|
TypeManager* type_manager)
|
2023-05-19 10:27:14 +03:00
|
|
|
: type_id_(type_id), type_(type), class_modifier_(class_modifier), type_manager_(type_manager) {}
|
2023-05-02 15:18:08 +03:00
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const DefinedType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const DefinedType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const DefinedType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-03 15:03:57 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-04 16:11:25 +03:00
|
|
|
utils::IdType GetTypeId() const {
|
2023-05-03 15:03:57 +03:00
|
|
|
return type_id_;
|
|
|
|
|
}
|
2023-05-04 16:11:25 +03:00
|
|
|
|
|
|
|
|
utils::IdType GetType() const {
|
|
|
|
|
return type_;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
utils::ClassModifier GetClassModifier() const {
|
|
|
|
|
return class_modifier_;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 20:05:48 +03:00
|
|
|
std::string ToString() const;
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
|
|
|
|
utils::IdType type_id_; // in defined types
|
|
|
|
|
utils::IdType type_; // in types manager, created using context types (if specific type)
|
2023-05-13 18:53:54 +03:00
|
|
|
utils::ClassModifier class_modifier_;
|
2023-05-02 15:18:08 +03:00
|
|
|
TypeManager* type_manager_ = nullptr;
|
2023-04-17 11:14:33 +03:00
|
|
|
};
|
|
|
|
|
|
2023-05-22 10:58:50 +03:00
|
|
|
const size_t InternalTypesCount = 6;
|
2023-04-21 14:27:55 +03:00
|
|
|
enum class InternalType {
|
2023-05-02 15:18:08 +03:00
|
|
|
Float = 0,
|
|
|
|
|
Int = 1,
|
|
|
|
|
String = 2,
|
|
|
|
|
Char = 3,
|
|
|
|
|
Bool = 4,
|
|
|
|
|
Unit = 5,
|
2023-04-21 14:27:55 +03:00
|
|
|
};
|
2023-04-17 11:14:33 +03:00
|
|
|
|
2023-05-08 20:34:36 +03:00
|
|
|
inline std::optional<InternalType> ToInternalType(const std::string& type) {
|
|
|
|
|
if (type.empty()) {
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (type[0]) {
|
2023-06-03 19:01:03 +03:00
|
|
|
case 'f':
|
|
|
|
|
if (type == "float") { return InternalType::Float; }
|
2023-05-08 20:34:36 +03:00
|
|
|
break;
|
2023-06-03 19:01:03 +03:00
|
|
|
case 'i':
|
|
|
|
|
if (type == "int") { return InternalType::Int; }
|
2023-05-08 20:34:36 +03:00
|
|
|
break;
|
2023-06-03 19:01:03 +03:00
|
|
|
case 's':
|
|
|
|
|
if (type == "string") { return InternalType::String; }
|
2023-05-08 20:34:36 +03:00
|
|
|
break;
|
2023-06-03 19:01:03 +03:00
|
|
|
case 'c':
|
|
|
|
|
if (type == "char") { return InternalType::Char; }
|
2023-05-08 20:34:36 +03:00
|
|
|
break;
|
2023-06-03 19:01:03 +03:00
|
|
|
case 'b':
|
|
|
|
|
if (type == "bool") { return InternalType::Bool; }
|
2023-05-08 20:34:36 +03:00
|
|
|
break;
|
2023-06-03 19:01:03 +03:00
|
|
|
case 'u':
|
|
|
|
|
if (type == "unit") { return InternalType::Unit; }
|
2023-05-08 20:34:36 +03:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-22 01:25:12 +03:00
|
|
|
inline std::string ToString(InternalType type) {
|
|
|
|
|
std::string result;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case InternalType::Float:
|
2023-06-03 19:01:03 +03:00
|
|
|
result = "float";
|
2023-05-22 01:25:12 +03:00
|
|
|
break;
|
|
|
|
|
case InternalType::Int:
|
2023-06-03 19:01:03 +03:00
|
|
|
result = "int";
|
2023-05-22 01:25:12 +03:00
|
|
|
break;
|
|
|
|
|
case InternalType::String:
|
2023-06-03 19:01:03 +03:00
|
|
|
result = "string";
|
2023-05-22 01:25:12 +03:00
|
|
|
break;
|
|
|
|
|
case InternalType::Char:
|
2023-06-03 19:01:03 +03:00
|
|
|
result = "char";
|
2023-05-22 01:25:12 +03:00
|
|
|
break;
|
|
|
|
|
case InternalType::Bool:
|
2023-06-03 19:01:03 +03:00
|
|
|
result = "bool";
|
2023-05-22 01:25:12 +03:00
|
|
|
break;
|
|
|
|
|
case InternalType::Unit:
|
2023-06-03 19:01:03 +03:00
|
|
|
result = "unit";
|
2023-05-22 01:25:12 +03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
class TupleType {
|
|
|
|
|
public:
|
|
|
|
|
TupleType() = default;
|
|
|
|
|
TupleType(const std::optional<std::string>& name,
|
|
|
|
|
const std::vector<std::pair<std::optional<std::string>, utils::IdType>>& fields,
|
|
|
|
|
TypeManager* type_manager)
|
|
|
|
|
: name_(name), fields_(fields), type_manager_(type_manager) {}
|
|
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const TupleType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const TupleType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const TupleType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-03 15:03:57 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
const std::vector<std::pair<std::optional<std::string>, utils::IdType>>& GetFields() const {
|
|
|
|
|
return fields_;
|
|
|
|
|
}
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const;
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
|
|
|
|
std::optional<std::string> name_;
|
|
|
|
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_;
|
|
|
|
|
TypeManager* type_manager_ = nullptr;
|
2023-04-17 11:14:33 +03:00
|
|
|
};
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
class VariantType {
|
|
|
|
|
public:
|
|
|
|
|
VariantType() = default;
|
|
|
|
|
VariantType(const std::optional<std::string>& name,
|
2023-06-03 19:01:03 +03:00
|
|
|
const std::vector<std::pair<std::string, std::optional<TupleType>>>& constructors,
|
2023-05-06 19:26:14 +03:00
|
|
|
std::optional<size_t> current_constructor)
|
|
|
|
|
: name_(name), constructors_(constructors), current_constructor_(current_constructor) {}
|
2023-05-02 15:18:08 +03:00
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const VariantType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const VariantType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const VariantType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-03 15:03:57 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-06-03 19:01:03 +03:00
|
|
|
const std::vector<std::pair<std::string, std::optional<TupleType>>>& GetConstructors() const {
|
2023-05-03 15:03:57 +03:00
|
|
|
return constructors_;
|
|
|
|
|
}
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-19 10:27:14 +03:00
|
|
|
void SetCurrentConstructor(size_t constructor) {
|
2023-05-06 19:26:14 +03:00
|
|
|
current_constructor_ = constructor;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const;
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
|
|
|
|
std::optional<std::string> name_;
|
2023-06-03 19:01:03 +03:00
|
|
|
std::vector<std::pair<std::string, std::optional<TupleType>>> constructors_;
|
2023-05-06 19:26:14 +03:00
|
|
|
std::optional<size_t> current_constructor_;
|
2023-05-02 15:18:08 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class OptionalType {
|
|
|
|
|
public:
|
|
|
|
|
OptionalType() = default;
|
|
|
|
|
OptionalType(utils::IdType type,
|
|
|
|
|
TypeManager* type_manager)
|
|
|
|
|
: type_(type), type_manager_(type_manager) {}
|
|
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const OptionalType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const OptionalType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const OptionalType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const;
|
2023-06-08 19:22:56 +03:00
|
|
|
|
|
|
|
|
utils::IdType GetType() const {
|
|
|
|
|
return type_;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
|
|
|
|
utils::IdType type_;
|
|
|
|
|
TypeManager* type_manager_ = nullptr;
|
2023-04-17 11:14:33 +03:00
|
|
|
};
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
class ReferenceToType {
|
|
|
|
|
public:
|
|
|
|
|
ReferenceToType() = default;
|
2023-05-05 16:35:13 +03:00
|
|
|
ReferenceToType(const std::vector<utils::ReferenceModifier>& references,
|
2023-05-02 15:18:08 +03:00
|
|
|
utils::IdType type,
|
|
|
|
|
TypeManager* type_manager)
|
2023-05-23 11:54:15 +03:00
|
|
|
: references_(references), type_(type), type_manager_(type_manager) {
|
|
|
|
|
if (references.empty()) {
|
|
|
|
|
error_handling::HandleInternalError("ReferenceToType with 0 references", "Type.ReferenceToType", std::nullopt);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-02 15:18:08 +03:00
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const ReferenceToType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const ReferenceToType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const ReferenceToType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const;
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
2023-05-05 16:35:13 +03:00
|
|
|
std::vector<utils::ReferenceModifier> references_;
|
2023-05-02 15:18:08 +03:00
|
|
|
utils::IdType type_;
|
|
|
|
|
TypeManager* type_manager_ = nullptr;
|
2023-04-22 19:30:16 +03:00
|
|
|
};
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
/////////////////////////////
|
|
|
|
|
|
|
|
|
|
class FunctionType {
|
|
|
|
|
public:
|
|
|
|
|
FunctionType() = default;
|
|
|
|
|
FunctionType(const std::vector<utils::IdType>& argument_types,
|
|
|
|
|
utils::IdType return_type,
|
|
|
|
|
TypeManager* type_manager)
|
|
|
|
|
: argument_types_(argument_types), return_type_(return_type), type_manager_(type_manager) {}
|
|
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const FunctionType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const FunctionType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const FunctionType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const;
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
|
|
|
|
std::vector<utils::IdType> argument_types_;
|
|
|
|
|
utils::IdType return_type_;
|
|
|
|
|
TypeManager* type_manager_ = nullptr;
|
2023-04-21 14:27:55 +03:00
|
|
|
};
|
2023-04-17 11:14:33 +03:00
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
class ArrayType {
|
|
|
|
|
public:
|
|
|
|
|
ArrayType() = default;
|
|
|
|
|
ArrayType(size_t size,
|
|
|
|
|
utils::IdType elements_type,
|
|
|
|
|
TypeManager* type_manager)
|
|
|
|
|
: size_(size), elements_type_(elements_type), type_manager_(type_manager) {}
|
|
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
2023-05-02 15:18:08 +03:00
|
|
|
bool Same(const ArrayType& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const ArrayType& type) const;
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const ArrayType& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-03 15:03:57 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
utils::IdType GetElementsType() {
|
|
|
|
|
return elements_type_;
|
|
|
|
|
}
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const;
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
|
|
|
|
size_t size_; // = 0 for dynamic
|
|
|
|
|
utils::IdType elements_type_;
|
|
|
|
|
TypeManager* type_manager_ = nullptr;
|
2023-04-17 11:14:33 +03:00
|
|
|
};
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
class Type {
|
|
|
|
|
public:
|
|
|
|
|
template<typename T>
|
2023-05-07 19:52:35 +03:00
|
|
|
explicit Type(const T& type) : type_(type) {}
|
2023-05-02 15:18:08 +03:00
|
|
|
|
2023-05-03 15:03:57 +03:00
|
|
|
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
|
|
|
|
|
bool Same(const Type& type) const;
|
2023-07-02 18:28:16 +03:00
|
|
|
bool Require(const Type& type) const; // TODO: check abstract type requirements for not abstract types
|
|
|
|
|
|
|
|
|
|
bool DeduceContext(const Type& actual_type,
|
|
|
|
|
std::unordered_map<std::string, std::optional<utils::IdType>>& context) const;
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-13 18:53:54 +03:00
|
|
|
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
|
|
|
|
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-07 15:17:37 +03:00
|
|
|
std::string GetTypeName() const;
|
|
|
|
|
|
2023-05-07 19:52:35 +03:00
|
|
|
std::variant<AbstractType,
|
|
|
|
|
DefinedType,
|
|
|
|
|
InternalType,
|
|
|
|
|
TupleType,
|
|
|
|
|
VariantType,
|
|
|
|
|
ReferenceToType,
|
|
|
|
|
FunctionType,
|
|
|
|
|
ArrayType,
|
|
|
|
|
OptionalType>& GetType() {
|
|
|
|
|
return type_;
|
|
|
|
|
}
|
2023-05-22 01:25:12 +03:00
|
|
|
|
2023-05-23 11:54:15 +03:00
|
|
|
std::string ToString() const;
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
|
|
|
|
std::variant<AbstractType,
|
|
|
|
|
DefinedType,
|
|
|
|
|
InternalType,
|
|
|
|
|
TupleType,
|
|
|
|
|
VariantType,
|
|
|
|
|
ReferenceToType,
|
|
|
|
|
FunctionType,
|
2023-05-06 19:26:14 +03:00
|
|
|
ArrayType,
|
|
|
|
|
OptionalType> type_;
|
2023-04-17 11:14:33 +03:00
|
|
|
};
|
|
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
class TypeManager {
|
|
|
|
|
public:
|
|
|
|
|
template<typename T>
|
2023-05-09 15:37:30 +03:00
|
|
|
utils::IdType AddValue(const T& type, utils::ValueType value_type) {
|
2023-05-07 19:52:35 +03:00
|
|
|
types_.push_back(std::pair<Type, utils::ValueType> {type, value_type});
|
|
|
|
|
return types_.size() - 1;
|
|
|
|
|
}
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-09 15:37:30 +03:00
|
|
|
utils::IdType AddAnyValue(Type&& type, utils::ValueType value_type) {
|
2023-05-07 19:52:35 +03:00
|
|
|
types_.push_back(std::pair<Type, utils::ValueType> {std::move(type), value_type});
|
|
|
|
|
return types_.size() - 1;
|
|
|
|
|
}
|
2023-05-02 15:18:08 +03:00
|
|
|
|
|
|
|
|
template<typename T>
|
2023-05-09 15:37:30 +03:00
|
|
|
std::optional<T*> GetValue(utils::IdType type_id) {
|
2023-05-07 19:52:35 +03:00
|
|
|
if (!std::holds_alternative<T>(types_.at(type_id).first.GetType())) {
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
2023-05-23 20:05:48 +03:00
|
|
|
return &std::get<T>(types_[type_id].first.GetType());
|
2023-05-07 19:52:35 +03:00
|
|
|
}
|
2023-05-02 15:18:08 +03:00
|
|
|
|
2023-05-09 15:37:30 +03:00
|
|
|
Type* GetAnyValue(utils::IdType type_id) {
|
2023-05-07 19:52:35 +03:00
|
|
|
return &types_.at(type_id).first;
|
|
|
|
|
}
|
2023-05-02 15:18:08 +03:00
|
|
|
|
2023-05-22 19:14:17 +03:00
|
|
|
utils::ValueType GetValueType(utils::IdType type_id) {
|
2023-05-07 19:52:35 +03:00
|
|
|
return types_.at(type_id).second;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-22 19:14:17 +03:00
|
|
|
void SetValueType(utils::IdType type_id, utils::ValueType value_type) {
|
|
|
|
|
types_.at(type_id).second = value_type;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-10 23:13:50 +03:00
|
|
|
bool EqualValues(utils::IdType first_type, utils::IdType second_type) {
|
2023-05-09 15:37:30 +03:00
|
|
|
return GetAnyValue(first_type)->Same(*GetAnyValue(second_type));
|
2023-05-07 19:52:35 +03:00
|
|
|
}
|
2023-05-06 19:26:14 +03:00
|
|
|
|
2023-05-10 23:13:50 +03:00
|
|
|
bool AddValueRequirement(utils::IdType type, utils::IdType requrement) {
|
2023-07-02 18:28:16 +03:00
|
|
|
return GetAnyValue(requrement)->Require(*GetAnyValue(type));
|
2023-05-07 19:52:35 +03:00
|
|
|
}
|
2023-05-04 16:11:25 +03:00
|
|
|
|
2023-05-02 15:18:08 +03:00
|
|
|
private:
|
2023-05-07 19:52:35 +03:00
|
|
|
std::vector<std::pair<Type, utils::ValueType>> types_;
|
2023-05-02 15:18:08 +03:00
|
|
|
};
|
2023-04-21 14:27:55 +03:00
|
|
|
|
|
|
|
|
} // namespace info::type
|
2023-05-02 15:18:08 +03:00
|
|
|
|