GDScript: Add warning if non-`@tool` class extends `@tool` class
This commit is contained in:
parent
6a13fdcae3
commit
3f52871f70
|
@ -533,6 +533,9 @@
|
||||||
<member name="debug/gdscript/warnings/integer_division" type="int" setter="" getter="" default="1">
|
<member name="debug/gdscript/warnings/integer_division" type="int" setter="" getter="" default="1">
|
||||||
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when dividing an integer by another integer (the decimal part will be discarded).
|
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when dividing an integer by another integer (the decimal part will be discarded).
|
||||||
</member>
|
</member>
|
||||||
|
<member name="debug/gdscript/warnings/missing_tool" type="int" setter="" getter="" default="1">
|
||||||
|
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when the base class script has the [code]@tool[/code] annotation, but the current class script does not have it.
|
||||||
|
</member>
|
||||||
<member name="debug/gdscript/warnings/narrowing_conversion" type="int" setter="" getter="" default="1">
|
<member name="debug/gdscript/warnings/narrowing_conversion" type="int" setter="" getter="" default="1">
|
||||||
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when passing a floating-point value to a function that expects an integer (it will be converted and lose precision).
|
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when passing a floating-point value to a function that expects an integer (it will be converted and lose precision).
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -411,6 +411,12 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (!parser->_is_tool && ext_parser->get_parser()->_is_tool) {
|
||||||
|
parser->push_warning(p_class, GDScriptWarning::MISSING_TOOL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
base = ext_parser->get_parser()->head->get_datatype();
|
base = ext_parser->get_parser()->head->get_datatype();
|
||||||
} else {
|
} else {
|
||||||
if (p_class->extends.is_empty()) {
|
if (p_class->extends.is_empty()) {
|
||||||
|
@ -438,6 +444,13 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c
|
||||||
push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), id);
|
push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), id);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (!parser->_is_tool && base_parser->get_parser()->_is_tool) {
|
||||||
|
parser->push_warning(p_class, GDScriptWarning::MISSING_TOOL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
base = base_parser->get_parser()->head->get_datatype();
|
base = base_parser->get_parser()->head->get_datatype();
|
||||||
}
|
}
|
||||||
} else if (ProjectSettings::get_singleton()->has_autoload(name) && ProjectSettings::get_singleton()->get_autoload(name).is_singleton) {
|
} else if (ProjectSettings::get_singleton()->has_autoload(name) && ProjectSettings::get_singleton()->get_autoload(name).is_singleton) {
|
||||||
|
@ -458,6 +471,13 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c
|
||||||
push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), id);
|
push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), id);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (!parser->_is_tool && info_parser->get_parser()->_is_tool) {
|
||||||
|
parser->push_warning(p_class, GDScriptWarning::MISSING_TOOL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
base = info_parser->get_parser()->head->get_datatype();
|
base = info_parser->get_parser()->head->get_datatype();
|
||||||
} else if (class_exists(name)) {
|
} else if (class_exists(name)) {
|
||||||
if (Engine::get_singleton()->has_singleton(name)) {
|
if (Engine::get_singleton()->has_singleton(name)) {
|
||||||
|
|
|
@ -109,6 +109,8 @@ String GDScriptWarning::get_message() const {
|
||||||
case STATIC_CALLED_ON_INSTANCE:
|
case STATIC_CALLED_ON_INSTANCE:
|
||||||
CHECK_SYMBOLS(2);
|
CHECK_SYMBOLS(2);
|
||||||
return vformat(R"*(The function "%s()" is a static function but was called from an instance. Instead, it should be directly called from the type: "%s.%s()".)*", symbols[0], symbols[1], symbols[0]);
|
return vformat(R"*(The function "%s()" is a static function but was called from an instance. Instead, it should be directly called from the type: "%s.%s()".)*", symbols[0], symbols[1], symbols[0]);
|
||||||
|
case MISSING_TOOL:
|
||||||
|
return R"(The base class script has the "@tool" annotation, but this script does not have it.)";
|
||||||
case REDUNDANT_STATIC_UNLOAD:
|
case REDUNDANT_STATIC_UNLOAD:
|
||||||
return R"(The "@static_unload" annotation is redundant because the file does not have a class with static variables.)";
|
return R"(The "@static_unload" annotation is redundant because the file does not have a class with static variables.)";
|
||||||
case REDUNDANT_AWAIT:
|
case REDUNDANT_AWAIT:
|
||||||
|
@ -219,6 +221,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
|
||||||
"UNSAFE_VOID_RETURN",
|
"UNSAFE_VOID_RETURN",
|
||||||
"RETURN_VALUE_DISCARDED",
|
"RETURN_VALUE_DISCARDED",
|
||||||
"STATIC_CALLED_ON_INSTANCE",
|
"STATIC_CALLED_ON_INSTANCE",
|
||||||
|
"MISSING_TOOL",
|
||||||
"REDUNDANT_STATIC_UNLOAD",
|
"REDUNDANT_STATIC_UNLOAD",
|
||||||
"REDUNDANT_AWAIT",
|
"REDUNDANT_AWAIT",
|
||||||
"ASSERT_ALWAYS_TRUE",
|
"ASSERT_ALWAYS_TRUE",
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
UNSAFE_VOID_RETURN, // Function returns void but returned a call to a function that can't be type checked.
|
UNSAFE_VOID_RETURN, // Function returns void but returned a call to a function that can't be type checked.
|
||||||
RETURN_VALUE_DISCARDED, // Function call returns something but the value isn't used.
|
RETURN_VALUE_DISCARDED, // Function call returns something but the value isn't used.
|
||||||
STATIC_CALLED_ON_INSTANCE, // A static method was called on an instance of a class instead of on the class itself.
|
STATIC_CALLED_ON_INSTANCE, // A static method was called on an instance of a class instead of on the class itself.
|
||||||
|
MISSING_TOOL, // The base class script has the "@tool" annotation, but this script does not have it.
|
||||||
REDUNDANT_STATIC_UNLOAD, // The `@static_unload` annotation is used but the class does not have static data.
|
REDUNDANT_STATIC_UNLOAD, // The `@static_unload` annotation is used but the class does not have static data.
|
||||||
REDUNDANT_AWAIT, // await is used but expression is synchronous (not a signal nor a coroutine).
|
REDUNDANT_AWAIT, // await is used but expression is synchronous (not a signal nor a coroutine).
|
||||||
ASSERT_ALWAYS_TRUE, // Expression for assert argument is always true.
|
ASSERT_ALWAYS_TRUE, // Expression for assert argument is always true.
|
||||||
|
@ -123,6 +124,7 @@ public:
|
||||||
WARN, // UNSAFE_VOID_RETURN
|
WARN, // UNSAFE_VOID_RETURN
|
||||||
IGNORE, // RETURN_VALUE_DISCARDED // Too spammy by default on common cases (connect, Tween, etc.).
|
IGNORE, // RETURN_VALUE_DISCARDED // Too spammy by default on common cases (connect, Tween, etc.).
|
||||||
WARN, // STATIC_CALLED_ON_INSTANCE
|
WARN, // STATIC_CALLED_ON_INSTANCE
|
||||||
|
WARN, // MISSING_TOOL
|
||||||
WARN, // REDUNDANT_STATIC_UNLOAD
|
WARN, // REDUNDANT_STATIC_UNLOAD
|
||||||
WARN, // REDUNDANT_AWAIT
|
WARN, // REDUNDANT_AWAIT
|
||||||
WARN, // ASSERT_ALWAYS_TRUE
|
WARN, // ASSERT_ALWAYS_TRUE
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
extends "./non_tool_extends_tool.notest.gd"
|
||||||
|
|
||||||
|
class InnerClass extends "./non_tool_extends_tool.notest.gd":
|
||||||
|
pass
|
||||||
|
|
||||||
|
func test():
|
||||||
|
pass
|
|
@ -0,0 +1 @@
|
||||||
|
@tool
|
|
@ -0,0 +1,9 @@
|
||||||
|
GDTEST_OK
|
||||||
|
>> WARNING
|
||||||
|
>> Line: 1
|
||||||
|
>> MISSING_TOOL
|
||||||
|
>> The base class script has the "@tool" annotation, but this script does not have it.
|
||||||
|
>> WARNING
|
||||||
|
>> Line: 3
|
||||||
|
>> MISSING_TOOL
|
||||||
|
>> The base class script has the "@tool" annotation, but this script does not have it.
|
|
@ -0,0 +1,9 @@
|
||||||
|
@warning_ignore("missing_tool")
|
||||||
|
extends "./non_tool_extends_tool.notest.gd"
|
||||||
|
|
||||||
|
@warning_ignore("missing_tool")
|
||||||
|
class InnerClass extends "./non_tool_extends_tool.notest.gd":
|
||||||
|
pass
|
||||||
|
|
||||||
|
func test():
|
||||||
|
pass
|
|
@ -0,0 +1 @@
|
||||||
|
GDTEST_OK
|
Loading…
Reference in New Issue