GDScript: Allow classes declaration to be done in single line

Incidentally, allow multiple statements in single line functions when
using semicolon as a terminator.
This commit is contained in:
George Marques 2021-09-21 14:13:23 -03:00
parent db028ac700
commit e5ebc9710d
No known key found for this signature in database
GPG Key ID: 046BD46A3201E43D
6 changed files with 63 additions and 8 deletions

View File

@ -579,7 +579,7 @@ void GDScriptParser::parse_program() {
} }
} }
parse_class_body(); parse_class_body(true);
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
for (Map<int, GDScriptTokenizer::CommentData>::Element *E = tokenizer.get_comments().front(); E; E = E->next()) { for (Map<int, GDScriptTokenizer::CommentData>::Element *E = tokenizer.get_comments().front(); E; E = E->next()) {
@ -615,9 +615,10 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class() {
} }
consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after class declaration.)"); consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after class declaration.)");
consume(GDScriptTokenizer::Token::NEWLINE, R"(Expected newline after class declaration.)");
if (!consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) { bool multiline = match(GDScriptTokenizer::Token::NEWLINE);
if (multiline && !consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) {
current_class = previous_class; current_class = previous_class;
return n_class; return n_class;
} }
@ -630,9 +631,11 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class() {
end_statement("superclass"); end_statement("superclass");
} }
parse_class_body(); parse_class_body(multiline);
consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)"); if (multiline) {
consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)");
}
current_class = previous_class; current_class = previous_class;
return n_class; return n_class;
@ -747,7 +750,7 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)()
} }
} }
void GDScriptParser::parse_class_body() { void GDScriptParser::parse_class_body(bool p_is_multiline) {
bool class_end = false; bool class_end = false;
while (!class_end && !is_at_end()) { while (!class_end && !is_at_end()) {
switch (current.type) { switch (current.type) {
@ -793,6 +796,9 @@ void GDScriptParser::parse_class_body() {
if (panic_mode) { if (panic_mode) {
synchronize(); synchronize();
} }
if (!p_is_multiline) {
class_end = true;
}
} }
} }
@ -1358,6 +1364,9 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,
int error_count = 0; int error_count = 0;
do { do {
if (!multiline && previous.type == GDScriptTokenizer::Token::SEMICOLON && check(GDScriptTokenizer::Token::NEWLINE)) {
break;
}
Node *statement = parse_statement(); Node *statement = parse_statement();
if (statement == nullptr) { if (statement == nullptr) {
if (error_count++ > 100) { if (error_count++ > 100) {
@ -1398,7 +1407,7 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,
break; break;
} }
} while (multiline && !check(GDScriptTokenizer::Token::DEDENT) && !lambda_ended && !is_at_end()); } while ((multiline || previous.type == GDScriptTokenizer::Token::SEMICOLON) && !check(GDScriptTokenizer::Token::DEDENT) && !lambda_ended && !is_at_end());
if (multiline) { if (multiline) {
if (!lambda_ended) { if (!lambda_ended) {

View File

@ -1324,7 +1324,7 @@ private:
ClassNode *parse_class(); ClassNode *parse_class();
void parse_class_name(); void parse_class_name();
void parse_extends(); void parse_extends();
void parse_class_body(); void parse_class_body(bool p_is_multiline);
template <class T> template <class T>
void parse_class_member(T *(GDScriptParser::*p_parse_function)(), AnnotationInfo::TargetKind p_target, const String &p_member_kind); void parse_class_member(T *(GDScriptParser::*p_parse_function)(), AnnotationInfo::TargetKind p_target, const String &p_member_kind);
SignalNode *parse_signal(); SignalNode *parse_signal();

View File

@ -0,0 +1,22 @@
#GDTEST_OK
func test():
a();
b();
c();
d();
e();
func a(): print("a");
func b(): print("b1"); print("b2")
func c(): print("c1"); print("c2");
func d():
print("d1");
print("d2")
func e():
print("e1");
print("e2");

View File

@ -0,0 +1,10 @@
GDTEST_OK
a
b1
b2
c1
c2
d1
d2
e1
e2

View File

@ -0,0 +1,11 @@
#GDTEST_OK
func test(): C.new().test("Ok"); test2()
func test2(): print("Ok 2")
class A: pass
class B extends RefCounted: pass
class C extends RefCounted: func test(x): print(x)

View File

@ -0,0 +1,3 @@
GDTEST_OK
Ok
Ok 2