Merge pull request #52068 from ThreeRhinosInAnElephantCostume/fixgdscript
Fix parse error on statement-less files with only newlines, add a warning for empty files.
This commit is contained in:
commit
4059cf2f02
13 changed files with 57 additions and 4 deletions
|
@ -328,6 +328,9 @@
|
|||
<member name="debug/gdscript/warnings/deprecated_keyword" type="bool" setter="" getter="" default="true">
|
||||
If [code]true[/code], enables warnings when deprecated keywords are used.
|
||||
</member>
|
||||
<member name="debug/gdscript/warnings/empty_file" type="bool" setter="" getter="" default="true">
|
||||
If [code]true[/code], enables warnings when an empty file is parsed.
|
||||
</member>
|
||||
<member name="debug/gdscript/warnings/enable" type="bool" setter="" getter="" default="true">
|
||||
If [code]true[/code], enables specific GDScript warnings (see [code]debug/gdscript/warnings/*[/code] settings). If [code]false[/code], disables all GDScript warnings.
|
||||
</member>
|
||||
|
|
|
@ -337,12 +337,29 @@ Error GDScriptParser::parse(const String &p_source_code, const String &p_script_
|
|||
tokenizer.set_cursor_position(cursor_line, cursor_column);
|
||||
script_path = p_script_path;
|
||||
current = tokenizer.scan();
|
||||
// Avoid error as the first token.
|
||||
while (current.type == GDScriptTokenizer::Token::ERROR) {
|
||||
push_error(current.literal);
|
||||
// Avoid error or newline as the first token.
|
||||
// The latter can mess with the parser when opening files filled exclusively with comments and newlines.
|
||||
while (current.type == GDScriptTokenizer::Token::ERROR || current.type == GDScriptTokenizer::Token::NEWLINE) {
|
||||
if (current.type == GDScriptTokenizer::Token::ERROR) {
|
||||
push_error(current.literal);
|
||||
}
|
||||
current = tokenizer.scan();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
// Warn about parsing an empty script file:
|
||||
if (current.type == GDScriptTokenizer::Token::TK_EOF) {
|
||||
// Create a dummy Node for the warning, pointing to the very beginning of the file
|
||||
Node *nd = alloc_node<PassNode>();
|
||||
nd->start_line = 1;
|
||||
nd->start_column = 0;
|
||||
nd->end_line = 1;
|
||||
nd->leftmost_column = 0;
|
||||
nd->rightmost_column = 0;
|
||||
push_warning(nd, GDScriptWarning::EMPTY_FILE);
|
||||
}
|
||||
#endif
|
||||
|
||||
push_multiline(false); // Keep one for the whole parsing.
|
||||
parse_program();
|
||||
pop_multiline();
|
||||
|
|
|
@ -145,6 +145,9 @@ String GDScriptWarning::get_message() const {
|
|||
case REDUNDANT_AWAIT: {
|
||||
return R"("await" keyword not needed in this case, because the expression isn't a coroutine nor a signal.)";
|
||||
}
|
||||
case EMPTY_FILE: {
|
||||
return "Empty script file.";
|
||||
}
|
||||
case WARNING_MAX:
|
||||
break; // Can't happen, but silences warning
|
||||
}
|
||||
|
@ -190,6 +193,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
|
|||
"ASSERT_ALWAYS_TRUE",
|
||||
"ASSERT_ALWAYS_FALSE",
|
||||
"REDUNDANT_AWAIT",
|
||||
"EMPTY_FILE",
|
||||
};
|
||||
|
||||
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
ASSERT_ALWAYS_TRUE, // Expression for assert argument is always true.
|
||||
ASSERT_ALWAYS_FALSE, // Expression for assert argument is always false.
|
||||
REDUNDANT_AWAIT, // await is used but expression is synchronous (not a signal nor a coroutine).
|
||||
EMPTY_FILE, // A script file is empty.
|
||||
WARNING_MAX,
|
||||
};
|
||||
|
||||
|
|
|
@ -496,7 +496,10 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Script files matching this pattern are allowed to not contain a test() function.
|
||||
if (source_file.match("*.notest.gd")) {
|
||||
return result;
|
||||
}
|
||||
// Test running.
|
||||
const Map<StringName, GDScriptFunction *>::Element *test_function_element = script->get_member_functions().find(GDScriptTestRunner::test_function_name);
|
||||
if (test_function_element == nullptr) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
>> WARNING
|
||||
>> Line: 1
|
||||
>> EMPTY_FILE
|
||||
>> Empty script file.
|
|
@ -0,0 +1 @@
|
|||
#a comment
|
|
@ -0,0 +1,4 @@
|
|||
>> WARNING
|
||||
>> Line: 1
|
||||
>> EMPTY_FILE
|
||||
>> Empty script file.
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
>> WARNING
|
||||
>> Line: 1
|
||||
>> EMPTY_FILE
|
||||
>> Empty script file.
|
|
@ -0,0 +1,4 @@
|
|||
#a comment, followed by a bunch of newlines
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
>> WARNING
|
||||
>> Line: 1
|
||||
>> EMPTY_FILE
|
||||
>> Empty script file.
|
Loading…
Reference in a new issue