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
@ -328,6 +328,9 @@
|
|||||||
<member name="debug/gdscript/warnings/deprecated_keyword" type="bool" setter="" getter="" default="true">
|
<member name="debug/gdscript/warnings/deprecated_keyword" type="bool" setter="" getter="" default="true">
|
||||||
If [code]true[/code], enables warnings when deprecated keywords are used.
|
If [code]true[/code], enables warnings when deprecated keywords are used.
|
||||||
</member>
|
</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">
|
<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.
|
If [code]true[/code], enables specific GDScript warnings (see [code]debug/gdscript/warnings/*[/code] settings). If [code]false[/code], disables all GDScript warnings.
|
||||||
</member>
|
</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);
|
tokenizer.set_cursor_position(cursor_line, cursor_column);
|
||||||
script_path = p_script_path;
|
script_path = p_script_path;
|
||||||
current = tokenizer.scan();
|
current = tokenizer.scan();
|
||||||
// Avoid error as the first token.
|
// Avoid error or newline as the first token.
|
||||||
while (current.type == GDScriptTokenizer::Token::ERROR) {
|
// 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);
|
push_error(current.literal);
|
||||||
|
}
|
||||||
current = tokenizer.scan();
|
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.
|
push_multiline(false); // Keep one for the whole parsing.
|
||||||
parse_program();
|
parse_program();
|
||||||
pop_multiline();
|
pop_multiline();
|
||||||
|
@ -145,6 +145,9 @@ String GDScriptWarning::get_message() const {
|
|||||||
case REDUNDANT_AWAIT: {
|
case REDUNDANT_AWAIT: {
|
||||||
return R"("await" keyword not needed in this case, because the expression isn't a coroutine nor a signal.)";
|
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:
|
case WARNING_MAX:
|
||||||
break; // Can't happen, but silences warning
|
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_TRUE",
|
||||||
"ASSERT_ALWAYS_FALSE",
|
"ASSERT_ALWAYS_FALSE",
|
||||||
"REDUNDANT_AWAIT",
|
"REDUNDANT_AWAIT",
|
||||||
|
"EMPTY_FILE",
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
|
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_TRUE, // Expression for assert argument is always true.
|
||||||
ASSERT_ALWAYS_FALSE, // Expression for assert argument is always false.
|
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).
|
REDUNDANT_AWAIT, // await is used but expression is synchronous (not a signal nor a coroutine).
|
||||||
|
EMPTY_FILE, // A script file is empty.
|
||||||
WARNING_MAX,
|
WARNING_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -496,7 +496,10 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
|
|||||||
}
|
}
|
||||||
return result;
|
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.
|
// Test running.
|
||||||
const Map<StringName, GDScriptFunction *>::Element *test_function_element = script->get_member_functions().find(GDScriptTestRunner::test_function_name);
|
const Map<StringName, GDScriptFunction *>::Element *test_function_element = script->get_member_functions().find(GDScriptTestRunner::test_function_name);
|
||||||
if (test_function_element == nullptr) {
|
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 New Issue
Block a user