Skip to content

Instantly share code, notes, and snippets.

@dalexeev
Created May 11, 2023 13:04
Show Gist options
  • Save dalexeev/173d6a14c065347b0f01f16b74308e84 to your computer and use it in GitHub Desktop.
Save dalexeev/173d6a14c065347b0f01f16b74308e84 to your computer and use it in GitHub Desktop.
@@ -2,6 +2,7 @@ class DataType {
private:
// Private access so we can control memory management.
DataType *container_element_type = nullptr;
+ DataType *gussed_type = nullptr;
public:
enum Kind {
@@ -11,19 +12,12 @@ public:
CLASS, // GDScript.
ENUM, // Enumeration.
VARIANT, // Can be any type.
+ UNKNOWN, // We don't know the type.
RESOLVING, // Currently resolving.
UNRESOLVED,
};
Kind kind = UNRESOLVED;
- enum TypeSource {
- UNDETECTED, // Can be any type.
- INFERRED, // Has inferred type, but still dynamic.
- ANNOTATED_EXPLICIT, // Has a specific type annotated.
- ANNOTATED_INFERRED, // Has a static type but comes from the assigned value.
- };
- TypeSource type_source = UNDETECTED;
-
bool is_constant = false;
bool is_read_only = false;
bool is_meta_type = false;
@@ -42,11 +36,12 @@ public:
_FORCE_INLINE_ bool is_set() const { return kind != RESOLVING && kind != UNRESOLVED; }
_FORCE_INLINE_ bool is_resolving() const { return kind == RESOLVING; }
- _FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; }
- _FORCE_INLINE_ bool is_variant() const { return kind == VARIANT || kind == RESOLVING || kind == UNRESOLVED; }
- _FORCE_INLINE_ bool is_hard_type() const { return type_source > INFERRED; }
+
String to_string() const;
+ bool is_subtype_of(const DataType &p_type) const;
+ bool is_compatible_with(const DataType &p_type, bool p_strict = true) const;
+
_FORCE_INLINE_ void set_container_element_type(const DataType &p_type) {
container_element_type = memnew(DataType(p_type));
}
@@ -71,15 +66,27 @@ public:
GDScriptParser::DataType get_typed_container_type() const;
- bool operator==(const DataType &p_other) const {
- if (type_source == UNDETECTED || p_other.type_source == UNDETECTED) {
- return true; // Can be consireded equal for parsing purposes.
- }
+ _FORCE_INLINE_ void set_gussed_type(const DataType &p_type) {
+ // TODO: Check if gussed type is subtype of this type?
+ gussed_type = memnew(DataType(p_type));
+ }
- if (type_source == INFERRED || p_other.type_source == INFERRED) {
- return true; // Can be consireded equal for parsing purposes.
- }
+ _FORCE_INLINE_ DataType get_gussed_type() const {
+ return (gussed_type != nullptr) ? *gussed_type : *this;
+ }
+ _FORCE_INLINE_ bool has_gussed_type() const {
+ return gussed_type != nullptr;
+ }
+
+ _FORCE_INLINE_ void unset_gussed_type() {
+ if (gussed_type) {
+ memdelete(gussed_type);
+ };
+ gussed_type = nullptr;
+ }
+
+ bool operator==(const DataType &p_other) const {
if (kind != p_other.kind) {
return false;
}
@@ -96,6 +103,7 @@ public:
return script_type == p_other.script_type;
case CLASS:
return class_type == p_other.class_type || class_type->fqcn == p_other.class_type->fqcn;
+ case UNKNOWN:
case RESOLVING:
case UNRESOLVED:
break;
@@ -110,9 +118,8 @@ public:
void operator=(const DataType &p_other) {
kind = p_other.kind;
- type_source = p_other.type_source;
- is_read_only = p_other.is_read_only;
is_constant = p_other.is_constant;
+ is_read_only = p_other.is_read_only;
is_meta_type = p_other.is_meta_type;
is_pseudo_type = p_other.is_pseudo_type;
is_coroutine = p_other.is_coroutine;
@@ -128,6 +135,10 @@ public:
if (p_other.has_container_element_type()) {
set_container_element_type(p_other.get_container_element_type());
}
+ unset_gussed_type();
+ if (p_other.has_gussed_type()) {
+ set_gussed_type(p_other.get_gussed_type());
+ }
}
DataType() = default;
@@ -138,5 +149,6 @@ public:
~DataType() {
unset_container_element_type();
+ unset_gussed_type();
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment