diff options
Diffstat (limited to 'modules')
10 files changed, 48 insertions, 14 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 5102c54785..fc2e6e94f3 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3139,6 +3139,12 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod p_identifier->reduced_value = member.enum_value.value; 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; + } + break; case GDScriptParser::ClassNode::Member::VARIABLE: p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_VARIABLE; p_identifier->variable_source = member.variable; @@ -3152,12 +3158,14 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod break; case GDScriptParser::ClassNode::Member::CLASS: if (p_base != nullptr && p_base->is_constant) { + p_identifier->is_constant = true; + p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT; + Error err = OK; GDScript *scr = GDScriptCache::get_full_script(base.script_path, err).ptr(); ERR_FAIL_COND_MSG(err != OK, "Error while getting subscript full script."); scr = scr->find_class(p_identifier->get_datatype().class_type->fqcn); p_identifier->reduced_value = scr; - p_identifier->is_constant = true; } break; default: diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 50588110c4..cf9e734b05 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -490,24 +490,29 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } break; case GDScriptParser::Node::CAST: { const GDScriptParser::CastNode *cn = static_cast<const GDScriptParser::CastNode *>(p_expression); - GDScriptParser::DataType og_cast_type = cn->cast_type->get_datatype(); + GDScriptParser::DataType og_cast_type = cn->get_datatype(); GDScriptDataType cast_type = _gdtype_from_datatype(og_cast_type, codegen.script); - if (og_cast_type.kind == GDScriptParser::DataType::ENUM) { - // Enum types are usually treated as dictionaries, but in this case we want to cast to an integer. - cast_type.kind = GDScriptDataType::BUILTIN; - cast_type.builtin_type = Variant::INT; - } + GDScriptCodeGenerator::Address result; + if (cast_type.has_type) { + if (og_cast_type.kind == GDScriptParser::DataType::ENUM) { + // Enum types are usually treated as dictionaries, but in this case we want to cast to an integer. + cast_type.kind = GDScriptDataType::BUILTIN; + cast_type.builtin_type = Variant::INT; + } - // Create temporary for result first since it will be deleted last. - GDScriptCodeGenerator::Address result = codegen.add_temporary(cast_type); + // Create temporary for result first since it will be deleted last. + result = codegen.add_temporary(cast_type); - GDScriptCodeGenerator::Address src = _parse_expression(codegen, r_error, cn->operand); + GDScriptCodeGenerator::Address src = _parse_expression(codegen, r_error, cn->operand); - gen->write_cast(result, src, cast_type); + gen->write_cast(result, src, cast_type); - if (src.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + if (src.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); + } + } else { + result = _parse_expression(codegen, r_error, cn->operand); } return result; diff --git a/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.gd b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.gd new file mode 100644 index 0000000000..ba1b198cbf --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.gd @@ -0,0 +1,5 @@ +# https://github.com/godotengine/godot/issues/69504#issuecomment-1345725988 + +func test(): + print("cast to Variant == null: ", 1 as Variant == null) + print("cast to Object == null: ", self as Object == null) diff --git a/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.out b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.out new file mode 100644 index 0000000000..541de99b8e --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/cast_non_null.out @@ -0,0 +1,3 @@ +GDTEST_OK +cast to Variant == null: false +cast to Object == null: false diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant.gd b/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant.gd new file mode 100644 index 0000000000..757744b6f1 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant.gd @@ -0,0 +1,6 @@ +const External = preload("external_enum_as_constant_external.notest.gd") +const MyEnum = External.MyEnum + +func test(): + print(MyEnum.WAITING == 0) + print(MyEnum.GODOT == 1) diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant.out b/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant.out new file mode 100644 index 0000000000..9d111a8322 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant.out @@ -0,0 +1,3 @@ +GDTEST_OK +true +true diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant_external.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant_external.notest.gd new file mode 100644 index 0000000000..7c090844d0 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_enum_as_constant_external.notest.gd @@ -0,0 +1,4 @@ +enum MyEnum { + WAITING, + GODOT +} diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.gd b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.gd index ed5fb18b73..18dca109fb 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.gd @@ -1,4 +1,4 @@ -const External = preload("inner_class_constant_assignment_external.notest.gd") +const External = preload("external_inner_class_as_constant_external.notest.gd") const ExternalInnerClass = External.InnerClass func test(): diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.out b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out index 15666c46ad..15666c46ad 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.out +++ b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment_external.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant_external.notest.gd index 788c99d469..788c99d469 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment_external.notest.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant_external.notest.gd |