Skip to content

Commit

Permalink
Merge pull request #70613 from vonagam/fix-enum-as-constant
Browse files Browse the repository at this point in the history
Fixes #54018
Fixes #70213
Fixes #70495
  • Loading branch information
vnen authored Dec 30, 2022
2 parents 0daa86d + b6aa484 commit 33afa82
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 18 deletions.
13 changes: 8 additions & 5 deletions modules/gdscript/gdscript_analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,7 @@ void GDScriptAnalyzer::resolve_class_member(GDScriptParser::ClassNode *p_class,
const GDScriptParser::EnumNode *prev_enum = current_enum;
current_enum = member.m_enum;

Dictionary dictionary;
for (int j = 0; j < member.m_enum->values.size(); j++) {
GDScriptParser::EnumNode::Value &element = member.m_enum->values.write[j];

Expand All @@ -960,11 +961,13 @@ void GDScriptAnalyzer::resolve_class_member(GDScriptParser::ClassNode *p_class,
}

enum_type.enum_values[element.identifier->name] = element.value;
dictionary[String(element.identifier->name)] = element.value;
}

current_enum = prev_enum;

member.m_enum->set_datatype(enum_type);
member.m_enum->dictionary = dictionary;

// Apply annotations.
for (GDScriptParser::AnnotationNode *&E : member.m_enum->annotations) {
Expand Down Expand Up @@ -3140,10 +3143,9 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
break;
case GDScriptParser::ClassNode::Member::ENUM:
if (p_base != nullptr && p_base->is_constant) {
p_identifier->is_constant = true;
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
}
p_identifier->is_constant = true;
p_identifier->reduced_value = member.m_enum->dictionary;
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
break;
case GDScriptParser::ClassNode::Member::VARIABLE:
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_VARIABLE;
Expand Down Expand Up @@ -3197,7 +3199,8 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
return;
case GDScriptParser::ClassNode::Member::ENUM:
p_identifier->set_datatype(member.get_datatype());
p_identifier->is_constant = false;
p_identifier->is_constant = true;
p_identifier->reduced_value = member.m_enum->dictionary;
return;
case GDScriptParser::ClassNode::Member::CLASS:
p_identifier->set_datatype(member.get_datatype());
Expand Down
20 changes: 7 additions & 13 deletions modules/gdscript/gdscript_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2453,26 +2453,20 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri

case GDScriptParser::ClassNode::Member::ENUM: {
const GDScriptParser::EnumNode *enum_n = member.m_enum;
StringName name = enum_n->identifier->name;

// TODO: Make enums not be just a dictionary?
Dictionary new_enum;
for (int j = 0; j < enum_n->values.size(); j++) {
// Needs to be string because Variant::get will convert to String.
new_enum[String(enum_n->values[j].identifier->name)] = enum_n->values[j].value;
}

p_script->constants.insert(enum_n->identifier->name, new_enum);
p_script->constants.insert(name, enum_n->dictionary);
#ifdef TOOLS_ENABLED
p_script->member_lines[enum_n->identifier->name] = enum_n->start_line;
p_script->doc_enums[enum_n->identifier->name] = DocData::EnumDoc();
p_script->doc_enums[enum_n->identifier->name].name = enum_n->identifier->name;
p_script->doc_enums[enum_n->identifier->name].description = enum_n->doc_description;
p_script->member_lines[name] = enum_n->start_line;
p_script->doc_enums[name] = DocData::EnumDoc();
p_script->doc_enums[name].name = name;
p_script->doc_enums[name].description = enum_n->doc_description;
for (int j = 0; j < enum_n->values.size(); j++) {
DocData::ConstantDoc const_doc;
const_doc.name = enum_n->values[j].identifier->name;
const_doc.value = Variant(enum_n->values[j].value).operator String();
const_doc.description = enum_n->values[j].doc_description;
p_script->doc_enums[enum_n->identifier->name].values.push_back(const_doc);
p_script->doc_enums[name].values.push_back(const_doc);
}
#endif
} break;
Expand Down
1 change: 1 addition & 0 deletions modules/gdscript/gdscript_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ class GDScriptParser {

IdentifierNode *identifier = nullptr;
Vector<Value> values;
Variant dictionary;
#ifdef TOOLS_ENABLED
String doc_description;
#endif // TOOLS_ENABLED
Expand Down
29 changes: 29 additions & 0 deletions modules/gdscript/tests/scripts/analyzer/features/enum_as_const.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class Outer:
enum OuterEnum { OuterValue = 3 }
const OuterConst := OuterEnum

class Inner:
enum InnerEnum { InnerValue = 7 }
const InnerConst := InnerEnum

static func test() -> void:
print(OuterEnum.size());
print(OuterEnum.OuterValue);
print(OuterConst.size());
print(OuterConst.OuterValue);
print(Outer.OuterEnum.size());
print(Outer.OuterEnum.OuterValue);
print(Outer.OuterConst.size());
print(Outer.OuterConst.OuterValue);

print(InnerEnum.size());
print(InnerEnum.InnerValue);
print(InnerConst.size());
print(InnerConst.InnerValue);
print(Inner.InnerEnum.size());
print(Inner.InnerEnum.InnerValue);
print(Inner.InnerConst.size());
print(Inner.InnerConst.InnerValue);

func test():
Outer.Inner.test()
17 changes: 17 additions & 0 deletions modules/gdscript/tests/scripts/analyzer/features/enum_as_const.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
GDTEST_OK
1
3
1
3
1
3
1
3
1
7
1
7
1
7
1
7

0 comments on commit 33afa82

Please sign in to comment.