Merge pull request #58686 from vnen/gdscript-warn-export-type-mismatch
This commit is contained in:
commit
1cf444aff0
4 changed files with 28 additions and 7 deletions
|
@ -321,6 +321,9 @@
|
||||||
<member name="debug/gdscript/warnings/exclude_addons" type="bool" setter="" getter="" default="true">
|
<member name="debug/gdscript/warnings/exclude_addons" type="bool" setter="" getter="" default="true">
|
||||||
If [code]true[/code], scripts in the [code]res://addons[/code] folder will not generate warnings.
|
If [code]true[/code], scripts in the [code]res://addons[/code] folder will not generate warnings.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="debug/gdscript/warnings/export_hint_type_mistmatch" type="bool" setter="" getter="" default="true">
|
||||||
|
If [code]true[/code], enables warnings when the type of the default value set to an exported variable is different than the specified export type.
|
||||||
|
</member>
|
||||||
<member name="debug/gdscript/warnings/function_conflicts_constant" type="bool" setter="" getter="" default="true">
|
<member name="debug/gdscript/warnings/function_conflicts_constant" type="bool" setter="" getter="" default="true">
|
||||||
If [code]true[/code], enables warnings when a function is declared with the same name as a constant.
|
If [code]true[/code], enables warnings when a function is declared with the same name as a constant.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -450,8 +450,20 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc
|
||||||
}
|
}
|
||||||
|
|
||||||
members_cache.push_back(c->variables[i]._export);
|
members_cache.push_back(c->variables[i]._export);
|
||||||
|
|
||||||
|
Variant::Type default_value_type = c->variables[i].default_value.get_type();
|
||||||
|
Variant::Type export_type = c->variables[i]._export.type;
|
||||||
|
|
||||||
|
// Convert the default value to the export type to avoid issues with the property editor and scene serialization.
|
||||||
|
// This is done only in the export side, the script itself will use the default value with no type change.
|
||||||
|
if (default_value_type != Variant::NIL && default_value_type != export_type) {
|
||||||
|
Variant::CallError ce;
|
||||||
|
const Variant *args = &c->variables[i].default_value;
|
||||||
|
member_default_values_cache[c->variables[i].identifier] = Variant::construct(export_type, &args, 1, ce);
|
||||||
|
} else {
|
||||||
member_default_values_cache[c->variables[i].identifier] = c->variables[i].default_value;
|
member_default_values_cache[c->variables[i].identifier] = c->variables[i].default_value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_signals.clear();
|
_signals.clear();
|
||||||
|
|
||||||
|
@ -2014,6 +2026,10 @@ String GDScriptWarning::get_message() const {
|
||||||
case STANDALONE_TERNARY: {
|
case STANDALONE_TERNARY: {
|
||||||
return "Standalone ternary conditional operator: the return value is being discarded.";
|
return "Standalone ternary conditional operator: the return value is being discarded.";
|
||||||
}
|
}
|
||||||
|
case EXPORT_HINT_TYPE_MISTMATCH: {
|
||||||
|
CHECK_SYMBOLS(2);
|
||||||
|
return vformat("The type of the default value (%s) doesn't match the type of the export hint (%s). The type won't be coerced.", symbols[0], symbols[1]);
|
||||||
|
}
|
||||||
case WARNING_MAX:
|
case WARNING_MAX:
|
||||||
break; // Can't happen, but silences warning
|
break; // Can't happen, but silences warning
|
||||||
}
|
}
|
||||||
|
@ -2057,6 +2073,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
|
||||||
"UNSAFE_CALL_ARGUMENT",
|
"UNSAFE_CALL_ARGUMENT",
|
||||||
"DEPRECATED_KEYWORD",
|
"DEPRECATED_KEYWORD",
|
||||||
"STANDALONE_TERNARY",
|
"STANDALONE_TERNARY",
|
||||||
|
"EXPORT_HINT_TYPE_MISTMATCH",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,7 @@ struct GDScriptWarning {
|
||||||
UNSAFE_CALL_ARGUMENT, // Function call argument is of a supertype of the require argument
|
UNSAFE_CALL_ARGUMENT, // Function call argument is of a supertype of the require argument
|
||||||
DEPRECATED_KEYWORD, // The keyword is deprecated and should be replaced
|
DEPRECATED_KEYWORD, // The keyword is deprecated and should be replaced
|
||||||
STANDALONE_TERNARY, // Return value of ternary expression is discarded
|
STANDALONE_TERNARY, // Return value of ternary expression is discarded
|
||||||
|
EXPORT_HINT_TYPE_MISTMATCH, // The type of the variable's default value doesn't match its export hint
|
||||||
WARNING_MAX,
|
WARNING_MAX,
|
||||||
} code;
|
} code;
|
||||||
Vector<String> symbols;
|
Vector<String> symbols;
|
||||||
|
|
|
@ -4995,22 +4995,22 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
// Warn if the default value set is not the same as the export type, since it won't be coerced and
|
||||||
|
// may create wrong expectations.
|
||||||
if (subexpr->type == Node::TYPE_CONSTANT && (member._export.type != Variant::NIL || member.data_type.has_type)) {
|
if (subexpr->type == Node::TYPE_CONSTANT && (member._export.type != Variant::NIL || member.data_type.has_type)) {
|
||||||
ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
|
ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
|
||||||
if (cn->value.get_type() != Variant::NIL) {
|
if (cn->value.get_type() != Variant::NIL) {
|
||||||
if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) {
|
if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) {
|
||||||
if (Variant::can_convert(cn->value.get_type(), member._export.type)) {
|
if (!Variant::can_convert(cn->value.get_type(), member._export.type)) {
|
||||||
Variant::CallError err;
|
|
||||||
const Variant *args = &cn->value;
|
|
||||||
cn->value = Variant::construct(member._export.type, &args, 1, err);
|
|
||||||
} else {
|
|
||||||
_set_error("Can't convert the provided value to the export type.");
|
_set_error("Can't convert the provided value to the export type.");
|
||||||
return;
|
return;
|
||||||
|
} else if (!member.data_type.has_type) {
|
||||||
|
_add_warning(GDScriptWarning::EXPORT_HINT_TYPE_MISTMATCH, member.line, Variant::get_type_name(cn->value.get_type()), Variant::get_type_name(member._export.type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
member.default_value = cn->value;
|
member.default_value = cn->value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IdentifierNode *id = alloc_node<IdentifierNode>();
|
IdentifierNode *id = alloc_node<IdentifierNode>();
|
||||||
|
|
Loading…
Reference in a new issue